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 <<
" -r, --reset: reset startup musrfit_startup.xml, i.e. rewrite a default, and quit.";
125 std::cout << std::endl <<
" The order of which musrfit_startup.xml is reset is:";
126 std::cout << std::endl <<
" (i) if present in the current dir.";
127 std::cout << std::endl <<
" (ii) if present under $HOME/.musrfit/";
128 std::cout << std::endl <<
" (iii) if present under $MUSRFITPATH/";
129 std::cout << std::endl <<
" (iv) if present under $ROOTSYS/";
130 std::cout << std::endl <<
" -y, --yaml: write fit results (MINUIT2.OUTPUT) into a yaml-file. Output <msr-file>.yaml";
131 std::cout << std::endl <<
" --dump <type> is writing a data file with the fit data and the theory";
132 std::cout << std::endl <<
" <type> can be 'ascii', 'root'";
133 std::cout << std::endl <<
" --timeout <timeout_tag>: overwrites to predefined timeout of " <<
timeout <<
" (sec).";
134 std::cout << std::endl <<
" <timeout_tag> <= 0 means timeout facility is not enabled. <timeout_tag> = nn";
135 std::cout << std::endl <<
" will set the timeout to nn (sec).";
136 std::cout << std::endl;
137 std::cout << std::endl <<
" At the end of a fit, musrfit writes the fit results into an <mlog-file> and";
138 std::cout << std::endl <<
" swaps them, i.e. in the <msr-file> you will find the fit results and in the";
139 std::cout << std::endl <<
" <mlog-file> your initial guess values.";
140 std::cout << std::endl << std::endl;
444int main(
int argc,
char *argv[])
447 bool show_syntax =
false;
456 if (!strcmp(argv[1],
"--version")) {
459 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;
461 std::cout << std::endl <<
"musrfit version: " << PACKAGE_VERSION <<
" (" << BUILD_TYPE <<
"), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
465 std::cout << std::endl <<
"musrfit git-branch: " << GIT_BRANCH <<
", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
467 std::cout << std::endl <<
"musrfit version: unknown" << std::endl << std::endl;
471 }
else if (!strcmp(argv[1],
"--nexus-support")) {
473 std::cout << std::endl <<
">> musrfit: NeXus support enabled. ";
474 std::cout <<
" HDF5 ready. ";
476 std::cout <<
" HDF4 ready." << std::endl << std::endl;
478 std::cout <<
" HDF4 not ready." << std::endl << std::endl;
481 std::cout << std::endl <<
"musrfit: NeXus support NOT enabled." << std::endl << std::endl;
484 }
else if (!strcmp(argv[1],
"--help")) {
495 bool keep_mn2_output =
false;
496 bool chisq_only =
false;
497 bool yaml_out =
false;
498 bool title_from_data_file =
false;
499 bool timeout_enabled =
true;
500 bool reset_startup_file =
false;
504 int number_of_cores=1;
507 number_of_cores = omp_get_num_procs();
514 const char *dsp = gSystem->GetDynamicPath();
515 if (strstr(dsp,
"/usr/local/lib") ==
nullptr)
516 gSystem->AddDynamicPath(
"/usr/local/lib");
520 if (!strcmp(argv[1],
"--show-dynamic-path")) {
521 std::cout << std::endl <<
"musrfit: internal dynamic search paths for shared libraries/root dictionaries:";
522 std::cout << std::endl <<
" '" << gSystem->GetDynamicPath() <<
"'" << std::endl << std::endl;
527 memset(filename,
'\0',
sizeof(filename));
528 strcpy(filename,
"");
529 for (
int i=1; i<argc; i++) {
530 if (strstr(argv[i],
".msr")) {
531 strncpy(filename, argv[i],
sizeof(filename));
532 }
else if (!strcmp(argv[i],
"-k") || !strcmp(argv[i],
"--keep-mn2-output")) {
533 keep_mn2_output =
true;
534 }
else if (!strcmp(argv[i],
"-c") || !strcmp(argv[i],
"--chisq-only")) {
536 }
else if (!strcmp(argv[i],
"-t") || !strcmp(argv[i],
"--title-from-data-file")) {
537 title_from_data_file =
true;
538 }
else if (!strcmp(argv[i],
"--dump")) {
540 dump = TString(argv[i+1]);
543 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump without <type>" << std::endl;
547 }
else if (!strcmp(argv[i],
"-e") || !strcmp(argv[i],
"--estimateN0")) {
549 }
else if (!strcmp(argv[i],
"-p") || !strcmp(argv[i],
"--per-run-block-chisq")) {
551 }
else if (!strcmp(argv[i],
"-y") || !strcmp(argv[i],
"--yaml")) {
553 }
else if (!strcmp(argv[i],
"-n") || !strcmp(argv[i],
"--no-of-cores-avail")) {
555 std::cout << std::endl;
556 std::cout <<
"musrfit: maxmimal number of cores for OpenMP available: " << omp_get_num_procs() << std::endl;
557 std::cout << std::endl;
559 std::cout << std::endl;
560 std::cout <<
">> musrfit: this option is only vaild if OpenMP is present. This seems not to be the case here. Sorry!" << std::endl;
561 std::cout << std::endl;
564 }
else if (!strcmp(argv[i],
"-u") || !strcmp(argv[i],
"--use-no-of-threads")) {
566 TString str(argv[i+1]);
568 int ival = str.Atoi();
570 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads with <number> <= 0" << std::endl;
571 std::cerr <<
" This doesn't make any sense." << std::endl;
574 }
else if (ival > number_of_cores) {
576 std::cerr << std::endl <<
">> musrfit: **WARNING** found option --use-no-of-threads with <number>=" << ival <<
" > max available cores=" << number_of_cores <<
"." << std::endl;
577 std::cerr <<
" Will set <number> to max available cores." << std::endl;
579 std::cerr << std::endl <<
">> musrfit: **WARNING** option --use-no-of-threads can only be used if OpenMP is available." << std::endl;
580 std::cerr <<
" Here it is not the case, and hence this option will be ignored." << std::endl;
583 number_of_cores = ival;
586 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads where <number> it not a number: '" << argv[i+1] <<
"'" << std::endl;
592 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --use-no-of-threads without <number>" << std::endl;
596 }
else if (!strcmp(argv[i],
"-r") || !strcmp(argv[i],
"--reset")) {
597 reset_startup_file =
true;
598 }
else if (!strcmp(argv[i],
"--timeout")) {
600 TString str(argv[i+1]);
604 timeout_enabled =
false;
605 std::cout << std::endl <<
">> musrfit: timeout disabled." << std::endl;
608 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout with unsupported <timeout_tag> = " << argv[i+1] << std::endl;
614 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --timeout without <timeout_tag>" << std::endl;
625 if ((strlen(filename) == 0) && !reset_startup_file) {
627 std::cout << std::endl <<
">> musrfit **ERROR** no msr-file present!" << std::endl;
636 if (!dump.IsNull()) {
638 if (!dump.Contains(
"ascii") && !dump.Contains(
"root")) {
639 std::cerr << std::endl <<
">> musrfit: **ERROR** found option --dump with unsupported <type> = " << dump << std::endl;
647 std::unique_ptr<TSAXParser> saxParser = std::make_unique<TSAXParser>();
648 std::unique_ptr<PStartupHandler> startupHandler = std::make_unique<PStartupHandler>(reset_startup_file);
649 if (reset_startup_file)
651 if (!startupHandler->StartupFileFound()) {
652 std::cerr << std::endl <<
">> musrfit **WARNING** couldn't find " << startupHandler->GetStartupFilePath().Data();
653 std::cerr << std::endl;
657 saxParser->ConnectToHandler(
"PStartupHandler", startupHandler.get());
664 std::cerr << std::endl <<
">> musrfit **WARNING** Reading/parsing musrfit_startup.xml failed.";
665 std::cerr << std::endl;
671 omp_set_num_threads(number_of_cores);
675 std::unique_ptr<PMsrHandler> msrHandler;
677 msrHandler = std::make_unique<PMsrHandler>(filename, &startup_options);
679 msrHandler = std::make_unique<PMsrHandler>(filename);
680 status = msrHandler->ReadMsrFile();
684 std::cout << std::endl <<
">> musrfit **ERROR** couldn't find " << filename << std::endl << std::endl;
687 std::cout << std::endl <<
">> musrfit **SYNTAX ERROR** in file " << filename <<
", full stop here." << std::endl << std::endl;
690 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to read the msr-file" << std::endl << std::endl;
697 std::unique_ptr<PRunDataHandler> dataHandler;
699 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get(), startupHandler->GetDataPathList());
701 dataHandler = std::make_unique<PRunDataHandler>(msrHandler.get());
703 dataHandler->ReadData();
705 bool success = dataHandler->IsAllDataAvailable();
707 std::cerr << std::endl <<
">> musrfit **ERROR** Couldn't read all data files, will quit ..." << std::endl;
711 if (title_from_data_file && success) {
715 std::cerr << std::endl <<
">> musrfit **ERROR** no run list present." << std::endl;
718 TString *name = rl->at(0).GetRunName();
719 if (name ==
nullptr) {
720 std::cerr << std::endl <<
">> musrfit **ERROR** to obtain run list name." << std::endl;
725 rrd = dataHandler->GetRunData(*(rl->at(0).GetRunName()));
726 if (rrd ==
nullptr) {
727 std::cerr << std::endl <<
">> musrfit **ERROR** no raw run data avaliable." << std::endl;
739 std::unique_ptr<PRunListCollection> runListCollection;
742 runListCollection = std::make_unique<PRunListCollection>(msrHandler.get(), dataHandler.get());
743 for (
unsigned int i=0; i < msrHandler->GetMsrRunList()->size(); i++) {
744 success = runListCollection->Add(i,
kFit);
746 std::cout << std::endl <<
">> musrfit **ERROR** Couldn't handle run no " << i+1 <<
": ";
747 std::cout << (*msrHandler->GetMsrRunList())[i].GetRunName()->Data();
754 std::unique_ptr<TThread> th;
755 if (timeout_enabled) {
756 static pid_t musrfit_pid = getpid();
764 std::unique_ptr<PFitter> fitter;
766 fitter = std::make_unique<PFitter>(msrHandler.get(), runListCollection.get(), chisq_only, yaml_out);
767 if (fitter->IsValid()) {
769 if (!fitter->IsScanOnly())
770 msrHandler->SetMsrStatisticConverged(fitter->HasConverged());
775 if (success && !chisq_only) {
776 if (!fitter->IsScanOnly()) {
777 status = msrHandler->WriteMsrLogFile();
781 std::cout << std::endl <<
">> musrfit **ERROR** couldn't write mlog-file" << std::endl << std::endl;
784 std::cout << std::endl <<
">> musrfit **ERROR** couldn't generate mlog-file name" << std::endl << std::endl;
787 std::cout << std::endl <<
">> musrfit **UNKOWN ERROR** when trying to write the mlog-file" << std::endl << std::endl;
795 if (success && !dump.IsNull()) {
796 std::cout << std::endl <<
"will write dump file ..." << std::endl;
798 if (dump.Contains(
"ascii"))
800 else if (dump.Contains(
"root"))
803 std::cout << std::endl <<
"do not know format " << dump.Data() <<
", sorry :-| " << std::endl;
808 if (keep_mn2_output && !chisq_only && !fitter->IsScanOnly()) {
810 TString fln = TString(filename);
812 strcpy(ext,
"-mn2.output");
813 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
814 gSystem->CopyFile(
"MINUIT2.OUTPUT", fln.Data(), kTRUE);
817 fln = TString(filename);
818 strcpy(ext,
"-mn2.root");
819 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
820 gSystem->CopyFile(
"MINUIT2.root", fln.Data(), kTRUE);
825 if (!chisq_only && !fitter->IsScanOnly()) {
827 std::cout << std::endl <<
">> swapping msr-, mlog-file ..." << std::endl;
829 gSystem->CopyFile(filename,
"__temp.msr", kTRUE);
831 TString fln = TString(filename);
833 strcpy(ext,
".mlog");
834 fln.ReplaceAll(
".msr", 4, ext, strlen(ext));
835 gSystem->CopyFile(fln.Data(), filename, kTRUE);
837 gSystem->CopyFile(
"__temp.msr", fln.Data(), kTRUE);
839 TSystemFile tmp(
"__temp.msr",
"./");
844 if (th && timeout_enabled) {
848 std::cout << std::endl <<
"done ..." << std::endl;