musrfit  1.9.2
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-2023 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 
41 #include <TApplication.h>
42 #include <TSAXParser.h>
43 #include <TROOT.h>
44 
45 #ifdef HAVE_GIT_REV_H
46 #include "git-revision.h"
47 #endif
48 
49 #include "PMusr.h"
50 #include "PStartupHandler.h"
51 #include "PMsrHandler.h"
52 #include "PRunDataHandler.h"
53 #include "PRunListCollection.h"
54 #include "PMusrCanvas.h"
55 
56 
57 //--------------------------------------------------------------------------
62 {
63  std::cout << std::endl << "usage: musrview <msr-file> [Options]";
64  std::cout << std::endl << " <msr-file>: msr/mlog input file";
65  std::cout << std::endl << " Options:";
66  std::cout << std::endl << " --help : display this help and exit.";
67  std::cout << std::endl << " --version : output version information and exit.";
68  std::cout << std::endl << " --show-dynamic-path : dumps the dynamic search paths and exit.";
69  std::cout << std::endl << " -f, --fourier: will directly present the Fourier transform of the <msr-file>.";
70  std::cout << std::endl << " -a, --avg: will directly present the averaged data/Fourier of the <msr-file>.";
71  std::cout << std::endl << " -1, --one_to_one: calculate theory points only at data points.";
72  std::cout << std::endl << " --<graphic-format-extension>: ";
73  std::cout << std::endl << " will produce a graphics-output-file without starting a root session.";
74  std::cout << std::endl << " the name is based on the <msr-file>, e.g. 3310.msr -> 3310_0.png";
75  std::cout << std::endl << " supported graphic-format-extension:";
76  std::cout << std::endl << " eps, pdf, gif, jpg, png, svg, xpm, root";
77  std::cout << std::endl << " example: musrview 3310.msr --png, will produce a files 3310_X.png";
78  std::cout << std::endl << " where 'X' stands for the plot number (starting form 0)";
79  std::cout << std::endl << " --ascii: ";
80  std::cout << std::endl << " will produce an ascii dump of the data and fit as plotted.";
81  std::cout << std::endl << " --timeout <timeout>: <timeout> given in seconds after which musrview terminates.";
82  std::cout << std::endl << " If <timeout> <= 0, no timeout will take place. Default <timeout> is 0.";
83  std::cout << std::endl << std::endl;
84 }
85 
86 //--------------------------------------------------------------------------
104 int main(int argc, char *argv[])
105 {
106  int result = PMUSR_SUCCESS;
107  bool show_syntax = false;
108  int status;
109  bool success = true;
110  char fileName[128];
111  bool fourier = false;
112  bool avg = false;
113  bool theoAtData = false; // theory points only at data points
114  bool graphicsOutput = false;
115  bool asciiOutput = false;
116  char graphicsExtension[128];
117  int timeout = 0;
118 
119  memset(fileName, '\0', sizeof(fileName));
120 
121  // add default shared library path /usr/local/lib if not already persent
122  const char *dsp = gSystem->GetDynamicPath();
123  if (strstr(dsp, "/usr/local/lib") == nullptr)
124  gSystem->AddDynamicPath("/usr/local/lib");
125 
126  // check input arguments
127  if (argc == 1) {
128  musrview_syntax();
129  return PMUSR_SYNTAX_REQUEST;
130  }
131  for (int i=1; i<argc; i++) {
132  if (strstr(argv[i], ".msr") || strstr(argv[i], ".mlog")) {
133  if (strlen(fileName) == 0) {
134  strcpy(fileName, argv[i]);
135  } else {
136  std::cerr << std::endl << "**ERROR** only one file name allowed." << std::endl;
137  show_syntax = true;
138  break;
139  }
140  } else if (!strcmp(argv[i], "--version")) {
141 #ifdef HAVE_CONFIG_H
142 #ifdef HAVE_GIT_REV_H
143  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;
144 #else
145  std::cout << std::endl << "musrview version: " << PACKAGE_VERSION << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
146 #endif
147 #else
148 #ifdef HAVE_GIT_REV_H
149  std::cout << std::endl << "musrview git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
150 #else
151  std::cout << std::endl << "musrview version: unknown." << std::endl << std::endl;
152 #endif
153 #endif
154  return PMUSR_SUCCESS;
155  } else if (!strcmp(argv[i], "--show-dynamic-path")) {
156  std::cout << std::endl << "musrview: internal dynamic search paths for shared libraries/root dictionaries:";
157  std::cout << std::endl << " '" << gSystem->GetDynamicPath() << "'" << std::endl << std::endl;
158  return PMUSR_SUCCESS;
159  } else if (!strcmp(argv[i], "--help")) {
160  show_syntax = true;
161  break;
162  } else if (!strcmp(argv[i], "-f") || !strcmp(argv[i], "--fourier")) {
163  fourier = true;
164  } else if (!strcmp(argv[i], "-a") || !strcmp(argv[i], "--avg")) {
165  avg = true;
166  } else if (!strcmp(argv[i], "-1") || !strcmp(argv[i], "--one_to_one")) {
167  theoAtData = true;
168  } else if (!strcmp(argv[i], "--eps") || !strcmp(argv[i], "--pdf") || !strcmp(argv[i], "--gif") ||
169  !strcmp(argv[i], "--jpg") || !strcmp(argv[i], "--png") || !strcmp(argv[i], "--svg") ||
170  !strcmp(argv[i], "--xpm") || !strcmp(argv[i], "--root")) {
171 
172  graphicsOutput = true;
173  strcpy(graphicsExtension, argv[i]+2);
174  } else if (!strcmp(argv[i], "--ascii")) {
175  asciiOutput = true;
176  } else if (!strcmp(argv[i], "--timeout")) {
177  if (i+1 < argc) {
178  TString str(argv[i+1]);
179  if (str.IsFloat()) {
180  timeout = str.Atoi();
181  } else {
182  show_syntax = true;
183  break;
184  }
185  i++;
186  } else {
187  show_syntax = true;
188  break;
189  }
190  } else {
191  show_syntax = true;
192  break;
193  }
194  }
195 
196  if (show_syntax) {
197  musrview_syntax();
199  }
200 
201  // read startup file
202  char startup_path_name[128];
203  std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
204  std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>();
205  if (!startupHandler->StartupFileFound()) {
206  std::cerr << std::endl << ">> musrview **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
207  std::cerr << std::endl;
208  } else {
209  strcpy(startup_path_name, startupHandler->GetStartupFilePath().Data());
210  saxParser->ConnectToHandler("PStartupHandler", startupHandler.get());
211  //status = saxParser->ParseFile(startup_path_name);
212  // parsing the file as above seems to lead to problems in certain environments;
213  // use the parseXmlFile function instead (see PStartupHandler.cpp for the definition)
214  status = parseXmlFile(saxParser.get(), startup_path_name);
215  // check for parse errors
216  if (status) { // error
217  std::cerr << std::endl << ">> musrview **WARNING** Reading/parsing musrfit_startup.xml failed.";
218  std::cerr << std::endl << ">> Any graph will appear with random symbols and colors!";
219  std::cerr << std::endl;
220  } else {
221  startupHandler->CheckLists();
222  }
223  }
224 
225  // read msr-file
226  std::unique_ptr<PMsrHandler> msrHandler = std::make_unique<PMsrHandler>(fileName);
227  status = msrHandler->ReadMsrFile();
228  if (status != PMUSR_SUCCESS) {
229  switch (status) {
231  std::cerr << std::endl << ">> musrview **ERROR** couldn't find '" << fileName << "'" << std::endl << std::endl;
232  break;
234  std::cerr << std::endl << ">> musrview **SYNTAX ERROR** in file " << fileName << ", full stop here." << std::endl << std::endl;
235  break;
236  default:
237  std::cerr << std::endl << ">> musrview **UNKNOWN ERROR** when trying to read the msr-file" << std::endl << std::endl;
238  break;
239  }
240  return status;
241  }
242  // make a plot list vector
243  PMsrPlotList *msrPlotList = msrHandler->GetMsrPlotList();
244  PIntVector plotList;
245  bool runPresent;
246  for (unsigned int i=0; i<msrPlotList->size(); i++) {
247  for (unsigned int j=0; j<msrPlotList->at(i).fRuns.size(); j++) {
248  // check that run is not already in the plotList
249  runPresent = false;
250  for (unsigned int k=0; k<plotList.size(); k++) {
251  if (msrPlotList->at(i).fRuns[j] == static_cast<int>(plotList[k])) {
252  runPresent = true;
253  break;
254  }
255  }
256  if (!runPresent) {
257  plotList.push_back(static_cast<int>(msrPlotList->at(i).fRuns[j]));
258  }
259  }
260  }
261 
262  // read all the necessary runs (raw data)
263  std::unique_ptr<PRunDataHandler> dataHandler;
264  if (startupHandler)
265  dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get(), startupHandler->GetDataPathList());
266  else
267  dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get());
268 
269  dataHandler->ReadData();
270 
271  success = dataHandler->IsAllDataAvailable();
272  if (!success) {
273  std::cerr << std::endl << ">> musrview **ERROR** Couldn't read all data files, will quit ..." << std::endl;
275  }
276 
277  // generate the necessary histogramms for the view
278  std::unique_ptr<PRunListCollection> runListCollection;
279  if (result == PMUSR_SUCCESS) {
280  // feed all the necessary histogramms for the view
281  runListCollection = std::make_unique<PRunListCollection>(msrHandler.get(), dataHandler.get(), theoAtData);
282  for (unsigned int i=0; i<msrHandler->GetMsrRunList()->size(); i++) {
283  // if run is in plotList add it, otherwise go to the next
284  runPresent = false;
285  for (unsigned int j=0; j<plotList.size(); j++) {
286  if (static_cast<unsigned int>(plotList[j]) == i+1) {
287  runPresent = true;
288  break;
289  }
290  }
291  if (runPresent) {
292  success = runListCollection->Add(i, kView);
293  if (!success) {
294  std::cerr << std::endl << ">> musrview **ERROR** Couldn't handle run no " << i << " ";
295  std::cerr << (*msrHandler->GetMsrRunList())[i].GetRunName()->Data();
296  result = PMUSR_MSR_RUN_ERROR;
297  break;
298  }
299  }
300  }
301  }
302 
303  if (result == PMUSR_SUCCESS) {
304  // generate Root application needed for PMusrCanvas
305  if (graphicsOutput || asciiOutput) {
306  argv[argc] = (char*)malloc(16*sizeof(char));
307  strcpy(argv[argc], "-b");
308  argc++;
309  }
310  TApplication app("App", &argc, argv);
311 
312  std::vector<PMusrCanvas*> canvasVector;
313  PMusrCanvas *musrCanvas;
314 
315  bool ok = true;
316  for (unsigned int i=0; i<msrHandler->GetMsrPlotList()->size(); i++) {
317 
318  if (startupHandler)
319  musrCanvas = new PMusrCanvas(i, msrHandler->GetMsrTitle()->Data(),
320  10+i*100, 10+i*100, 800, 600,
321  startupHandler->GetFourierDefaults(),
322  startupHandler->GetMarkerList(),
323  startupHandler->GetColorList(),
324  graphicsOutput||asciiOutput,
325  fourier, avg, theoAtData);
326  else
327  musrCanvas = new PMusrCanvas(i, msrHandler->GetMsrTitle()->Data(),
328  10+i*100, 10+i*100, 800, 600,
329  graphicsOutput||asciiOutput,
330  fourier, avg, theoAtData);
331 
332  if (!musrCanvas->IsValid()) {
333  std::cerr << std::endl << ">> musrview **SEVERE ERROR** Couldn't invoke all necessary objects, will quit.";
334  std::cerr << std::endl;
335  ok = false;
336  break;
337  }
338 
339  musrCanvas->SetTimeout(timeout);
340 
341  // ugly but rootcling cannot handle the spirit-parser framework
342  musrCanvas->SetMsrHandler(msrHandler.get());
343  musrCanvas->SetRunListCollection(runListCollection.get());
344 
345  musrCanvas->UpdateParamTheoryPad();
346  musrCanvas->UpdateDataTheoryPad();
347  musrCanvas->UpdateInfoPad();
348 
349  if (!musrCanvas->IsValid()) { // something went wrong
350  ok = false;
351  break;
352  }
353 
354  musrCanvas->Connect("Done(Int_t)", "TApplication", &app, "Terminate(Int_t)");
355 
356  if (graphicsOutput) {
357  musrCanvas->SaveGraphicsAndQuit(fileName, graphicsExtension);
358  }
359 
360  if (asciiOutput) {
361  // generate export data file name
362  TString str(fileName);
363  str.Remove(str.Last('.'));
364  str += ".dat";
365  // save data in batch mode
366  musrCanvas->ExportData(str.Data());
367  musrCanvas->Done(0);
368  }
369 
370  // keep musrCanvas objects
371  canvasVector.push_back(musrCanvas);
372  }
373 
374  // check that everything is ok
375  if (ok)
376  app.Run(true); // true needed that Run will return after quit so that cleanup works
377 
378  // clean up
379  char canvasName[32];
380  for (unsigned int i=0; i<canvasVector.size(); i++) {
381  // check if canvas is still there before calling the destructor **TO BE DONE**
382  snprintf(canvasName, sizeof(canvasName), "fMainCanvas%d", i);
383  if (gROOT->GetListOfCanvases()->FindObject(canvasName) != nullptr) {
384  canvasVector[i]->~PMusrCanvas();
385  }
386  }
387  canvasVector.clear();
388  }
389 
390  // clean up
391  plotList.clear();
392 
393  return result;
394 }
Definition: PMusr.h:220
virtual void ExportData(const Char_t *fileName)
virtual void UpdateInfoPad()
#define PMUSR_MSR_RUN_ERROR
Definition: PMusr.h:54
virtual void UpdateParamTheoryPad()
int main(int argc, char *argv[])
Definition: musrview.cpp:104
int parseXmlFile(TSAXParser *, const char *)
#define PMUSR_MSR_FILE_NOT_FOUND
Definition: PMusr.h:47
std::vector< PMsrPlotStructure > PMsrPlotList
Definition: PMusr.h:802
std::vector< Int_t > PIntVector
Definition: PMusr.h:178
#define PMUSR_SYNTAX_REQUEST
Definition: PMusr.h:45
virtual Bool_t IsValid()
Definition: PMusrCanvas.h:217
#define PMUSR_DATA_FILE_READ_ERROR
Definition: PMusr.h:53
const char * startup_path_name
static int timeout
Definition: musrfit.cpp:71
void musrview_syntax()
Definition: musrview.cpp:61
#define PMUSR_MSR_SYNTAX_ERROR
Definition: PMusr.h:49
virtual void SetMsrHandler(PMsrHandler *msrHandler)
virtual void SetRunListCollection(PRunListCollection *runList)
Definition: PMusrCanvas.h:221
#define PMUSR_WRONG_STARTUP_SYNTAX
Definition: PMusr.h:46
virtual void Done(Int_t status=0)
#define PMUSR_SUCCESS
Definition: PMusr.h:44
virtual void UpdateDataTheoryPad()
return status
virtual void SetTimeout(Int_t ival)
virtual void SaveGraphicsAndQuit(Char_t *fileName, Char_t *graphicsFormat)