/*************************************************************************** mupp_plot.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch This is the main entry point for the mupp_plot application, a standalone ROOT-based plotting program that works in conjunction with the mupp GUI. The program: - Takes a mupp instance number (0-255) as a command-line argument - Reads plot styling configuration from mupp_startup.xml - Creates a ROOT application with a PMuppCanvas for displaying plots - Establishes IPC communication with the mupp GUI via message queues - Monitors for plot data updates and refreshes the display accordingly - Provides interactive features (zoom, export, line/marker toggle) The mupp_plot application runs as a separate process from the main mupp GUI, allowing plots to be displayed and manipulated independently while maintaining synchronization with the data analysis workflow. ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007-2025 by Andreas Suter * * andreas.suter@psi.ch * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include #include #include #include #include "PMuppStartupHandler.h" #include "PMuppCanvas.h" //-------------------------------------------------------------------------- /** * @brief Main entry point for the mupp_plot application. * * Initializes the ROOT plotting environment, reads configuration from * mupp_startup.xml, creates the canvas, and runs the ROOT event loop. * * The program flow: * 1. Validates command-line arguments (mupp instance number) * 2. Parses mupp_startup.xml for marker styles, sizes, and colors * 3. Creates a TApplication and PMuppCanvas * 4. Sets up signal/slot connections for window management * 5. Runs the ROOT event loop * 6. Cleans up resources on exit * * @param argc number of command-line arguments (must be 2) * @param argv command-line arguments array; argv[1] must be instance number (0-255) * @return exit status: 0 on success, -1 if argc != 2, -2 if instance number out of range */ int main(int argc, char *argv[]) { if (argc != 2) { return -1; } int mupp_instance = (int)strtol(argv[1], NULL, 10); if ((mupp_instance < 0) || (mupp_instance > 255)) { return -2; } // read startup file char startup_path_name[128]; std::unique_ptr saxParser = std::make_unique(); std::unique_ptr startupHandler = std::make_unique(); if (!startupHandler->StartupFileFound()) { std::cerr << std::endl << ">> mupp_plot **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data(); std::cerr << std::endl; } else { strcpy(startup_path_name, startupHandler->GetStartupFilePath().Data()); saxParser->ConnectToHandler("PMuppStartupHandler", startupHandler.get()); // parsing the file as above seems to lead to problems in certain environments; // use the parseXmlFile function instead (see PMuppStartupHandler.cpp for the definition) Int_t status = parseXmlFile(saxParser.get(), startup_path_name); // check for parse errors if (status) { // error std::cerr << std::endl << ">> mupp_plot **WARNING** Reading/parsing mupp_startup.xml failed."; std::cerr << std::endl << ">> Graph will appear with random symbols and colors!"; std::cerr << std::endl; } else { startupHandler->CheckLists(); } } TApplication app("App", nullptr, nullptr); Bool_t ok=kTRUE; PMuppCanvas *muppCanvas = new PMuppCanvas("mupp", 10, 10, 600, 800, startupHandler->GetMarkerStyleList(), startupHandler->GetMarkerSizeList(), startupHandler->GetColorList(), mupp_instance); if (muppCanvas != nullptr) { if (muppCanvas->IsValid()) { // connect signal/slot TQObject::Connect("TCanvas", "Closed()", "PMuppCanvas", muppCanvas, "LastCanvasClosed()"); muppCanvas->Connect("Done(Int_t)", "TApplication", &app, "Terminate(Int_t)"); } else { std::cerr << std::endl << ">> mupp_plot **SEVERE ERROR** invoke object is invalid, will quit."; std::cerr << std::endl; ok = false; } } else { std::cerr << std::endl << ">> mupp_plot **SEVERE ERROR** Couldn't invoke all necessary objects, will quit."; std::cerr << std::endl; ok = false; } // check that everything is ok if (ok) app.Run(true); // true needed that Run will return after quit so that cleanup works // clean up if (muppCanvas) { delete muppCanvas; muppCanvas = 0; } return 0; }