musrfit 1.10.0
musrview.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 musrview.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <stdio.h>
35#include <stdlib.h>
36#include <string.h>
37
38#include <iostream>
39#include <memory>
40#include <string>
41#include <vector>
42#include <sstream>
43
44
45#include <TApplication.h>
46#include <TSAXParser.h>
47#include <TROOT.h>
48
49#ifdef HAVE_GIT_REV_H
50#include "git-revision.h"
51#endif
52
53#include "PMusr.h"
54#include "PStartupHandler.h"
55#include "PMsrHandler.h"
56#include "PRunDataHandler.h"
57#include "PRunListCollection.h"
58#include "PMusrCanvas.h"
59#include "PMsgBox.h"
60
61
62//--------------------------------------------------------------------------
67{
68 std::cout << std::endl << "usage: musrview <msr-file> [Options]";
69 std::cout << std::endl << " <msr-file>: msr/mlog input file";
70 std::cout << std::endl << " Options:";
71 std::cout << std::endl << " --help : display this help and exit.";
72 std::cout << std::endl << " --version : output version information and exit.";
73 std::cout << std::endl << " --show-dynamic-path : dumps the dynamic search paths and exit.";
74 std::cout << std::endl << " -f, --fourier: will directly present the Fourier transform of the <msr-file>.";
75 std::cout << std::endl << " -a, --avg: will directly present the averaged data/Fourier of the <msr-file>.";
76 std::cout << std::endl << " -1, --one_to_one: calculate theory points only at data points.";
77 std::cout << std::endl << " --<graphic-format-extension>: ";
78 std::cout << std::endl << " will produce a graphics-output-file without starting a root session.";
79 std::cout << std::endl << " the name is based on the <msr-file>, e.g. 3310.msr -> 3310_0.png";
80 std::cout << std::endl << " supported graphic-format-extension:";
81 std::cout << std::endl << " eps, pdf, gif, jpg, png, svg, xpm, root";
82 std::cout << std::endl << " example: musrview 3310.msr --png, will produce a files 3310_X.png";
83 std::cout << std::endl << " where 'X' stands for the plot number (starting form 0)";
84 std::cout << std::endl << " --ascii: ";
85 std::cout << std::endl << " will produce an ascii dump of the data and fit as plotted.";
86 std::cout << std::endl << " --timeout <timeout>: <timeout> given in seconds after which musrview terminates.";
87 std::cout << std::endl << " If <timeout> <= 0, no timeout will take place. Default <timeout> is 0.";
88 std::cout << std::endl << " -s, --show-errMsgBox: if this tag is defined, error message boxes are shown,";
89 std::cout << std::endl << " rather than only stderr output.";
90 std::cout << std::endl << std::endl;
91}
92
93//--------------------------------------------------------------------------
94void musrview_error_msg(std::string errMsg)
95{
96 int argc=0;
97 char **argv;
98 TApplication app("musrviewErrorMsg", &argc, argv);
99 new PMsgBox(errMsg, gClient->GetRoot(), 600, 200);
100 app.Run();
101}
102
103//--------------------------------------------------------------------------
121int main(int argc, char *argv[])
122{
123 int result{PMUSR_SUCCESS};
124 bool show_syntax{false};
125 int status;
126 bool success{true};
127 std::string fileName{};
128 bool fourier{false};
129 bool avg{false};
130 bool theoAtData{false}; // theory points only at data points
131 bool graphicsOutput{false};
132 bool asciiOutput{false};
133 std::string graphicsExtension{};
134 int timeout{0};
135 bool show_errMsgBox{false};
136 std::stringstream errMsg;
137
138 // add default shared library path /usr/local/lib if not already persent
139 const char *dsp = gSystem->GetDynamicPath();
140 if (strstr(dsp, "/usr/local/lib") == nullptr)
141 gSystem->AddDynamicPath("/usr/local/lib");
142
143 // check input arguments
144 if (argc == 1) {
147 }
148 for (int i=1; i<argc; i++) {
149 if (strstr(argv[i], ".msr") || strstr(argv[i], ".mlog")) {
150 if (fileName.empty()) {
151 fileName = argv[i];
152 } else {
153 std::cerr << std::endl << "**ERROR** only one file name allowed." << std::endl;
154 show_syntax = true;
155 break;
156 }
157 } else if (!strcmp(argv[i], "--version")) {
158#ifdef HAVE_CONFIG_H
159#ifdef HAVE_GIT_REV_H
160 std::cout << std::endl << "musrview version: " << PACKAGE_VERSION << ", git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
161#else
162 std::cout << std::endl << "musrview version: " << PACKAGE_VERSION << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
163#endif
164#else
165#ifdef HAVE_GIT_REV_H
166 std::cout << std::endl << "musrview git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
167#else
168 std::cout << std::endl << "musrview version: unknown." << std::endl << std::endl;
169#endif
170#endif
171 return PMUSR_SUCCESS;
172 } else if (!strcmp(argv[i], "--show-dynamic-path")) {
173 std::cout << std::endl << "musrview: internal dynamic search paths for shared libraries/root dictionaries:";
174 std::cout << std::endl << " '" << gSystem->GetDynamicPath() << "'" << std::endl << std::endl;
175 return PMUSR_SUCCESS;
176 } else if (!strcmp(argv[i], "--help")) {
177 show_syntax = true;
178 break;
179 } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--fourier")) {
180 fourier = true;
181 } else if (!strcmp(argv[i], "-a") || !strcmp(argv[i], "--avg")) {
182 avg = true;
183 } else if (!strcmp(argv[i], "-1") || !strcmp(argv[i], "--one_to_one")) {
184 theoAtData = true;
185 } else if (!strcmp(argv[i], "--eps") || !strcmp(argv[i], "--pdf") || !strcmp(argv[i], "--gif") ||
186 !strcmp(argv[i], "--jpg") || !strcmp(argv[i], "--png") || !strcmp(argv[i], "--svg") ||
187 !strcmp(argv[i], "--xpm") || !strcmp(argv[i], "--root")) {
188
189 graphicsOutput = true;
190 graphicsExtension = argv[i]+2;
191 } else if (!strcmp(argv[i], "--ascii")) {
192 asciiOutput = true;
193 } else if (!strcmp(argv[i], "--timeout")) {
194 if (i+1 < argc) {
195 TString str(argv[i+1]);
196 if (str.IsFloat()) {
197 timeout = str.Atoi();
198 } else {
199 show_syntax = true;
200 break;
201 }
202 i++;
203 } else {
204 show_syntax = true;
205 break;
206 }
207 } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--show-errMsgBox")) {
208 show_errMsgBox = true;
209 } else {
210 show_syntax = true;
211 break;
212 }
213 }
214
215 if (show_syntax) {
218 }
219
220 // read startup file
221 std::string startup_path_name{};
222 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
223 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>();
224 if (!startupHandler->StartupFileFound()) {
225 std::cerr << std::endl << ">> musrview **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
226 std::cerr << std::endl;
227 } else {
228 startup_path_name = startupHandler->GetStartupFilePath().Data();
229 saxParser->ConnectToHandler("PStartupHandler", startupHandler.get());
230 //status = saxParser->ParseFile(startup_path_name);
231 // parsing the file as above seems to lead to problems in certain environments;
232 // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition)
233 status = parseXmlFile(saxParser.get(), startup_path_name.c_str());
234 // check for parse errors
235 if (status) { // error
236 std::cerr << std::endl << ">> musrview **WARNING** Reading/parsing musrfit_startup.xml failed.";
237 std::cerr << std::endl << ">> Any graph will appear with random symbols and colors!";
238 std::cerr << std::endl;
239 } else {
240 startupHandler->CheckLists();
241 }
242 }
243
244 // read msr-file
245 std::unique_ptr<PMsrHandler> msrHandler = std::make_unique<PMsrHandler>(fileName.c_str());
246 status = msrHandler->ReadMsrFile();
247 if (status != PMUSR_SUCCESS) {
248 errMsg << msrHandler->GetLastErrorMsg();
249 switch (status) {
251 errMsg << "\n";
252 errMsg << ">> musrview **ERROR** couldn't find '" << fileName << "'\n\n";
253 break;
255 errMsg << "\n";
256 errMsg << ">> musrview **SYNTAX ERROR** in file " << fileName << ", full stop here.\n\n";
257 break;
258 default:
259 errMsg << "\n";
260 errMsg << ">> musrview **UNKNOWN ERROR** when trying to read the msr-file.\n\n";
261 break;
262 }
263 std::cerr << errMsg.str();
264 if (show_errMsgBox)
265 musrview_error_msg(errMsg.str());
266 return status;
267 }
268 // make a plot list vector
269 PMsrPlotList *msrPlotList = msrHandler->GetMsrPlotList();
270 PIntVector plotList;
271 bool runPresent;
272 for (unsigned int i=0; i<msrPlotList->size(); i++) {
273 for (unsigned int j=0; j<msrPlotList->at(i).fRuns.size(); j++) {
274 // check that run is not already in the plotList
275 runPresent = false;
276 for (unsigned int k=0; k<plotList.size(); k++) {
277 if (msrPlotList->at(i).fRuns[j] == static_cast<int>(plotList[k])) {
278 runPresent = true;
279 break;
280 }
281 }
282 if (!runPresent) {
283 plotList.push_back(static_cast<int>(msrPlotList->at(i).fRuns[j]));
284 }
285 }
286 }
287
288 // read all the necessary runs (raw data)
289 std::unique_ptr<PRunDataHandler> dataHandler;
290 if (startupHandler)
291 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get(), startupHandler->GetDataPathList());
292 else
293 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get());
294
295 dataHandler->ReadData();
296
297 success = dataHandler->IsAllDataAvailable();
298 if (!success) {
299 errMsg << ">> musrview **ERROR** Couldn't read all data files, will quit ...\n";
300 std::cerr << errMsg.str();
301 if (show_errMsgBox)
302 musrview_error_msg(errMsg.str());
304 }
305
306 // generate the necessary histogramms for the view
307 std::unique_ptr<PRunListCollection> runListCollection;
308 if (result == PMUSR_SUCCESS) {
309 // feed all the necessary histogramms for the view
310 runListCollection = std::make_unique<PRunListCollection>(msrHandler.get(), dataHandler.get(), theoAtData);
311 for (unsigned int i=0; i<msrHandler->GetMsrRunList()->size(); i++) {
312 // if run is in plotList add it, otherwise go to the next
313 runPresent = false;
314 for (unsigned int j=0; j<plotList.size(); j++) {
315 if (static_cast<unsigned int>(plotList[j]) == i+1) {
316 runPresent = true;
317 break;
318 }
319 }
320 if (runPresent) {
321 success = runListCollection->Add(i, kView);
322 if (!success) {
323 errMsg << ">> musrview **ERROR** Couldn't handle run no " << i << " ";
324 errMsg << (*msrHandler->GetMsrRunList())[i].GetRunName()->Data() << "\n";
325 std::cerr << errMsg.str();
326 if (show_errMsgBox)
327 musrview_error_msg(errMsg.str());
328 result = PMUSR_MSR_RUN_ERROR;
329 break;
330 }
331 }
332 }
333 }
334
335 if (result == PMUSR_SUCCESS) {
336 // create the ROOT application needed for PMusrCanvas
337 // and pass it only essential arguments
338 std::vector<char*> args;
339 args.push_back(argv[0]); // program name
340 if (graphicsOutput || asciiOutput) {
341 args.push_back((char*)"-b"); // batch mode flag
342 }
343 int cc = args.size();
344 TApplication app("App", &cc, args.data());
345
346 std::vector<PMusrCanvas*> canvasVector;
347 PMusrCanvas *musrCanvas = nullptr;
348
349 bool ok = true;
350 for (unsigned int i=0; i<msrHandler->GetMsrPlotList()->size(); i++) {
351
352 if (startupHandler)
353 musrCanvas = new PMusrCanvas(i, msrHandler->GetMsrTitle()->Data(),
354 10+i*100, 10+i*100, 800, 600,
355 startupHandler->GetFourierDefaults(),
356 startupHandler->GetMarkerList(),
357 startupHandler->GetColorList(),
358 graphicsOutput||asciiOutput,
359 fourier, avg, theoAtData);
360 else
361 musrCanvas = new PMusrCanvas(i, msrHandler->GetMsrTitle()->Data(),
362 10+i*100, 10+i*100, 800, 600,
363 graphicsOutput||asciiOutput,
364 fourier, avg, theoAtData);
365
366 if (musrCanvas == nullptr) {
367 errMsg << ">> musrview **SEVERE ERROR** Couldn't invoke all necessary objects, will quit.\n";
368 std::cerr << errMsg.str();
369 if (show_errMsgBox)
370 musrview_error_msg(errMsg.str());
371 ok = false;
372 break;
373 }
374 if (!musrCanvas->IsValid()) {
375 errMsg << ">> musrview **SEVERE ERROR** Couldn't invoke all necessary objects, will quit.\n";
376 std::cerr << errMsg.str();
377 if (show_errMsgBox)
378 musrview_error_msg(errMsg.str());
379 ok = false;
380 delete musrCanvas;
381 break;
382 }
383
384 musrCanvas->SetTimeout(timeout);
385
386 // ugly but rootcling cannot handle the spirit-parser framework
387 musrCanvas->SetMsrHandler(msrHandler.get());
388 musrCanvas->SetRunListCollection(runListCollection.get());
389
390 musrCanvas->UpdateParamTheoryPad();
391 musrCanvas->UpdateDataTheoryPad();
392 musrCanvas->UpdateInfoPad();
393
394 if (!musrCanvas->IsValid()) { // something went wrong
395 ok = false;
396 break;
397 }
398
399 musrCanvas->Connect("Done(Int_t)", "TApplication", &app, "Terminate(Int_t)");
400
401 if (graphicsOutput) {
402 musrCanvas->SaveGraphicsAndQuit(fileName.c_str(), graphicsExtension.c_str());
403 }
404
405 if (asciiOutput) {
406 // generate export data file name
407 TString str(fileName.c_str());
408 str.Remove(str.Last('.'));
409 str += ".dat";
410 // save data in batch mode
411 musrCanvas->ExportData(str.Data());
412 musrCanvas->Done(0);
413 }
414
415 // keep musrCanvas objects
416 canvasVector.push_back(musrCanvas);
417 }
418
419 // check that everything is ok
420 if (ok)
421 app.Run(true); // true needed that Run will return after quit so that cleanup works
422
423 // clean up
424 char canvasName[32];
425 for (unsigned int i=0; i<canvasVector.size(); i++) {
426 // check if canvas is still there before calling the destructor **TO BE DONE**
427 snprintf(canvasName, sizeof(canvasName), "fMainCanvas%d", i);
428 if (gROOT->GetListOfCanvases()->FindObject(canvasName) != nullptr) {
429 canvasVector[i]->~PMusrCanvas();
430 }
431 }
432 canvasVector.clear();
433 }
434
435 // clean up
436 plotList.clear();
437
438 return result;
439}
#define PMUSR_DATA_FILE_READ_ERROR
Error reading data file (ROOT, NeXus, MUD, etc.)
Definition PMusr.h:76
#define PMUSR_MSR_RUN_ERROR
Error during run processing or fitting.
Definition PMusr.h:78
@ kView
Viewing mode - display data and theory without fitting.
Definition PMusr.h:430
#define PMUSR_SYNTAX_REQUEST
Syntax help was requested via command line.
Definition PMusr.h:60
#define PMUSR_SUCCESS
Successful operation completion.
Definition PMusr.h:58
#define PMUSR_MSR_FILE_NOT_FOUND
MSR file could not be found at specified path.
Definition PMusr.h:64
std::vector< PMsrPlotStructure > PMsrPlotList
Definition PMusr.h:1330
#define PMUSR_MSR_SYNTAX_ERROR
Syntax error detected in MSR file content.
Definition PMusr.h:68
std::vector< Int_t > PIntVector
Definition PMusr.h:381
#define PMUSR_WRONG_STARTUP_SYNTAX
Incorrect startup command syntax provided.
Definition PMusr.h:62
const char * startup_path_name
return status
int parseXmlFile(TSAXParser *, const char *)
Replacement function for TSAXParser::ParseFile().
GUI message box for displaying error messages and warnings.
Definition PMsgBox.h:63
ROOT-based canvas for interactive visualization of muSR data and fits.
virtual void Done(Int_t status=0)
ROOT signal emitted when canvas is closed or timeout occurs.
virtual void SetMsrHandler(PMsrHandler *msrHandler)
Sets the MSR file handler for accessing fit parameters and configuration.
virtual void SaveGraphicsAndQuit(const Char_t *fileName, const Char_t *graphicsFormat)
Saves canvas to graphics file and emits Done signal.
virtual void SetRunListCollection(PRunListCollection *runList)
Sets the run list collection for accessing fit data and results.
virtual Bool_t IsValid()
Returns true if canvas initialized successfully.
virtual void UpdateInfoPad()
Updates info/legend pad with run information.
virtual void SetTimeout(Int_t ival)
Sets timeout in seconds after which Done signal is emitted (0=no timeout)
virtual void ExportData(const Char_t *fileName)
Exports displayed data to ASCII file.
virtual void UpdateParamTheoryPad()
Updates parameter and theory display pads with current fit results.
virtual void UpdateDataTheoryPad()
Updates main data/theory plotting pad.
static int timeout
Definition musrfit.cpp:72
int main(int argc, char *argv[])
Definition musrview.cpp:121
void musrview_error_msg(std::string errMsg)
Definition musrview.cpp:94
void musrview_syntax()
Definition musrview.cpp:66