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