98 std::cout << std::endl <<
"usage: musrfit [<msr-file> [-k, --keep-mn2-ouput] [-c, --chisq-only] [-t, --title-from-data-file]";
99 std::cout << std::endl <<
" [-e, --estimateN0] [-p, --per-run-block-chisq]";
100 std::cout << std::endl <<
" [--dump <type>] [--timeout <timeout_tag>] |";
101 std::cout << std::endl <<
" -n, --no-of-cores-avail | -u, --use-no-of-threads <number> |";
102 std::cout << std::endl <<
" --nexus-support | --show-dynamic-path | --version | --help";
103 std::cout << std::endl <<
" <msr-file>: msr input file";
104 std::cout << std::endl <<
" 'musrfit <msr-file>' will execute musrfit";
105 std::cout << std::endl <<
" 'musrfit' or 'musrfit --help' will show this help";
106 std::cout << std::endl <<
" 'musrfit --version' will print the musrfit version";
107 std::cout << std::endl <<
" 'musrfit --nexus-support' will print if NeXus support is available.";
108 std::cout << std::endl <<
" 'musrfit --show-dynamic-path' will print the internal dynamic library search paths.";
109 std::cout << std::endl <<
" -k, --keep-mn2-output: will rename the files MINUIT2.OUTPUT and ";
110 std::cout << std::endl <<
" MINUIT2.root to <msr-file>-mn2.output and <msr-file>-mn2.root,";
111 std::cout << std::endl <<
" respectively,";
112 std::cout << std::endl <<
" e.g. <msr-file> = 147.msr -> 147-mn2.output, 147-mn2.root";
113 std::cout << std::endl <<
" -c, --chisq-only: instead of fitting the data, chisq is just calculated";
114 std::cout << std::endl <<
" once and the result is set to the stdout. This feature is useful";
115 std::cout << std::endl <<
" to adjust initial parameters.";
116 std::cout << std::endl <<
" -t, --title-from-data-file: will replace the <msr-file> run title by the";
117 std::cout << std::endl <<
" run title of the FIRST run of the <msr-file> run block, if a run title";
118 std::cout << std::endl <<
" is present in the data file.";
119 std::cout << std::endl <<
" -e, --estimateN0: estimate N0 for single histogram fits.";
120 std::cout << std::endl <<
" -p, --per-run-block-chisq: will write per run block chisq to the msr-file.";
121 std::cout << std::endl <<
" -n, --no-of-cores-avail: print out how many cores are available (only vaild for OpenMP)";
122 std::cout << std::endl <<
" -u, --use-no-of-threads <number>:";
123 std::cout << std::endl <<
" <number>: number of threads to be used (OpenMP). Needs to be <= max. number of cores.";
124 std::cout << std::endl <<
" If OpenMP is enable, the maximal number of cores is used, if it is not limited by this option.";
125 std::cout << std::endl <<
" -r, --reset: reset startup musrfit_startup.xml, i.e. rewrite a default, and quit.";
126 std::cout << std::endl <<
" The order of which musrfit_startup.xml is reset is:";
127 std::cout << std::endl <<
" (i) if present in the current dir.";
128 std::cout << std::endl <<
" (ii) if present under $HOME/.musrfit/";
129 std::cout << std::endl <<
" (iii) if present under $MUSRFITPATH/";
130 std::cout << std::endl <<
" (iv) if present under $ROOTSYS/";
131 std::cout << std::endl <<
" -y, --yaml: write fit results (MINUIT2.OUTPUT) into a yaml-file. Output <msr-file>.yaml";
132 std::cout << std::endl <<
" --dump <type> is writing a data file with the fit data and the theory";
133 std::cout << std::endl <<
" <type> can be 'ascii', 'root'";
134 std::cout << std::endl <<
" --timeout <timeout_tag>: overwrites to predefined timeout of " <<
timeout <<
" (sec).";
135 std::cout << std::endl <<
" <timeout_tag> <= 0 means timeout facility is not enabled. <timeout_tag> = nn";
136 std::cout << std::endl <<
" will set the timeout to nn (sec).";
137 std::cout << std::endl;
138 std::cout << std::endl <<
" At the end of a fit, musrfit writes the fit results into an <mlog-file> and";
139 std::cout << std::endl <<
" swaps them, i.e. in the <msr-file> you will find the fit results and in the";
140 std::cout << std::endl <<
" <mlog-file> your initial guess values.";
141 std::cout << std::endl << std::endl;
445int main(
int argc,
char *argv[])
448 bool show_syntax =
false;
457 if (!strcmp(argv[1],
"--version")) {
460 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;
462 std::cout << std::endl <<
"musrfit version: " << PACKAGE_VERSION <<
" (" << BUILD_TYPE <<
"), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
466 std::cout << std::endl <<
"musrfit git-branch: " << GIT_BRANCH <<
", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
468 std::cout << std::endl <<
"musrfit version: unknown" << std::endl << std::endl;
472 }
else if (!strcmp(argv[1],
"--nexus-support")) {
474 std::cout << std::endl <<
">> musrfit: NeXus support enabled. ";
475 std::cout <<
" HDF5 ready. ";
477 std::cout <<
" HDF4 ready." << std::endl << std::endl;
479 std::cout <<
" HDF4 not ready." << std::endl << std::endl;
482 std::cout << std::endl <<
"musrfit: NeXus support NOT enabled." << std::endl << std::endl;
485 }
else if (!strcmp(argv[1],
"--help")) {
496 bool keep_mn2_output =
false;
497 bool chisq_only =
false;
498 bool yaml_out =
false;
499 bool title_from_data_file =
false;
500 bool timeout_enabled =
true;
501 bool reset_startup_file =
false;
505 int number_of_cores=1;
508 number_of_cores = omp_get_num_procs();
512 std::string filename{};
515 const char *dsp = gSystem->GetDynamicPath();
516 if (strstr(dsp,
"/usr/local/lib") ==
nullptr)
517 gSystem->AddDynamicPath(
"/usr/local/lib");
521 if (!strcmp(argv[1],
"--show-dynamic-path")) {
522 std::cout << std::endl <<
"musrfit: internal dynamic search paths for shared libraries/root dictionaries:";
523 std::cout << std::endl <<
" '" << gSystem->GetDynamicPath() <<
"'" << std::endl << std::endl;
528 for (
int i=1; i<argc; i++) {
529 if (strstr(argv[i],
".msr")) {
531 }
else if (!strcmp(argv[i],
"-k") || !strcmp(argv[i],
"--keep-mn2-output")) {
532 keep_mn2_output =
true;
533 }
else if (!strcmp(argv[i],
"-c") || !strcmp(argv[i],
"--chisq-only")) {
535 }
else if (!strcmp(argv[i],
"-t") || !strcmp(argv[i],
"--title-from-data-file")) {
536 title_from_data_file =
true;
537 }
else if (!strcmp(argv[i],
"--dump")) {
539 dump = TString(argv[i+1]);
542 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump without <type>" << std::endl;
546 }
else if (!strcmp(argv[i],
"-e") || !strcmp(argv[i],
"--estimateN0")) {
548 }
else if (!strcmp(argv[i],
"-p") || !strcmp(argv[i],
"--per-run-block-chisq")) {
550 }
else if (!strcmp(argv[i],
"-y") || !strcmp(argv[i],
"--yaml")) {
552 }
else if (!strcmp(argv[i],
"-n") || !strcmp(argv[i],
"--no-of-cores-avail")) {
554 std::cout << std::endl;
555 std::cout <<
"musrfit: maxmimal number of cores for OpenMP available: " << omp_get_num_procs() << std::endl;
556 std::cout << std::endl;
558 std::cout << std::endl;
559 std::cout <<
">> musrfit: this option is only vaild if OpenMP is present. This seems not to be the case here. Sorry!" << std::endl;
560 std::cout << std::endl;
563 }
else if (!strcmp(argv[i],
"-u") || !strcmp(argv[i],
"--use-no-of-threads")) {
565 TString str(argv[i+1]);
567 int ival = str.Atoi();
569 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads with <number> <= 0" << std::endl;
570 std::cerr <<
" This doesn't make any sense." << std::endl;
573 }
else if (ival > number_of_cores) {
575 std::cerr << std::endl <<
">> musrfit: **WARNING** found option --use-no-of-threads with <number>=" << ival <<
" > max available cores=" << number_of_cores <<
"." << std::endl;
576 std::cerr <<
" Will set <number> to max available cores." << std::endl;
578 std::cerr << std::endl <<
">> musrfit: **WARNING** option --use-no-of-threads can only be used if OpenMP is available." << std::endl;
579 std::cerr <<
" Here it is not the case, and hence this option will be ignored." << std::endl;
582 number_of_cores = ival;
585 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads where <number> it not a number: '" << argv[i+1] <<
"'" << std::endl;
591 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads without <number>" << std::endl;
595 }
else if (!strcmp(argv[i],
"-r") || !strcmp(argv[i],
"--reset")) {
596 reset_startup_file =
true;
597 }
else if (!strcmp(argv[i],
"--timeout")) {
599 TString str(argv[i+1]);
603 timeout_enabled =
false;
604 std::cout << std::endl <<
">> musrfit: timeout disabled." << std::endl;
607 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout with unsupported <timeout_tag> = " << argv[i+1] << std::endl;
613 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout without <timeout_tag>" << std::endl;
624 if (filename.empty() && !reset_startup_file) {
626 std::cout << std::endl <<
">> musrfit **ERROR** no msr-file present!" << std::endl;
635 if (!dump.IsNull()) {
637 if (!dump.Contains(
"ascii") && !dump.Contains(
"root")) {
638 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump with unsupported <type> = " << dump << std::endl;
646 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
647 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>(reset_startup_file);
648 if (reset_startup_file)
650 if (!startupHandler->StartupFileFound()) {
651 std::cerr << std::endl <<
">> musrfit **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
652 std::cerr << std::endl;
655 saxParser->ConnectToHandler(
"PStartupHandler", startupHandler.get());
662 std::cerr << std::endl <<
">> musrfit **WARNING** Reading/parsing musrfit_startup.xml failed.";
663 std::cerr << std::endl;
669 omp_set_num_threads(number_of_cores);
673 std::unique_ptr<PMsrHandler> msrHandler;
675 msrHandler = std::make_unique<PMsrHandler>(filename.c_str(), &startup_options);
677 msrHandler = std::make_unique<PMsrHandler>(filename.c_str());
678 status = msrHandler->ReadMsrFile();
682 std::cout << std::endl <<
">> musrfit **ERROR** couldn't find " << filename << std::endl << std::endl;
685 std::cout << std::endl <<
">> musrfit **SYNTAX ERROR** in file " << filename <<
", full stop here." << std::endl << std::endl;
688 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to read the msr-file" << std::endl << std::endl;
695 std::unique_ptr<PRunDataHandler> dataHandler;
697 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get(), startupHandler->GetDataPathList());
699 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get());
701 dataHandler->ReadData();
703 bool success = dataHandler->IsAllDataAvailable();
705 std::cerr << std::endl <<
">> musrfit **ERROR** Couldn't read all data files, will quit ..." << std::endl;
709 if (title_from_data_file && success) {
713 std::cerr << std::endl <<
">> musrfit **ERROR** no run list present." << std::endl;
716 TString *name = rl->at(0).GetRunName();
717 if (name ==
nullptr) {
718 std::cerr << std::endl <<
">> musrfit **ERROR** to obtain run list name." << std::endl;
723 rrd = dataHandler->GetRunData(*(rl->at(0).GetRunName()));
724 if (rrd ==
nullptr) {
725 std::cerr << std::endl <<
">> musrfit **ERROR** no raw run data avaliable." << std::endl;
737 std::unique_ptr<PRunListCollection> runListCollection;
740 runListCollection = std::make_unique<PRunListCollection>(msrHandler.get(), dataHandler.get());
741 for (
unsigned int i=0; i < msrHandler->GetMsrRunList()->size(); i++) {
742 success = runListCollection->Add(i,
kFit);
744 std::cout << std::endl <<
">> musrfit **ERROR** Couldn't handle run no " << i+1 <<
": ";
745 std::cout << (*msrHandler->GetMsrRunList())[i].GetRunName()->Data();
752 std::unique_ptr<TThread> th;
753 if (timeout_enabled) {
754 static pid_t musrfit_pid = getpid();
762 std::unique_ptr<PFitter> fitter;
764 fitter = std::make_unique<PFitter>(msrHandler.get(), runListCollection.get(), chisq_only, yaml_out);
765 if (fitter->IsValid()) {
767 if (!fitter->IsScanOnly())
768 msrHandler->SetMsrStatisticConverged(fitter->HasConverged());
773 if (success && !chisq_only) {
774 if (!fitter->IsScanOnly()) {
775 status = msrHandler->WriteMsrLogFile();
779 std::cout << std::endl <<
">> musrfit **ERROR** couldn't write mlog-file" << std::endl << std::endl;
782 std::cout << std::endl <<
">> musrfit **ERROR** couldn't generate mlog-file name" << std::endl << std::endl;
785 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to write the mlog-file" << std::endl << std::endl;
793 if (success && !dump.IsNull()) {
794 std::cout << std::endl <<
"will write dump file ..." << std::endl;
796 if (dump.Contains(
"ascii"))
798 else if (dump.Contains(
"root"))
801 std::cout << std::endl <<
"do not know format " << dump.Data() <<
", sorry :-| " << std::endl;
806 if (keep_mn2_output && !chisq_only && !fitter->IsScanOnly()) {
808 TString fln = TString(filename.c_str());
809 fln.ReplaceAll(
".msr",
"-mn2.output");
810 gSystem->CopyFile(
"MINUIT2.OUTPUT", fln.Data(), kTRUE);
813 fln = TString(filename.c_str());
814 fln.ReplaceAll(
".msr",
"-mn2.root");
815 gSystem->CopyFile(
"MINUIT2.root", fln.Data(), kTRUE);
820 if (!chisq_only && !fitter->IsScanOnly()) {
822 std::cout << std::endl <<
">> swapping msr-, mlog-file ..." << std::endl;
824 gSystem->CopyFile(filename.c_str(),
"__temp.msr", kTRUE);
826 TString fln = TString(filename.c_str());
827 fln.ReplaceAll(
".msr",
".mlog");
828 gSystem->CopyFile(fln.Data(), filename.c_str(), kTRUE);
830 gSystem->CopyFile(
"__temp.msr", fln.Data(), kTRUE);
832 TSystemFile tmp(
"__temp.msr",
"./");
837 if (th && timeout_enabled) {
841 std::cout << std::endl <<
"done ..." << std::endl;