/* ============================================================ DRS Data Display Qt-based graphical user interface for displaying data taken with the drsdaq program. There are two operation modes: inspection of a raw data file and data taking via the socket interface. Connecting to a socket server automatically disables raw data file operation and closes any open file. Oliver Grimm ============================================================ */ #include "GUI.h" ddd::ddd() { WaitForData = false; // Instantiate without console output RD = new RawDataCTX(true); PixMap = new PixelMap("../../config/PixelMap.txt", false); //--------------------------------------------------------------------- //**************************** Main window **************************** //--------------------------------------------------------------------- Central = new QWidget(this); setCentralWidget(Central); Socket = new QTcpSocket(Central); connect(Socket, SIGNAL(readyRead()), this, SLOT(ReadFromSocket())); connect(Socket, SIGNAL(disconnected()), this, SLOT(GotDisconnected())); // SpinBox for event number EventNo = new QSpinBox(Central); EventNo->setEnabled(false); connect(EventNo, SIGNAL(valueChanged(int)), this, SLOT(DisplayEvent(int))); EventNo->setToolTip("Event number in file"); SpinLayout = new QFormLayout(); SpinLayout->setRowWrapPolicy(QFormLayout::WrapAllRows); SpinLayout->addRow("E&vent #", EventNo); // SpinBox for channel number ChannelNo = new QSpinBox(Central); ChannelNo->setEnabled(false); connect(ChannelNo, SIGNAL(valueChanged(int)), this, SLOT(DisplayEvent(int))); ChannelNo->setToolTip("Channels 0-19 for 2 DRS chips per mezzanine board"); // SpinBox for board number BoardNo = new QSpinBox(Central); BoardNo->setEnabled(false); connect(BoardNo, SIGNAL(valueChanged(int)), this, SLOT(DisplayEvent(int))); BoardNo->setToolTip("Mezzanine board number"); // TextBox for pixel ID PixelID = new QLineEdit(Central); PixelID->setEnabled(false); connect(PixelID, SIGNAL(returnPressed()), this, SLOT(TranslatePixelID())); PixelID->setToolTip("Pixel identification"); // Layout of pixel addressing widgets FormLayout = new QFormLayout; FormLayout->setRowWrapPolicy(QFormLayout::WrapAllRows); FormLayout->addRow("&Channel #", ChannelNo); FormLayout->addRow("&Board #", BoardNo); FormLayout->addRow("Pixel ID", PixelID); // Socket button SocketButton = new QPushButton("Socke&t\nInterface", Central); SocketButton->setFont(QFont("Times", 10, QFont::Bold)); connect(SocketButton, SIGNAL(clicked()), this, SLOT(OpenSocketWindow())); SocketButton->setToolTip("Open window for socket communication"); // M0 display button M0Display = new QPushButton("M0 Display",Central); M0Display->setFont(QFont("Times", 10, QFont::Bold)); connect(M0Display, SIGNAL(clicked()), this, SLOT(OpenM0Window())); M0Display->setToolTip("Open window for M0 display"); // Acquire button and Continuous check box GetButton = new QPushButton("&Acquire", Central); GetButton->setFont(QFont("Times", 10, QFont::Bold)); GetButton->setEnabled(false); connect(GetButton, SIGNAL(clicked()), this, SLOT(GetSignalFromSocket())); GetButton->setToolTip("Acquire event over socket interface"); ContinuousBox = new QCheckBox("Continuous", Central); ContinuousBox->setFont(QFont("Times", 10, QFont::Bold)); ContinuousBox->setToolTip("Acquire continuously"); // Plot area Graph = new QwtPlot(Central); Graph->setAxisTitle(QwtPlot::xBottom, "Time (ns)"); Graph->setAxisTitle(QwtPlot::yLeft, "Signal (mV)"); Graph->setAutoReplot(true); Graph->setCanvasBackground(QColor(Qt::yellow)); Graph->setToolTip("Left mouse button to zoom (+Shift to pan)"); Zoomer = new QwtPlotZoomer(QwtPlot::xBottom,QwtPlot::yLeft,Graph->canvas()); Panner = new QwtPlotPanner(Graph->canvas()); Panner->setMouseButton(Qt::LeftButton, Qt::ShiftModifier); Grid = new QwtPlotGrid; Grid->setMajPen(QPen(Qt::gray, 0, Qt::DotLine)); Grid->attach(Graph); Signal = new QwtPlotCurve; Signal->attach(Graph); Signal->setStyle(QwtPlotCurve::Steps); // Text boxes for run and event header RunHeaderDisplay = new QPlainTextEdit(Central); EventHeaderDisplay = new QPlainTextEdit(Central); RunHeaderDisplay->setReadOnly(true); EventHeaderDisplay->setReadOnly(true); // Browse botton LoadButton = new QToolButton(Central); LoadButton->setToolButtonStyle (Qt::ToolButtonTextOnly); LoadButton->setText("..."); connect(LoadButton, SIGNAL(clicked()), this, SLOT(FileDialog())); LoadButton->setToolTip("Open file dialog to select raw data file"); // Filename box FilenameBox = new QLineEdit(Central); connect(FilenameBox, SIGNAL(returnPressed()), this, SLOT(OpenDatafile())); FilenameBox->setToolTip("Raw data file name"); // Tab widget TabWidget = new QTabWidget(Central); TabWidget->addTab(Graph, "&Signal"); TabWidget->addTab(RunHeaderDisplay, "&Run Header"); TabWidget->addTab(EventHeaderDisplay, "&Event Header"); // Layout of all widgets MainLayout = new QGridLayout(Central); MainLayout->addWidget(FilenameBox, 0, 0, 1, 3); MainLayout->addWidget(LoadButton, 0, 3); MainLayout->addLayout(SpinLayout, 1, 0); MainLayout->addLayout(FormLayout, 2, 0); MainLayout->addWidget(SocketButton, 6,0); MainLayout->addWidget(M0Display, 3,0); MainLayout->addWidget(GetButton, 4,0); MainLayout->addWidget(ContinuousBox, 5,0); MainLayout->addWidget(TabWidget, 1, 1, 6, 5); MainLayout->setColumnStretch(1, 10); // Menu bar QMenu* Menu = menuBar()->addMenu("&Menu"); OpenAction = Menu->addAction("Open data file", this, SLOT(FileDialog())); OpenAction->setShortcut(Qt::CTRL + Qt::Key_O); QAction* SaveAction = Menu->addAction("Save plot", this, SLOT(MenuSave())); SaveAction->setShortcut(Qt::CTRL + Qt::Key_S); Menu->addAction("Print plot", this, SLOT(MenuPrint())); Menu->addSeparator(); ConnectAction = Menu->addAction("Connect", this, SLOT(MakeConnection())); ConnectAction->setShortcut(Qt::CTRL + Qt::Key_C); Menu->addSeparator(); Menu->addAction("Help", this, SLOT(MenuHelp())); Menu->addAction("About", this, SLOT(MenuAbout())); Menu->addSeparator(); QAction* QuitAction = Menu->addAction("Quit", qApp, SLOT(quit())); QuitAction->setShortcut(Qt::CTRL + Qt::Key_Q); //----------------------------------------------------------------------- //**************************** Socket window **************************** //----------------------------------------------------------------------- // Create widget (initially hidden) SocketWindow = new QWidget(); SocketWindow->setWindowTitle("ddd - Socket Interface"); // Edit box for IP Address IPAddress = new QLineEdit(SocketWindow); IPAddress->setText("eth-vme02"); IPAddress->setToolTip("Address of socket server"); AddressLayout = new QFormLayout; AddressLayout->addRow("&Remote Address", IPAddress); // SpinBox for port selection Port = new QSpinBox(SocketWindow); Port->setRange(0,65535); Port->setValue(2000); Port->setToolTip("Port number of socket server"); PortLayout = new QFormLayout; PortLayout->addRow("&Port", Port); // Button to make connection Connect = new QPushButton("Connect", SocketWindow); Connect->setFont(QFont("Times", 10, QFont::Bold)); connect(Connect, SIGNAL(clicked()), this, SLOT(MakeConnection())); Connect->setToolTip("Connect to server"); // Edit box for command Command = new QLineEdit(SocketWindow); CommandLayout = new QFormLayout; CommandLayout->addRow("&Command", Command); Command->setEnabled(false); connect(Command, SIGNAL(returnPressed()), this, SLOT(SendToSocket())); Command->setToolTip("Command to send to socket server"); // Text box for socket output SocketOutput= new QPlainTextEdit(SocketWindow); SocketOutput->setReadOnly(true); SocketOutput->setMaximumBlockCount(MAX_OUTPUT_LINES); SocketOutput->setToolTip("Output of socket server"); // Layout of all widgets SocketLayout = new QGridLayout(SocketWindow); SocketLayout->addLayout(AddressLayout, 0, 0, 0, 1); SocketLayout->addLayout(PortLayout, 0, 2); SocketLayout->addWidget(Connect, 0, 3); SocketLayout->addLayout(CommandLayout, 1, 0, 1, 4); SocketLayout->addWidget(SocketOutput, 2, 0, 4, 4); //----------------------------------------------------------------------- //**************************** M0 window **************************** //----------------------------------------------------------------------- M0Window = new QWidget(); M0Window->setWindowTitle("ddd - M0 Display"); Graph2D = new QwtPlot(M0Window); Graph2D->setAutoReplot(true); Graph2D->setCanvasBackground(QColor(Qt::white)); M0Layout = new QGridLayout(M0Window); M0Layout->addWidget(Graph2D, 1,1,3,3); Signal2D = new QwtPlotSpectrogram; Signal2D->attach(Graph2D); //initialize raster data of M0 display double z[6][6]; for (int i=0; i<6; i++){ for (int j=0; j<6; j++){ z[i][j]=i+j; } } Signal2D->setData(SpectrogramDataM0(z)); //color (z-) axis of M0 display colorMap = QwtLinearColorMap(Qt::yellow, Qt::red); Signal2D->setColorMap(colorMap); Graph2D->axisWidget(QwtPlot::yRight)->setTitle("Maximum Sample Amplitude (mV)"); Graph2D->axisWidget(QwtPlot::yRight)->setColorBarEnabled(true); Graph2D->axisWidget(QwtPlot::yRight)->setColorMap(Signal2D->data().range(),Signal2D->colorMap()); Graph2D->setAxisScale(QwtPlot::yRight,Signal2D->data().range().minValue(),Signal2D->data().range().maxValue()); Graph2D->enableAxis(QwtPlot::yRight); Graph2D->plotLayout()->setAlignCanvasToScales(true); Graph2D->replot(); } ddd::~ddd() { // Qwt items delete Grid; delete Signal; delete Signal2D; // Layout items delete PortLayout; delete CommandLayout; delete AddressLayout; delete FormLayout; delete SpinLayout; // Other items delete SocketWindow; delete M0Window; delete PixMap; delete RD; } //--------------------------------------------------------------------- //**************************** Main program *************************** //--------------------------------------------------------------------- int main(int argc, char *argv[]) { QApplication app(argc, argv); ddd MainWindow; MainWindow.setGeometry(100, 100, 800, 500); MainWindow.setWindowTitle("ddd - DRS Data Display"); MainWindow.show(); return app.exec(); }