41 #include <sys/types.h> 49 #include <TSAXParser.h> 55 #include <TSystemFile.h> 59 #include "git-revision.h" 80 pid_t *pid = (pid_t*)(args);
84 std::cerr << std::endl <<
">> **FATAL ERROR** musrfit_timeout for task pid=" << *pid <<
" called! Will kill it!" << std::endl << std::endl;
88 return (
void*)
nullptr;
97 std::cout << std::endl <<
"usage: musrfit [<msr-file> [-k, --keep-mn2-ouput] [-c, --chisq-only] [-t, --title-from-data-file]";
98 std::cout << std::endl <<
" [-e, --estimateN0] [-p, --per-run-block-chisq]";
99 std::cout << std::endl <<
" [--dump <type>] [--timeout <timeout_tag>] |";
100 std::cout << std::endl <<
" -n, --no-of-cores-avail | -u, --use-no-of-threads <number> |";
101 std::cout << std::endl <<
" --nexus-support | --show-dynamic-path | --version | --help";
102 std::cout << std::endl <<
" <msr-file>: msr input file";
103 std::cout << std::endl <<
" 'musrfit <msr-file>' will execute musrfit";
104 std::cout << std::endl <<
" 'musrfit' or 'musrfit --help' will show this help";
105 std::cout << std::endl <<
" 'musrfit --version' will print the musrfit version";
106 std::cout << std::endl <<
" 'musrfit --nexus-support' will print if NeXus support is available.";
107 std::cout << std::endl <<
" 'musrfit --show-dynamic-path' will print the internal dynamic library search paths.";
108 std::cout << std::endl <<
" -k, --keep-mn2-output: will rename the files MINUIT2.OUTPUT and ";
109 std::cout << std::endl <<
" MINUIT2.root to <msr-file>-mn2.output and <msr-file>-mn2.root,";
110 std::cout << std::endl <<
" respectively,";
111 std::cout << std::endl <<
" e.g. <msr-file> = 147.msr -> 147-mn2.output, 147-mn2.root";
112 std::cout << std::endl <<
" -c, --chisq-only: instead of fitting the data, chisq is just calculated";
113 std::cout << std::endl <<
" once and the result is set to the stdout. This feature is useful";
114 std::cout << std::endl <<
" to adjust initial parameters.";
115 std::cout << std::endl <<
" -t, --title-from-data-file: will replace the <msr-file> run title by the";
116 std::cout << std::endl <<
" run title of the FIRST run of the <msr-file> run block, if a run title";
117 std::cout << std::endl <<
" is present in the data file.";
118 std::cout << std::endl <<
" -e, --estimateN0: estimate N0 for single histogram fits.";
119 std::cout << std::endl <<
" -p, --per-run-block-chisq: will write per run block chisq to the msr-file.";
120 std::cout << std::endl <<
" -n, --no-of-cores-avail: print out how many cores are available (only vaild for OpenMP)";
121 std::cout << std::endl <<
" -u, --use-no-of-threads <number>:";
122 std::cout << std::endl <<
" <number>: number of threads to be used (OpenMP). Needs to be <= max. number of cores.";
123 std::cout << std::endl <<
" If OpenMP is enable, the maximal number of cores is used, if it is not limited by this option.";
124 std::cout << std::endl <<
" --dump <type> is writing a data file with the fit data and the theory";
125 std::cout << std::endl <<
" <type> can be 'ascii', 'root'";
126 std::cout << std::endl <<
" --timeout <timeout_tag>: overwrites to predefined timeout of " <<
timeout <<
" (sec).";
127 std::cout << std::endl <<
" <timeout_tag> <= 0 means timeout facility is not enabled. <timeout_tag> = nn";
128 std::cout << std::endl <<
" will set the timeout to nn (sec).";
129 std::cout << std::endl;
130 std::cout << std::endl <<
" At the end of a fit, musrfit writes the fit results into an <mlog-file> and";
131 std::cout << std::endl <<
" swaps them, i.e. in the <msr-file> you will find the fit results and in the";
132 std::cout << std::endl <<
" <mlog-file> your initial guess values.";
133 std::cout << std::endl << std::endl;
149 Ssiz_t index = fln.Last(
'.');
150 fln.Insert(index, count);
155 f.open(fln.Data(), std::iostream::out);
157 std::cout << std::endl <<
"Couldn't open dump (" << fln.Data() <<
") file for writting, sorry ...";
158 std::cout << std::endl;
163 f <<
"% number of data values = " << data->
GetValue()->size() << std::endl;
164 f <<
"% time (us), value, error, theory" << std::endl;
166 for (
unsigned int i=0; i<data->
GetValue()->size(); i++) {
168 f << time <<
", " << data->
GetValue()->at(i) <<
", " << data->
GetError()->at(i) <<
", " << data->
GetTheory()->at(i) << std::endl;
186 TString fln(fileName);
187 fln.ReplaceAll(
".msr",
".dat");
197 for (
unsigned int i=0; i<size; i++) {
210 for (
unsigned int i=0; i<size; i++) {
223 for (
unsigned int i=0; i<size; i++) {
236 for (
unsigned int i=0; i<size; i++) {
249 for (
unsigned int i=0; i<size; i++) {
262 for (
unsigned int i=0; i<size; i++) {
286 TString title = fln.Copy();
287 snprintf(name,
sizeof(name),
"_%d", runCounter);
288 title.ReplaceAll(
".root", name);
290 snprintf(name,
sizeof(name),
"c%d", runCounter);
292 std::unique_ptr<TCanvas> c = std::make_unique<TCanvas>(name, title.Data(), 10, 10, 800, 600);
296 Double_t start = -diff/2.0;
298 std::unique_ptr<TH1F> hdata = std::make_unique<TH1F>(
"hdata",
"run data", data->
GetValue()->size(), start, end);
299 std::unique_ptr<TH1F> htheo = std::make_unique<TH1F>(
"htheo",
"run theory", data->
GetValue()->size(), start, end);
302 for (
unsigned int i=0; i<data->
GetValue()->size(); i++) {
303 hdata->SetBinContent(i+1, data->
GetValue()->at(i));
304 hdata->SetBinError(i+1, data->
GetError()->at(i));
305 htheo->SetBinContent(i+1, data->
GetTheory()->at(i));
308 hdata->SetMarkerStyle(20);
309 hdata->Draw(
"*H HIST E1");
311 htheo->SetLineColor(2);
312 htheo->SetLineWidth(3);
313 htheo->Draw(
"C SAME");
315 f.WriteTObject(c.get());
329 TString fln(fileName);
330 fln.ReplaceAll(
".msr",
".root");
332 TFile f(fln.Data(),
"recreate");
342 for (
unsigned int i=0; i<size; i++) {
355 for (
unsigned int i=0; i<size; i++) {
368 for (
unsigned int i=0; i<size; i++) {
381 for (
unsigned int i=0; i<size; i++) {
394 for (
unsigned int i=0; i<size; i++) {
407 for (
unsigned int i=0; i<size; i++) {
437 int main(
int argc,
char *argv[])
439 bool show_syntax =
false;
441 bool keep_mn2_output =
false;
442 bool chisq_only =
false;
443 bool title_from_data_file =
false;
444 bool timeout_enabled =
true;
448 int number_of_cores=1;
451 number_of_cores = omp_get_num_procs();
464 const char *dsp = gSystem->GetDynamicPath();
465 if (strstr(dsp,
"/usr/local/lib") ==
nullptr)
466 gSystem->AddDynamicPath(
"/usr/local/lib");
469 if (!strcmp(argv[1],
"--version")) {
471 #ifdef HAVE_GIT_REV_H 472 std::cout << std::endl <<
"musrfit version: " << PACKAGE_VERSION <<
", git-branch: " << GIT_BRANCH <<
", git-rev: " << GIT_CURRENT_SHA1 <<
" (" << BUILD_TYPE <<
"), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
474 std::cout << std::endl <<
"musrfit version: " << PACKAGE_VERSION <<
" (" << BUILD_TYPE <<
"), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
477 #ifdef HAVE_GIT_REV_H 478 std::cout << std::endl <<
"musrfit git-branch: " << GIT_BRANCH <<
", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
480 std::cout << std::endl <<
"musrfit version: unknown" << std::endl << std::endl;
484 }
else if (!strcmp(argv[1],
"--nexus-support")) {
485 #ifdef PNEXUS_ENABLED 486 std::cout << std::endl <<
">> musrfit: NeXus support enabled." << std::endl << std::endl;
488 std::cout << std::endl <<
"musrfit: NeXus support NOT enabled." << std::endl << std::endl;
491 }
else if (!strcmp(argv[1],
"--show-dynamic-path")) {
492 std::cout << std::endl <<
"musrfit: internal dynamic search paths for shared libraries/root dictionaries:";
493 std::cout << std::endl <<
" '" << gSystem->GetDynamicPath() <<
"'" << std::endl << std::endl;
495 }
else if (!strcmp(argv[1],
"--help")) {
505 strcpy(filename,
"");
506 for (
int i=1; i<argc; i++) {
507 if (strstr(argv[i],
".msr")) {
508 strncpy(filename, argv[i],
sizeof(filename));
509 }
else if (!strcmp(argv[i],
"-k") || !strcmp(argv[i],
"--keep-mn2-output")) {
510 keep_mn2_output =
true;
511 }
else if (!strcmp(argv[i],
"-c") || !strcmp(argv[i],
"--chisq-only")) {
513 }
else if (!strcmp(argv[i],
"-t") || !strcmp(argv[i],
"--title-from-data-file")) {
514 title_from_data_file =
true;
515 }
else if (!strcmp(argv[i],
"--dump")) {
517 dump = TString(argv[i+1]);
520 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump without <type>" << std::endl;
524 }
else if (!strcmp(argv[i],
"-e") || !strcmp(argv[i],
"--estimateN0")) {
526 }
else if (!strcmp(argv[i],
"-p") || !strcmp(argv[i],
"--per-run-block-chisq")) {
528 }
else if (!strcmp(argv[i],
"-n") || !strcmp(argv[i],
"--no-of-cores-avail")) {
530 std::cout << std::endl;
531 std::cout <<
"musrfit: maxmimal number of cores for OpenMP available: " << omp_get_num_procs() << std::endl;
532 std::cout << std::endl;
534 std::cout << std::endl;
535 std::cout <<
">> musrfit: this option is only vaild if OpenMP is present. This seems not to be the case here. Sorry!" << std::endl;
536 std::cout << std::endl;
539 }
else if (!strcmp(argv[i],
"-u") || !strcmp(argv[i],
"--use-no-of-threads")) {
541 TString str(argv[i+1]);
543 int ival = str.Atoi();
545 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads with <number> <= 0" << std::endl;
546 std::cerr <<
" This doesn't make any sense." << std::endl;
549 }
else if (ival > number_of_cores) {
551 std::cerr << std::endl <<
">> musrfit: **WARNING** found option --use-no-of-threads with <number>=" << ival <<
" > max available cores=" << number_of_cores <<
"." << std::endl;
552 std::cerr <<
" Will set <number> to max available cores." << std::endl;
554 std::cerr << std::endl <<
">> musrfit: **WARNING** option --use-no-of-threads can only be used if OpenMP is available." << std::endl;
555 std::cerr <<
" Here it is not the case, and hence this option will be ignored." << std::endl;
558 number_of_cores = ival;
561 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads where <number> it not a number: '" << argv[i+1] <<
"'" << std::endl;
567 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads without <number>" << std::endl;
571 }
else if (!strcmp(argv[i],
"--timeout")) {
573 TString str(argv[i+1]);
577 timeout_enabled =
false;
578 std::cout << std::endl <<
">> musrfit: timeout disabled." << std::endl;
581 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout with unsupported <timeout_tag> = " << argv[i+1] << std::endl;
587 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout without <timeout_tag>" << std::endl;
598 if (strlen(filename) == 0) {
600 std::cout << std::endl <<
">> musrfit **ERROR** no msr-file present!" << std::endl;
609 if (!dump.IsNull()) {
611 if (!dump.Contains(
"ascii") && !dump.Contains(
"root")) {
612 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump with unsupported <type> = " << dump << std::endl;
620 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
621 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>();
622 if (!startupHandler->StartupFileFound()) {
623 std::cerr << std::endl <<
">> musrfit **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
624 std::cerr << std::endl;
627 saxParser->ConnectToHandler(
"PStartupHandler", startupHandler.get());
634 std::cerr << std::endl <<
">> musrfit **WARNING** Reading/parsing musrfit_startup.xml failed.";
635 std::cerr << std::endl;
641 omp_set_num_threads(number_of_cores);
645 std::unique_ptr<PMsrHandler> msrHandler;
647 msrHandler = std::make_unique<PMsrHandler>(filename, &startup_options);
649 msrHandler = std::make_unique<PMsrHandler>(filename);
650 status = msrHandler->ReadMsrFile();
654 std::cout << std::endl <<
">> musrfit **ERROR** couldn't find " << filename << std::endl << std::endl;
657 std::cout << std::endl <<
">> musrfit **SYNTAX ERROR** in file " << filename <<
", full stop here." << std::endl << std::endl;
660 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to read the msr-file" << std::endl << std::endl;
667 std::unique_ptr<PRunDataHandler> dataHandler;
669 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get(), startupHandler->GetDataPathList());
671 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get());
673 dataHandler->ReadData();
675 bool success = dataHandler->IsAllDataAvailable();
677 std::cout << std::endl <<
">> musrfit **ERROR** Couldn't read all data files, will quit ..." << std::endl;
681 if (title_from_data_file && success) {
683 PRawRunData *rrd = dataHandler->GetRunData(*(rl->at(0).GetRunName()));
689 std::unique_ptr<PRunListCollection> runListCollection;
692 runListCollection = std::make_unique<PRunListCollection>(msrHandler.get(), dataHandler.get());
693 for (
unsigned int i=0; i < msrHandler->GetMsrRunList()->size(); i++) {
694 success = runListCollection->Add(i,
kFit);
696 std::cout << std::endl <<
">> musrfit **ERROR** Couldn't handle run no " << i+1 <<
": ";
697 std::cout << (*msrHandler->GetMsrRunList())[i].GetRunName()->Data();
704 std::unique_ptr<TThread> th;
705 if (timeout_enabled) {
706 pid_t musrfit_pid = getpid();
714 std::unique_ptr<PFitter> fitter;
716 fitter = std::make_unique<PFitter>(msrHandler.get(), runListCollection.get(), chisq_only);
717 if (fitter->IsValid()) {
719 if (!fitter->IsScanOnly())
720 msrHandler->SetMsrStatisticConverged(fitter->HasConverged());
725 if (success && !chisq_only) {
726 if (!fitter->IsScanOnly()) {
727 status = msrHandler->WriteMsrLogFile();
731 std::cout << std::endl <<
">> musrfit **ERROR** couldn't write mlog-file" << std::endl << std::endl;
734 std::cout << std::endl <<
">> musrfit **ERROR** couldn't generate mlog-file name" << std::endl << std::endl;
737 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to write the mlog-file" << std::endl << std::endl;
745 if (success && !dump.IsNull()) {
746 std::cout << std::endl <<
"will write dump file ..." << std::endl;
748 if (dump.Contains(
"ascii"))
750 else if (dump.Contains(
"root"))
753 std::cout << std::endl <<
"do not know format " << dump.Data() <<
", sorry :-| " << std::endl;
758 if (keep_mn2_output && !chisq_only && !fitter->IsScanOnly()) {
760 TString fln = TString(filename);
762 strcpy(ext,
"-mn2.output");
763 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
764 gSystem->CopyFile(
"MINUIT2.OUTPUT", fln.Data(), kTRUE);
767 fln = TString(filename);
768 strcpy(ext,
"-mn2.root");
769 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
770 gSystem->CopyFile(
"MINUIT2.root", fln.Data(), kTRUE);
775 if (!chisq_only && !fitter->IsScanOnly()) {
777 std::cout << std::endl <<
">> swapping msr-, mlog-file ..." << std::endl;
779 gSystem->CopyFile(filename,
"__temp.msr", kTRUE);
781 TString fln = TString(filename);
783 strcpy(ext,
".mlog");
784 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
785 gSystem->CopyFile(fln.Data(), filename, kTRUE);
787 gSystem->CopyFile(
"__temp.msr", fln.Data(), kTRUE);
789 TSystemFile tmp(
"__temp.msr",
"./");
794 std::cout << std::endl <<
"done ..." << std::endl;
void musrfit_write_root(TFile &f, TString fln, PRunData *data, int runCounter)
virtual PRunData * GetAsymmetry(UInt_t index, EDataSwitch tag=kIndex)
virtual UInt_t GetNoOfAsymmetryRRF() const
returns the number of asymmetry RRF data sets present in the msr-file
virtual const PDoubleVector * GetError()
void musrfit_dump_root(char *fileName, PRunListCollection *runList)
Bool_t writeExpectedChisq
if set to true, expected chisq and chisq per block will be written
std::vector< PMsrRunBlock > PMsrRunList
Bool_t estimateN0
if set to true, for single histogram fits N0 will be estimated
virtual UInt_t GetNoOfSingleHistoRRF() const
returns the number of single histogram RRF data sets present in the msr-file
virtual const PDoubleVector * GetTheory()
virtual UInt_t GetNoOfMuMinus() const
returns the number of mu minus data sets present in the msr-file
int parseXmlFile(TSAXParser *, const char *)
#define PMUSR_MSR_FILE_NOT_FOUND
virtual PRunData * GetMuMinus(UInt_t index, EDataSwitch tag=kIndex)
virtual PRunData * GetAsymmetryRRF(UInt_t index, EDataSwitch tag=kIndex)
void musrfit_dump_ascii(char *fileName, PRunListCollection *runList)
virtual PRunData * GetSingleHisto(UInt_t index, EDataSwitch tag=kIndex)
void musrfit_write_ascii(TString fln, PRunData *data, int runCounter)
int main(int argc, char *argv[])
const char * startup_path_name
virtual const PDoubleVector * GetValue()
virtual PRunData * GetNonMusr(UInt_t index, EDataSwitch tag=kIndex)
#define PMUSR_MSR_SYNTAX_ERROR
#define PMUSR_TOKENIZE_ERROR
virtual PRunData * GetSingleHistoRRF(UInt_t index, EDataSwitch tag=kIndex)
#define PMUSR_WRONG_STARTUP_SYNTAX
#define PMUSR_MSR_LOG_FILE_WRITE_ERROR
virtual UInt_t GetNoOfNonMusr() const
returns the number of non-muSR data sets present in the msr-file
virtual Double_t GetDataTimeStart()
virtual const TString * GetRunTitle()
void * musrfit_timeout(void *args)
virtual Double_t GetDataTimeStep()
virtual UInt_t GetNoOfSingleHisto() const
returns the number of single histogram data sets present in the msr-file
virtual UInt_t GetNoOfAsymmetry() const
returns the number of asymmetry data sets present in the msr-file