diff --git a/src/classes/CMakeLists.txt b/src/classes/CMakeLists.txt index fe4f048db..1c90cfd5d 100644 --- a/src/classes/CMakeLists.txt +++ b/src/classes/CMakeLists.txt @@ -17,6 +17,15 @@ root_generate_dictionary( LINKDEF ${MUSRFIT_INC}/PFourierCanvasLinkDef.h MODULE PFourierCanvas ) +root_generate_dictionary( + PMsgBoxDict + PMsgBox.h + LINKDEF ${MUSRFIT_INC}/PMsgBoxLinkDef.h + OPTIONS + -I${Boost_INCLUDE_DIR} -I${FFTW3_INCLUDE} -I${MUSRFIT_INC} + -inlineInputHeader + MODULE PMsgBox +) root_generate_dictionary( PMusrCanvasDict PMusrCanvas.h @@ -72,7 +81,7 @@ set(prefix "${CMAKE_INSTALL_PREFIX}") set(exec_prefix "\$\{prefix\}") set(libdir "\$\{exec_prefix\}/lib") set(includedir "\$\{prefix\}/include") -set(MUSR_VERSION "1.5.0") +set(MUSR_VERSION "1.6.0") set(MUSR_LIBRARY_NAME "PMusr") configure_file("PMusr.pc.in" "PMusr.pc" @ONLY) set(USERFCN_LIBRARY_NAME "PUserFcnBase") @@ -93,6 +102,8 @@ add_library(PMusr SHARED PMusrCanvasDict.cxx PFunction.cpp PFunctionHandler.cpp + PMsgBox.cpp + PMsgBoxDict.cxx PMsr2Data.cpp PMsrHandler.cpp PMusrCanvas.cpp @@ -220,6 +231,8 @@ install(TARGETS PMusr DESTINATION lib) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libPFourierCanvas_rdict.pcm ${CMAKE_CURRENT_BINARY_DIR}/libPFourierCanvas.rootmap + ${CMAKE_CURRENT_BINARY_DIR}/libPMsgBox_rdict.pcm + ${CMAKE_CURRENT_BINARY_DIR}/libPMsgBox.rootmap ${CMAKE_CURRENT_BINARY_DIR}/libPMusrCanvas_rdict.pcm ${CMAKE_CURRENT_BINARY_DIR}/libPMusrCanvas.rootmap ${CMAKE_CURRENT_BINARY_DIR}/libPMusrT0_rdict.pcm diff --git a/src/classes/PMsgBox.cpp b/src/classes/PMsgBox.cpp new file mode 100644 index 000000000..4e939cd62 --- /dev/null +++ b/src/classes/PMsgBox.cpp @@ -0,0 +1,78 @@ +/*************************************************************************** + + PMsgBox.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * 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 "PMsgBox.h" + +PMsgBox::PMsgBox(const std::string errMsg, const TGWindow *p, UInt_t w, UInt_t h) : TGMainFrame(p, w, h) +{ + fListBox = new TGListBox(this, 89); + + // feed list box with errMsg + size_t start = 0; + size_t end = errMsg.find("\n"); + unsigned int i=1; + std::string tok{""}; + fListBox->AddEntry(tok.c_str(), i++); + while (end != std::string::npos) { + tok = errMsg.substr(start, end - start); + start = end + 1; + end = errMsg.find("\n", start); + fListBox->AddEntry(tok.c_str(), i++); + } + + fListBox->Resize(600, 200); + AddFrame(fListBox, new TGLayoutHints(kLHintsTop | kLHintsLeft | kLHintsExpandX | kLHintsExpandY, 5, 5, 5, 5)); + + // Create a horizontal frame containing button(s) + TGHorizontalFrame *hframe = new TGHorizontalFrame(this, 150, 20, kFixedWidth); + TGTextButton *exit = new TGTextButton(hframe, "&Exit "); + exit->Connect("Pressed()", "PMsgBox", this, "DoExit()"); + hframe->AddFrame(exit, new TGLayoutHints(kLHintsExpandX, 5, 5, 3, 4)); + AddFrame(hframe, new TGLayoutHints(kLHintsExpandX, 2, 2, 5, 1)); + + // Set a name to the main frame + SetWindowName("Error Message"); + MapSubwindows(); + + // Initialize the layout algorithm via Resize() + Resize(GetDefaultSize()); + + // Map main frame + MapWindow(); +} + +PMsgBox::~PMsgBox() +{ + // nothing to be done here? +} + +void PMsgBox::DoExit() +{ + gApplication->Terminate(0); +} diff --git a/src/classes/PMsrHandler.cpp b/src/classes/PMsrHandler.cpp index 0de97cd0a..9133dd4ab 100644 --- a/src/classes/PMsrHandler.cpp +++ b/src/classes/PMsrHandler.cpp @@ -276,9 +276,11 @@ Int_t PMsrHandler::ReadMsrFile() if ((result == PMUSR_SUCCESS) && !fFourierOnly) { UInt_t parX, parY; if (!CheckUniquenessOfParamNames(parX, parY)) { - std::cerr << std::endl << ">> PMsrHandler::ReadMsrFile: **SEVERE ERROR** parameter name " << fParam[parX].fName.Data() << " is identical for parameter no " << fParam[parX].fNo << " and " << fParam[parY].fNo << "!"; - std::cerr << std::endl << ">> Needs to be fixed first!"; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ReadMsrFile: **SEVERE ERROR** parameter name " << fParam[parX].fName.Data() << " is identical for parameter no " << fParam[parX].fNo << " and " << fParam[parY].fNo << "!\n"; + fLastErrorMsg << ">> Needs to be fixed first!\n"; + std::cerr << std::endl << fLastErrorMsg.str(); result = PMUSR_MSR_SYNTAX_ERROR; } } @@ -2443,8 +2445,10 @@ Int_t PMsrHandler::WriteMsrFile(const Char_t *filename, std::map= fParam.size()) { - std::cerr << std::endl << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is >= than the number of fit parameters " << fParam.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is >= than the number of fit parameters " << fParam.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -2470,8 +2474,10 @@ Bool_t PMsrHandler::SetMsrParamValue(UInt_t idx, Double_t value) Bool_t PMsrHandler::SetMsrParamStep(UInt_t idx, Double_t value) { if (idx >= fParam.size()) { - std::cerr << std::endl << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrParamValue(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -2496,8 +2502,10 @@ Bool_t PMsrHandler::SetMsrParamStep(UInt_t idx, Double_t value) Bool_t PMsrHandler::SetMsrParamPosErrorPresent(UInt_t idx, Bool_t value) { if (idx >= fParam.size()) { - std::cerr << std::endl << ">> PMsrHandler::SetMsrParamPosErrorPresent(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrParamPosErrorPresent(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -2522,8 +2530,10 @@ Bool_t PMsrHandler::SetMsrParamPosErrorPresent(UInt_t idx, Bool_t value) Bool_t PMsrHandler::SetMsrParamPosError(UInt_t idx, Double_t value) { if (idx >= fParam.size()) { - std::cerr << std::endl << ">> PMsrHandler::SetMsrParamPosError(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrParamPosError(): **ERROR** idx = " << idx << " is larger than the number of parameters " << fParam.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -2546,8 +2556,10 @@ Bool_t PMsrHandler::SetMsrParamPosError(UInt_t idx, Double_t value) void PMsrHandler::SetMsrT0Entry(UInt_t runNo, UInt_t idx, Double_t bin) { if (runNo >= fRuns.size()) { // error - std::cerr << std::endl << ">> PMsrHandler::SetMsrT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return; } @@ -2574,8 +2586,10 @@ void PMsrHandler::SetMsrT0Entry(UInt_t runNo, UInt_t idx, Double_t bin) void PMsrHandler::SetMsrAddT0Entry(UInt_t runNo, UInt_t addRunIdx, UInt_t histoIdx, Double_t bin) { if (runNo >= fRuns.size()) { // error - std::cerr << std::endl << ">> PMsrHandler::SetMsrAddT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrAddT0Entry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return; } @@ -2607,8 +2621,10 @@ void PMsrHandler::SetMsrAddT0Entry(UInt_t runNo, UInt_t addRunIdx, UInt_t histoI void PMsrHandler::SetMsrDataRangeEntry(UInt_t runNo, UInt_t idx, Int_t bin) { if (runNo >= fRuns.size()) { // error - std::cerr << std::endl << ">> PMsrHandler::SetMsrDataRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrDataRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return; } @@ -2628,8 +2644,10 @@ void PMsrHandler::SetMsrDataRangeEntry(UInt_t runNo, UInt_t idx, Int_t bin) void PMsrHandler::SetMsrBkgRangeEntry(UInt_t runNo, UInt_t idx, Int_t bin) { if (runNo >= fRuns.size()) { // error - std::cerr << std::endl << ">> PMsrHandler::SetMsrBkgRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size(); - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::SetMsrBkgRangeEntry: **ERROR** runNo = " << runNo << ", is out of valid range 0.." << fRuns.size() << "\n"; + std::cerr << fLastErrorMsg.str(); return; } @@ -2714,8 +2732,10 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) tokens = iter->fLine.Tokenize(" \t"); if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandleFitParameterEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleFitParameterEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -2832,28 +2852,27 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) // check if enough elements found if (error) { - std::cerr << std::endl; - std::cerr << std::endl << ">> PMsrHandler::HandleFitParameterEntry: **ERROR** in line " << iter->fLineNo << ":"; - std::cerr << std::endl << ">> " << iter->fLine.Data(); - std::cerr << std::endl << ">> A Fit Parameter line needs to have the following form: "; - std::cerr << std::endl; - std::cerr << std::endl << ">> No Name Value Step/Error [Lower_Boundary Upper_Boundary]"; - std::cerr << std::endl; - std::cerr << std::endl << ">> or"; - std::cerr << std::endl; - std::cerr << std::endl << ">> No Name Value Step/Neg_Error Pos_Error [Lower_Boundary Upper_Boundary]"; - std::cerr << std::endl; - std::cerr << std::endl << ">> No: the parameter number (an Int_t)"; - std::cerr << std::endl << ">> Name: the name of the parameter (less than 256 character)"; - std::cerr << std::endl << ">> Value: the starting value of the parameter (a Double_t)"; - std::cerr << std::endl << ">> Step/Error,"; - std::cerr << std::endl << ">> Step/Neg_Error: the starting step value in a fit (a Double_t), or"; - std::cerr << std::endl << ">> the symmetric error (MIGRAD, SIMPLEX), or"; - std::cerr << std::endl << ">> the negative error (MINOS)"; - std::cerr << std::endl << ">> Pos_Error: the positive error (MINOS), (a Double_t or \"none\")"; - std::cerr << std::endl << ">> Lower_Boundary: the lower boundary allowed for the fit parameter (a Double_t or \"none\")"; - std::cerr << std::endl << ">> Upper_Boundary: the upper boundary allowed for the fit parameter (a Double_t or \"none\")"; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << "\n"; + fLastErrorMsg << ">> PMsrHandler::HandleFitParameterEntry: **ERROR** in line " << iter->fLineNo << ":\n"; + fLastErrorMsg << ">> " << iter->fLine.Data() << "\n"; + fLastErrorMsg << ">> A Fit Parameter line needs to have the following form:\n"; + fLastErrorMsg << "\n"; + fLastErrorMsg << ">> No Name Value Step/Error [Lower_Boundary Upper_Boundary]\n\n"; + fLastErrorMsg << ">> or\n\n"; + fLastErrorMsg << ">> No Name Value Step/Neg_Error Pos_Error [Lower_Boundary Upper_Boundary]\n\n"; + fLastErrorMsg << ">> No: the parameter number (an Int_t)\n"; + fLastErrorMsg << ">> Name: the name of the parameter (less than 256 character)\n"; + fLastErrorMsg << ">> Value: the starting value of the parameter (a Double_t)\n"; + fLastErrorMsg << ">> Step/Error,\n"; + fLastErrorMsg << ">> Step/Neg_Error: the starting step value in a fit (a Double_t), or\n"; + fLastErrorMsg << ">> the symmetric error (MIGRAD, SIMPLEX), or\n"; + fLastErrorMsg << ">> the negative error (MINOS)\n"; + fLastErrorMsg << ">> Pos_Error: the positive error (MINOS), (a Double_t or \"none\")\n"; + fLastErrorMsg << ">> Lower_Boundary: the lower boundary allowed for the fit parameter (a Double_t or \"none\")\n"; + fLastErrorMsg << ">> Upper_Boundary: the upper boundary allowed for the fit parameter (a Double_t or \"none\")\n"; + std::cerr << fLastErrorMsg.str(); } else { // everything is OK, therefore add the parameter to the parameter list fParam.push_back(param); } @@ -2871,13 +2890,15 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) for (UInt_t i=0; i(i)+1) { error = true; - std::cerr << std::endl << ">> PMsrHandler::HandleFitParameterEntry: **ERROR**"; - std::cerr << std::endl << ">> Sorry, you are assuming to much from this program, it cannot"; - std::cerr << std::endl << ">> handle none subsequent numbered parameters yet or in the near future."; - std::cerr << std::endl << ">> Found parameter " << fParam[i].fName.Data() << ", with"; - std::cerr << std::endl << ">> parameter number " << fParam[i].fNo << ", at paramter position " << i+1 << "."; - std::cerr << std::endl << ">> This needs to be fixed first."; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleFitParameterEntry: **ERROR**\n"; + fLastErrorMsg << ">> Sorry, you are assuming to much from this program, it cannot\n"; + fLastErrorMsg << ">> handle none subsequent numbered parameters yet or in the near future.\n"; + fLastErrorMsg << ">> Found parameter " << fParam[i].fName.Data() << ", with\n"; + fLastErrorMsg << ">> parameter number " << fParam[i].fNo << ", at paramter position " << i+1 << ".\n"; + fLastErrorMsg << ">> This needs to be fixed first.\n"; + std::cerr << fLastErrorMsg.str(); break; } } @@ -2986,8 +3007,10 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) // tokenize line tokens = str.Tokenize(" \t"); if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandleGlobalEntry: **SEVERE ERROR** Couldn't tokenize line " << iter->fLineNo; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleGlobalEntry: **SEVERE ERROR** Couldn't tokenize line " << iter->fLineNo << "\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -3197,9 +3220,12 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) if (error) { --iter; - std::cerr << std::endl << ">> PMsrHandler::HandleGlobalEntry: **ERROR** in line " << iter->fLineNo << ":"; - std::cerr << std::endl << ">> '" << iter->fLine.Data() << "'"; - std::cerr << std::endl << ">> GLOBAL block syntax is too complex to print it here. Please check the manual."; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleGlobalEntry: **ERROR** in line " << iter->fLineNo << ":\n"; + fLastErrorMsg << ">> '" << iter->fLine.Data() << "'\n"; + fLastErrorMsg << ">> GLOBAL block syntax is too complex to print it here. Please check the manual.\n"; + std::cerr << fLastErrorMsg.str(); } else { // save global fGlobal = global; } @@ -3250,8 +3276,10 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) // tokenize line tokens = str.Tokenize(" \t"); if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -3307,10 +3335,12 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) if (line.BeginsWith("addrun", TString::kIgnoreCase)) { if (!runLinePresent) { - std::cerr << std::endl << ">> PMsrHandler::HandleRunEntry: **ERROR** Found ADDRUN without prior RUN, or"; - std::cerr << std::endl << ">> ADDRUN lines intercepted by other stuff. All this is not allowed!"; - std::cerr << std::endl << ">> error in line " << iter->fLineNo; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleRunEntry: **ERROR** Found ADDRUN without prior RUN, or\n"; + fLastErrorMsg << ">> ADDRUN lines intercepted by other stuff. All this is not allowed!\n"; + fLastErrorMsg << ">> error in line " << iter->fLineNo << "\n"; + std::cerr << fLastErrorMsg.str(); error = true; continue; } @@ -3521,7 +3551,10 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) if (!fFourierOnly) { for (UInt_t i=0; isize(); i++) { if ((param.GetMap(i) < 0) || (param.GetMap(i) > static_cast(fParam.size()))) { - std::cerr << std::endl << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** map value " << param.GetMap(i) << " in line " << iter->fLineNo << " is out of range!"; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** map value " << param.GetMap(i) << " in line " << iter->fLineNo << " is out of range!\n"; + std::cerr << fLastErrorMsg.str(); error = true; break; } @@ -3814,9 +3847,12 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) if (error) { --iter; - std::cerr << std::endl << ">> PMsrHandler::HandleRunEntry: **ERROR** in line " << iter->fLineNo << ":"; - std::cerr << std::endl << ">> " << iter->fLine.Data(); - std::cerr << std::endl << ">> RUN block syntax is too complex to print it here. Please check the manual."; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleRunEntry: **ERROR** in line " << iter->fLineNo << ":\n"; + fLastErrorMsg << ">> " << iter->fLine.Data() << "\n"; + fLastErrorMsg << ">> RUN block syntax is too complex to print it here. Please check the manual.\n"; + std::cerr << fLastErrorMsg.str(); } else { // save last run found fRuns.push_back(param); param.CleanUp(); @@ -3969,7 +4005,10 @@ Bool_t PMsrHandler::ParseFourierPhaseValueVector(PMsrFourierStructure &fourier, TObjArray *tok = str.Tokenize(" ,;\t"); if (tok == nullptr) { - std::cerr << std::endl << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** couldn't tokenize Fourier phase line." << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** couldn't tokenize Fourier phase line.\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -3990,8 +4029,11 @@ Bool_t PMsrHandler::ParseFourierPhaseValueVector(PMsrFourierStructure &fourier, } else { result = false; if (i>1) { // make sure that no 'phase val, parX' mixture is present - std::cerr << std::endl << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** in Fourier phase line."; - std::cerr << std::endl << ">> Attempt to mix val, parX? This is currently not supported." << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** in Fourier phase line.\n"; + fLastErrorMsg << ">> Attempt to mix val, parX? This is currently not supported.\n\n"; + std::cerr << fLastErrorMsg.str(); error = true; } break; @@ -4029,7 +4071,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co TObjArray *tok = str.Tokenize(" ,;\t"); if (tok == nullptr) { - std::cerr << std::endl << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** couldn't tokenize Fourier phase line." << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** couldn't tokenize Fourier phase line.\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -4045,7 +4090,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co TObjString *ostr = dynamic_cast(tok->At(i)); sstr = ostr->GetString(); if (!sstr.BeginsWith("par")) { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found unhandable token '" << sstr << "'" << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found unhandable token '" << sstr << "'\n"; + std::cerr << fLastErrorMsg.str(); error = true; result = false; break; @@ -4063,7 +4111,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co } if (refCount > 1) { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found multiple parR's! Only one reference phase is accepted." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found multiple parR's! Only one reference phase is accepted.\n"; + std::cerr << fLastErrorMsg.str(); result = false; } @@ -4083,7 +4134,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co fourier.fPhaseRef = sstr.Atoi(); fourier.fPhaseParamNo.push_back(sstr.Atoi()); } else { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found token '" << ostr->GetString() << "' which is not parX with X an integer." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found token '" << ostr->GetString() << "' which is not parX with X an integer.\n"; + std::cerr << fLastErrorMsg.str(); fourier.fPhaseParamNo.clear(); error = true; break; @@ -4129,7 +4183,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier // remove 'par(' from string if present, otherwise and error is issued if (!wstr.BeginsWith("par(") && !wstr.BeginsWith("parR(")) { - std::cout << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** token should start with 'par(' or 'parR(', found: '" << wstr << "' -> ERROR" << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** token should start with 'par(' or 'parR(', found: '" << wstr << "' -> ERROR\n"; + std::cerr << fLastErrorMsg.str(); error = true; return false; } @@ -4151,14 +4208,20 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier // tokenize rest which should have the form 'X0, offset, #Param' TObjArray *tok = wstr.Tokenize(",;"); if (tok == nullptr) { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** tokenize failed." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** tokenize failed.\n"; + std::cerr << fLastErrorMsg.str(); error = true; return false; } // check for proper number of expected elements if (tok->GetEntries() != 3) { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** wrong syntax for the expected par(X0, offset, #param)." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** wrong syntax for the expected par(X0, offset, #param).\n"; + std::cerr << fLastErrorMsg.str(); error = true; delete tok; return false; @@ -4172,7 +4235,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier if (wstr.IsDigit()) { x0 = wstr.Atoi(); } else { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** X0='" << wstr << "' is not an integer." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** X0='" << wstr << "' is not an integer.\n"; + std::cerr << fLastErrorMsg.str(); error = true; delete tok; return false; @@ -4184,7 +4250,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier if (wstr.IsDigit()) { offset = wstr.Atoi(); } else { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** offset='" << wstr << "' is not an integer." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** offset='" << wstr << "' is not an integer.\n"; + std::cerr << fLastErrorMsg.str(); error = true; delete tok; return false; @@ -4196,7 +4265,10 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier if (wstr.IsDigit()) { noParam = wstr.Atoi(); } else { - std::cerr << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** #Param='" << wstr << "' is not an integer." << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** #Param='" << wstr << "' is not an integer.\n"; + std::cerr << fLastErrorMsg.str(); error = true; delete tok; return false; @@ -4257,8 +4329,10 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) // tokenize line tokens = iter->fLine.Tokenize(" \t"); if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandleFourierEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleFourierEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } @@ -4401,7 +4475,10 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) if (fourier.fPhaseParamNo.size() > 0) { for (UInt_t i=0; i fParam.size()) { - std::cerr << ">> PMsrHandler::HandleFourierEntry: found Fourier parameter entry par" << fourier.fPhaseParamNo[i] << " > #Param = " << fParam.size() << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleFourierEntry: found Fourier parameter entry par" << fourier.fPhaseParamNo[i] << " > #Param = " << fParam.size() << "\n"; + std::cerr << fLastErrorMsg.str(); error = true; --iter; continue; @@ -4507,28 +4584,28 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) } if (error) { - std::cerr << std::endl << ">> PMsrHandler::HandleFourierEntry: **ERROR** in line " << iter->fLineNo << ":"; - std::cerr << std::endl; - std::cerr << std::endl << ">> " << iter->fLine.Data(); - std::cerr << std::endl; - std::cerr << std::endl << ">> FOURIER block syntax, parameters in [] are optinal:"; - std::cerr << std::endl; - std::cerr << std::endl << ">> FOURIER"; - std::cerr << std::endl << ">> [units Gauss | MHz | Mc/s]"; - std::cerr << std::endl << ">> [fourier_power n # n is a number such that zero padding up to 2^n will be used]"; - std::cerr << std::endl << ">> n=0 means no zero padding"; - std::cerr << std::endl << ">> 0 <= n <= 20 are allowed values"; - std::cerr << std::endl << ">> [dc-corrected true | false]"; - std::cerr << std::endl << ">> [apodization none | weak | medium | strong]"; - std::cerr << std::endl << ">> [plot real | imag | real_and_imag | power | phase | phase_opt_real]"; - std::cerr << std::endl << ">> [phase valList | parList | parIterList [# comment]]"; - std::cerr << std::endl << ">> valList : val [sep val ... sep val]. sep=' ,;\\t'"; - std::cerr << std::endl << ">> parList : parX0 [sep parX1 ... sep parX1]"; - std::cerr << std::endl << ">> parIterList : par(X0,offset,#param), with X0=first parameter number"; - std::cerr << std::endl << ">> offset=parameter offset, #param=number of phase parameters."; - std::cerr << std::endl << ">> [range_for_phase_correction min max | all]"; - std::cerr << std::endl << ">> [range min max]"; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandleFourierEntry: **ERROR** in line " << iter->fLineNo << ":\n\n"; + fLastErrorMsg << ">> " << iter->fLine.Data() << "\n\n"; + fLastErrorMsg << ">> FOURIER block syntax, parameters in [] are optinal:\n\n"; + fLastErrorMsg << ">> FOURIER\n"; + fLastErrorMsg << ">> [units Gauss | MHz | Mc/s]\n"; + fLastErrorMsg << ">> [fourier_power n # n is a number such that zero padding up to 2^n will be used]\n"; + fLastErrorMsg << ">> n=0 means no zero padding\n"; + fLastErrorMsg << ">> 0 <= n <= 20 are allowed values\n"; + fLastErrorMsg << ">> [dc-corrected true | false]\n"; + fLastErrorMsg << ">> [apodization none | weak | medium | strong]\n"; + fLastErrorMsg << ">> [plot real | imag | real_and_imag | power | phase | phase_opt_real]\n"; + fLastErrorMsg << ">> [phase valList | parList | parIterList [# comment]]\n"; + fLastErrorMsg << ">> valList : val [sep val ... sep val]. sep=' ,;\\t'\n"; + fLastErrorMsg << ">> parList : parX0 [sep parX1 ... sep parXn], Xi is the parameter number\n"; + fLastErrorMsg << ">> parList : parRX0 sep parX1 ... sep parXn, parRX0 is the reference phase, e.g. parR3\n"; + fLastErrorMsg << ">> parIterList : par(X0,offset,#param), with X0=first parameter number\n"; + fLastErrorMsg << ">> offset=parameter offset, #param=number of phase parameters.\n"; + fLastErrorMsg << ">> [range_for_phase_correction min max | all]\n"; + fLastErrorMsg << ">> [range min max]\n"; + std::cerr << fLastErrorMsg.str(); } else { // save last run found fFourier = fourier; } @@ -4603,8 +4680,10 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) if (line.Contains("PLOT")) { // handle plot header tokens = line.Tokenize(" \t"); if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo << "\n\n"; + std::cerr << fLastErrorMsg.str(); return false; } if (tokens->GetEntries() < 2) { // plot type missing @@ -4642,9 +4721,11 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) case MSR_PLOT_MU_MINUS: rl = std::make_unique(line.Data()); if (!rl->Parse(errorMsg, true)) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; - std::cerr << std::endl << ">> Error Message: " << errorMsg; - std::cerr << std::endl << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo << "\n"; + fLastErrorMsg << ">> Error Message: " << errorMsg; + std::cerr << fLastErrorMsg.str(); return false; } runList = rl->GetList(); @@ -6379,9 +6460,11 @@ Bool_t PMsrHandler::CheckAddRunParameters() // check concerning the addt0 tags if (fRuns[i].GetAddT0BinEntries() != 0) { if (fRuns[i].GetAddT0BinEntries() != fRuns[i].GetRunNameSize()-1) { - std::cerr << std::endl << ">> PMsrHandler::CheckAddRunParameters: **ERROR** # of addt0 != # of addruns."; - std::cerr << std::endl << ">> Run #" << i+1; - std::cerr << std::endl; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::CheckAddRunParameters: **ERROR** # of addt0 != # of addruns.\n"; + fLastErrorMsg << ">> Run #" << i+1 << "\n"; + std::cerr << std::endl << fLastErrorMsg.str(); result = false; break; } @@ -6406,8 +6489,10 @@ void PMsrHandler::CheckMaxLikelihood() for (UInt_t i=0; i> PMsrHandler::CheckMaxLikelihood: **WARNING**: Maximum Log Likelihood Fit is only implemented"; - std::cerr << std::endl << ">> for Single Histogram and Mu Minus Fits. Will fall back to Chi Square Fit."; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::CheckMaxLikelihood: **WARNING**: Maximum Log Likelihood Fit is only implemented\n"; + fLastErrorMsg << ">> for Single Histogram and Mu Minus Fits. Will fall back to Chi Square Fit.\n"; std::cerr << std::endl << std::endl; fStatistic.fChisq = true; break; @@ -6530,24 +6615,30 @@ Bool_t PMsrHandler::CheckRealFFT() // check if the given phases in the Fourier block are in agreement with the Plot block settings if ((fFourier.fPhase.size() > 1) && (fPlots.size() > 0)) { if (fFourier.fPhase.size() != fPlots[0].fRuns.size()) { - std::cerr << std::endl << ">> PMsrHandler::ReadMsrFile: **ERROR** if more than one phase is given in the Fourier block,"; - std::cerr << std::endl << ">> it needs to correspond to the number of runs in the Plot block!" << std::endl; - std::cerr << std::endl << ">> currently:"; - std::cerr << std::endl << ">> number of runs in the PLOT block: " << fPlots[0].fRuns.size(); - std::cerr << std::endl << ">> number of phases in the FOURIER block: " << fFourier.fPhase.size(); + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ReadMsrFile: **ERROR** if more than one phase is given in the Fourier block,\n"; + fLastErrorMsg << ">> it needs to correspond to the number of runs in the Plot block!\n"; + fLastErrorMsg << ">> currently:\n"; + fLastErrorMsg << ">> number of runs in the PLOT block: " << fPlots[0].fRuns.size() << "\n"; + fLastErrorMsg << ">> number of phases in the FOURIER block: " << fFourier.fPhase.size() << "\n"; + std::cerr << std::endl << fLastErrorMsg.str(); return false; } } // make sure that FOURIER phases are defined if ((fFourier.fPhase.size() == 0) && (fFourier.fPhaseParamNo.size() == 0)) { - std::cerr << std::endl << ">> PMsrHandler::ReadMsrFile: **ERROR** for FOURIER plot != POWER,"; - std::cerr << std::endl << ">> phases need to be defined in the FOURIER block!"; - std::cerr << std::endl << ">> Examples:"; - std::cerr << std::endl << ">> phase parR7 par9 par13 par16"; - std::cerr << std::endl << ">> where parR7 is the reference phase, and the others the relative phases."; - std::cerr << std::endl << ">> I.e. phase of run 2: parR7 + par9, etc."; - std::cerr << std::endl << ">> For further details see the docu."; + fLastErrorMsg.str(""); + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ReadMsrFile: **ERROR** for FOURIER plot != POWER,\n"; + fLastErrorMsg << ">> phases need to be defined in the FOURIER block!\n"; + fLastErrorMsg << ">> Examples:\n"; + fLastErrorMsg << ">> phase parR7 par9 par13 par16\n"; + fLastErrorMsg << ">> where parR7 is the reference phase, and the others the relative phases.\n"; + fLastErrorMsg << ">> I.e. phase of run 2: parR7 + par9, etc.\n"; + fLastErrorMsg << ">> For further details see the docu.\n"; + std::cerr << std::endl << fLastErrorMsg.str(); return false; } diff --git a/src/include/PMsgBox.h b/src/include/PMsgBox.h new file mode 100644 index 000000000..2abfecc6b --- /dev/null +++ b/src/include/PMsgBox.h @@ -0,0 +1,54 @@ +/*************************************************************************** + + PMsgBox.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifndef _PMSGBOX_H_ +#define _PMSGBOX_H_ + +#include + +#include +#include +#include +#include +#include + +class PMsgBox : public TGMainFrame { + +private: + TGListBox *fListBox; + +public: + PMsgBox(const std::string errMsg, const TGWindow *p, UInt_t w, UInt_t h); + ~PMsgBox() override; + void DoExit(); + + ClassDefOverride(PMsgBox, 0) +}; + +#endif // _PMSGBOX_H_ diff --git a/src/include/PMsgBoxLinkDef.h b/src/include/PMsgBoxLinkDef.h new file mode 100644 index 000000000..81a6ca2db --- /dev/null +++ b/src/include/PMsgBoxLinkDef.h @@ -0,0 +1,39 @@ +/*************************************************************************** + + PMsgBoxLinkDef.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * 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. * + ***************************************************************************/ + +#ifdef __CINT__ + +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +#pragma link C++ class PMsgBox+; + +#endif + diff --git a/src/include/PMsrHandler.h b/src/include/PMsrHandler.h index ec0b363bf..2601c30b1 100644 --- a/src/include/PMsrHandler.h +++ b/src/include/PMsrHandler.h @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include @@ -103,6 +105,8 @@ class PMsrHandler virtual void GetGroupingString(Int_t runNo, TString detector, TString &groupingStr); virtual Bool_t EstimateN0(); + + virtual std::string GetLastErrorMsg() { return fLastErrorMsg.str(); } virtual std::string GetDKSTheoryString(); virtual UInt_t GetDKSTag(); @@ -135,6 +139,8 @@ class PMsrHandler Int_t fNoOfMaps; + std::stringstream fLastErrorMsg; + virtual Bool_t HandleFitParameterEntry(PMsrLines &line); virtual Bool_t HandleTheoryEntry(PMsrLines &line); virtual Bool_t HandleFunctionsEntry(PMsrLines &line); diff --git a/src/musredit_qt5/musredit/PTextEdit.cpp b/src/musredit_qt5/musredit/PTextEdit.cpp index 39cb0dc00..615d6a5f1 100644 --- a/src/musredit_qt5/musredit/PTextEdit.cpp +++ b/src/musredit_qt5/musredit/PTextEdit.cpp @@ -2620,6 +2620,9 @@ void PTextEdit::musrView() if (fAdmin->getMusrviewShowOneToOneFlag()) arg << "-1"; + // add error message box option + arg << "-s"; + QProcess proc; // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); diff --git a/src/musredit_qt6/musredit/PTextEdit.cpp b/src/musredit_qt6/musredit/PTextEdit.cpp index 4842db736..3c28f8370 100644 --- a/src/musredit_qt6/musredit/PTextEdit.cpp +++ b/src/musredit_qt6/musredit/PTextEdit.cpp @@ -2612,6 +2612,9 @@ void PTextEdit::musrView() if (fAdmin->getMusrviewShowOneToOneFlag()) arg << "-1"; + // add error message box option + arg << "-s"; + QProcess proc; // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); diff --git a/src/musrview.cpp b/src/musrview.cpp index 9561d2b44..3660be40c 100644 --- a/src/musrview.cpp +++ b/src/musrview.cpp @@ -38,6 +38,8 @@ #include #include #include +#include + #include #include @@ -53,6 +55,7 @@ #include "PRunDataHandler.h" #include "PRunListCollection.h" #include "PMusrCanvas.h" +#include "PMsgBox.h" //-------------------------------------------------------------------------- @@ -81,9 +84,21 @@ void musrview_syntax() std::cout << std::endl << " will produce an ascii dump of the data and fit as plotted."; std::cout << std::endl << " --timeout : given in seconds after which musrview terminates."; std::cout << std::endl << " If <= 0, no timeout will take place. Default is 0."; + std::cout << std::endl << " -s, --show-errMsgBox: if this tag is defined, error message boxes are shown,"; + std::cout << std::endl << " rather than only stderr output."; std::cout << std::endl << std::endl; } +//-------------------------------------------------------------------------- +void musrview_error_msg(std::string errMsg) +{ + int argc=0; + char **argv; + TApplication app("musrviewErrorMsg", &argc, argv); + new PMsgBox(errMsg, gClient->GetRoot(), 600, 200); + app.Run(); +} + //-------------------------------------------------------------------------- /** *

The musrview program is used to show muSR fit results in graphical form. @@ -104,18 +119,20 @@ void musrview_syntax() */ int main(int argc, char *argv[]) { - int result = PMUSR_SUCCESS; - bool show_syntax = false; + int result{PMUSR_SUCCESS}; + bool show_syntax{false}; int status; - bool success = true; + bool success{true}; char fileName[128]; - bool fourier = false; - bool avg = false; - bool theoAtData = false; // theory points only at data points - bool graphicsOutput = false; - bool asciiOutput = false; + bool fourier{false}; + bool avg{false}; + bool theoAtData{false}; // theory points only at data points + bool graphicsOutput{false}; + bool asciiOutput{false}; char graphicsExtension[128]; - int timeout = 0; + int timeout{0}; + bool show_errMsgBox{false}; + std::stringstream errMsg; memset(fileName, '\0', sizeof(fileName)); @@ -188,6 +205,8 @@ int main(int argc, char *argv[]) show_syntax = true; break; } + } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--show-errMsgBox")) { + show_errMsgBox = true; } else { show_syntax = true; break; @@ -227,17 +246,24 @@ int main(int argc, char *argv[]) std::unique_ptr msrHandler = std::make_unique(fileName); status = msrHandler->ReadMsrFile(); if (status != PMUSR_SUCCESS) { + errMsg << msrHandler->GetLastErrorMsg(); switch (status) { case PMUSR_MSR_FILE_NOT_FOUND: - std::cerr << std::endl << ">> musrview **ERROR** couldn't find '" << fileName << "'" << std::endl << std::endl; + errMsg << "\n"; + errMsg << ">> musrview **ERROR** couldn't find '" << fileName << "'\n\n"; break; case PMUSR_MSR_SYNTAX_ERROR: - std::cerr << std::endl << ">> musrview **SYNTAX ERROR** in file " << fileName << ", full stop here." << std::endl << std::endl; + errMsg << "\n"; + errMsg << ">> musrview **SYNTAX ERROR** in file " << fileName << ", full stop here.\n\n"; break; default: - std::cerr << std::endl << ">> musrview **UNKNOWN ERROR** when trying to read the msr-file" << std::endl << std::endl; + errMsg << "\n"; + errMsg << ">> musrview **UNKNOWN ERROR** when trying to read the msr-file.\n\n"; break; } + std::cerr << errMsg.str(); + if (show_errMsgBox) + musrview_error_msg(errMsg.str()); return status; } // make a plot list vector