/** * @file GArgumentParserLS.cpp */ /* Copyright (C) Dr. Ruediger Berlich and Karlsruhe Institute of Technology * (University of the State of Baden-Wuerttemberg and National Laboratory * of the Helmholtz Association) * * Contact: info [at] gemfony (dot) com * * This file is part of the Geneva library, Gemfony scientific's optimization * library. * * Geneva is free software: you can redistribute it and/or modify * it under the terms of version 3 of the GNU Affero General Public License * as published by the Free Software Foundation. * * Geneva is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with the Geneva library. If not, see <http://www.gnu.org/licenses/>. * * For further information on Gemfony scientific and Geneva, visit * http://www.gemfony.com . */ #include "Examples/pbarpToOmegaPiLS/GArgumentParserLS.hh" #include "ErrLogger/ErrLogger.hh" using namespace std; /************************************************************************************************/ /** * A function that parses the command line for all required parameters */ bool ApplicationParameterLS::parseCommandLine(int argc, char **argv) { try { int iAppMode=0; unsigned short DEFAULTPORT=port; std::string DEFAULTIP=ip; bool DEFAULTPARALLELIZATIONMODE=parallelizationMode; boost::uint16_t recombinationScheme=0; bool verbose; string strErrLogMode="debug"; // Check the command line options. Uses the Boost program options library. string strAppName(argv[0]); size_t found = strAppName.rfind("/")+1; if (found != string::npos) strAppName=strAppName.substr(found); string strDesc="Usage: " + strAppName + " [options]"; po::options_description desc(strDesc); desc.add_options() ("help,h", "emit help message") ("configFile,c",po::value<std::string>(&configFile)->default_value(configFile), "The name of the configuration file holding further configuration options") ("parallelizationMode,p", po::value<boost::uint16_t>(¶llelizationMode)->default_value(parallelizationMode), "Whether or not to run this optimization in serial mode (0), multi-threaded (1) or networked (2) mode") ("serverMode,s","Whether to run networked execution in server or client mode. The option only gets evaluated if \"--parallelizationMode=2\"") ("ip",po::value<std::string>(&ip)->default_value(ip), "The ip of the server") ("port",po::value<unsigned short>(&port)->default_value(port), "The port of the server") ("serMode", po::value<Gem::Common::serializationMode>(&serMode)->default_value(serMode), "Specifies whether serialization shall be done in TEXTMODE (0), XMLMODE (1) or BINARYMODE (2)") ("spf", po::value<string>(&strPathStartParamFile),"Path to the start parameter file.") ("mFixParFile", po::value<string>(&strMinuitFixParamFile),"Path to file for fixing parmeters in MINUIT.") ("M1", "Spin M for calculation of spin density.") ("M2", "Spin M' for calculation of spin density.") ("allSpin","Calculate all possible spin density elements of the spin density matrix.") ("remB",po::value<int>(&nNumEventsRemove),"Remove number of events from the beginning of the event list.") ("remE",po::value<int>(&nNumEventsRemove),"Remove number of events from the end of the event list.") ("redE",po::value<int>(&nNumEventsRed),"Reduce number of events from the event list to specified number.") ; po::options_description common("Common Options"); common.add_options() ("datFile",po::value<string>(&_dataFile), "full path of data file") ("mcFile",po::value<string>(&_mcFile), "full path of Monte Carlo file") ("lmax", po::value<unsigned>(&lMax)->default_value(lMax),"choose lmax.") ("pbarmom", po::value<unsigned>(&pbarMom)->default_value(pbarMom),"choose pbar momentum.") ("errLogMode,e", po::value<string>(&strErrLogMode)->default_value(strErrLogMode), "choose mode for Error logger.") ("appMode,a", po::value<int>(&iAppMode)->default_value(enAppExecMode), "Specifies which application should be used: for fitting GenEvA (0); for Minuit (1); Minuit after GenEvA (2); spin density calculation (3); QA mode (4); test mode for calculating pbarp-> omega pi states (5); test mode for histogramming (6); test mode for streaming fit parameter (7) .") ("name,n", po::value<string>(&strName)->default_value("myApp"), "Name that is attached to all otuput file names to be able to run multiple fits in parallel.") ("LhMode", po::value<std::string>(&theLhMode)->default_value(theLhMode), "Specifies the likelihood mode: OmegaPiLhGamma, OmegaTo3PiLhGamma or OmegaTo3PiLhProd") ; po::options_description config("Configuration file options"); config.add_options() ("nProducerThreads",po::value<boost::uint16_t>(&nProducerThreads)->default_value(nProducerThreads), "The amount of random number producer threads") ("nEvaluationThreads",po::value<boost::uint16_t>(&nEvaluationThreads)->default_value(nEvaluationThreads), "The amount of threads processing individuals simultaneously") ("populationSize",po::value<std::size_t>(&populationSize)->default_value(populationSize), "The size of the super-population") ("nParents",po::value<std::size_t>(&nParents)->default_value(nParents), "The number of parents in the population") // Needs to be treated separately ("maxIterations", po::value<boost::uint32_t>(&maxIterations)->default_value(maxIterations), "Maximum number of iterations in the population") ("maxMinutes", po::value<long>(&maxMinutes)->default_value(maxMinutes), "The maximum number of minutes the optimization of the population should run") ("reportIteration",po::value<boost::uint32_t>(&reportIteration)->default_value(reportIteration), "The number of iterations after which information should be emitted in the super-population") ("rScheme",po::value<boost::uint16_t>(&recombinationScheme)->default_value(VALUERECOMBINE), "The recombination scheme for the super-population") ("sortingScheme,o", po::value<sortingMode>(&smode)->default_value(smode), "Determines whether sorting is done in MUCOMMANU (0), MUPLUSNU (1) or MUNU1PRETAIN (2) mode") ("arraySize", po::value<std::size_t>(&arraySize)->default_value(arraySize), "The size of the buffer with random arrays in the random factory") ("verbose",po::value<bool>(&verbose)->default_value(true), "Whether additional information should be emitted") ("processingCycles", po::value<boost::uint32_t>(&processingCycles)->default_value(processingCycles), "The maximum number of cycles a client should perform mutations before it returns without success") ("returnRegardless", po::value<bool>(&returnRegardless)->default_value(returnRegardless), "Specifies whether results should be returned even if they are not better than before") ("waitFactor", po::value<boost::uint32_t>(&waitFactor)->default_value(waitFactor), "Influences the maximum waiting time of the GBrokerEA after the arrival of the first evaluated individuum") ; po::options_description cmdline_options; cmdline_options.add(desc).add(common); po::options_description config_file_options; config_file_options.add(config).add(common); po::variables_map vm; po::store(po::parse_command_line(argc, argv, cmdline_options), vm); po::notify(vm); // Check the name of the configuation file if(configFile.empty() || configFile == "empty" || configFile == "unknown") { stringstream strError; strError << "Error: Invalid configuration file name given: \"" << configFile << "\""; throw runtime_error(strError.str()); } std::ifstream ifs(configFile.c_str()); if(!ifs.good()) { stringstream strError; strError << "Error accessing configuratiocommonn file " << configFile; throw runtime_error(strError.str()); } store(po::parse_config_file(ifs, config_file_options), vm); po::notify(vm); // Emit a help message, if necessary if (vm.count("help")) { std::cout << cmdline_options << endl; exit(0); } serverMode=false; if (vm.count("parallelizationMode")) { if(parallelizationMode > 2) { stringstream strError; strError << "Error: the \"-p\" or \"--parallelizationMode\" option may only assume the\n" << "values 0 (serial), 1 (multi-threaded) or 2 (networked). Leaving ..."; throw runtime_error(strError.str()); } if(parallelizationMode == 2) if(vm.count("serverMode")) serverMode = true; } if(parallelizationMode != DEFAULTPARALLELIZATIONMODE || ip != DEFAULTIP || port != DEFAULTPORT){ std::string parModeString; switch(parallelizationMode) { case 0: parModeString = "serial"; break; case 1: parModeString = "multi-threaded"; break; case 2: parModeString = "networked"; break; }; std::cout << "\nRunning with the following command line options:\n" << "configFile = " << configFile << "\n" << "parallelizationMode = " << parModeString << "\n" << "serverMode = " << (serverMode?"true":"false") << "\n" << "ip = " << ip << "\n" << "port = " << port << "\n" << "serMode = " << serMode << "\n" << endl; } enAppExecMode=enExecMode(iAppMode); if (vm.count("appMode")) { if (int(enAppExecMode) > 7 || int(enAppExecMode) < 0) { stringstream strError; strError << "The option number " << int(enAppExecMode) << " for minimization algorithm is out of range!"; throw runtime_error(strError.str()); } } if (vm.count("allSpin")) { bCalcAllSpindensity = true; } else bCalcAllSpindensity = false; if (vm.count("spf")) { if (strPathStartParamFile.empty()) { stringstream strError; strError << "start parameter file must be specified when using --spf"; throw runtime_error(strError.str()); } } if (vm.count("mFixParFile")) { if (strMinuitFixParamFile.empty()) { stringstream strError; strError << "file to fix parameters with MINUIT must be specified when using --mFixParFile"; throw runtime_error(strError.str()); } } if (!vm.count("name") && (enAppExecMode != SpinDensity)) { stringstream strError; strError << "Name of the process must be specified!"; throw runtime_error(strError.str()); } //Config File Parameter check // Check the number of parents in the super-population if(2*nParents > populationSize){ stringstream strError; strError << "Error: Invalid number of parents inpopulation\n" << "nParents = " << nParents << "\n" << "populationSize = " << populationSize; throw runtime_error(strError.str()); } // Workaround for assigment problem with rScheme if(recombinationScheme==(boost::uint16_t)VALUERECOMBINE) rScheme=VALUERECOMBINE; else if(recombinationScheme==(boost::uint16_t)RANDOMRECOMBINE) rScheme=RANDOMRECOMBINE; else if(recombinationScheme==(boost::uint16_t)DEFAULTRECOMBINE) rScheme=DEFAULTRECOMBINE; else { stringstream strError; strError << "Error: Invalid recombination scheme in population: " << recombinationScheme; throw runtime_error(strError.str()); } if(strErrLogMode == "debug") errLogMode = debug; else if(strErrLogMode == "trace") errLogMode = trace; else if(strErrLogMode == "routine") errLogMode = routine; else if(strErrLogMode == "warning") errLogMode = warning; else if(strErrLogMode == "error") errLogMode = error; else if(strErrLogMode == "alert") errLogMode = alert; else { errLogMode = debug; Warning << "ErrorLogger not (properly) set -> Use mode 'DEBUG' " << endmsg; } if(vm.count("remB") && vm.count("remE")) { stringstream strError; strError << "Options remB and remE can't be combined only one can be used."; throw runtime_error(strError.str()); } else { if(vm.count("remE")) { bRemoveEventsFromEnd = true; } else if(vm.count("remB")) { bRemoveEventsFromEnd = false; } if (nNumEventsRemove<0) { stringstream strError; strError << "Number of events to remove must be positive!"; throw runtime_error(strError.str()); } } if (vm.count("redE")) { if(vm.count("remB") || vm.count("remE")) { stringstream strError; strError << "Options redE can't be used in connection with options remE or remB."; throw runtime_error(strError.str()); } if (nNumEventsRed < 0) { stringstream strError; strError << "Number to which number of events should be reduced must be greater then zero."; throw runtime_error(strError.str()); } bRemoveEventsFromEnd = true; } else nNumEventsRed=0; if (vm.count("allSpin") || vm.count("M1") || vm.count("M2")) { if (!vm.count("spf")) { stringstream strError; strError << "Start parameter file must be specified for the calculation of spin density"; throw runtime_error(strError.str()); } } if(verbose){ std::cout << "\nRunning with the following options using " << configFile << ":\n" << "data file: " << _dataFile <<"\n" << "mc file: " << _mcFile <<"\n" << "nProducerThreads = " << (boost::uint16_t)nProducerThreads << "\n" // boost::uint8_t not printable on gcc ??? << "populationSize = " << populationSize << "\n" << "nParents = " << nParents << "\n" << "maxIterations = " << maxIterations << "\n" << "maxMinutes = " << maxMinutes << "\n" << "reportIteration = " << reportIteration << "\n" << "rScheme = " << (boost::uint16_t)rScheme << "\n" << "sortingScheme = " << smode << "\n" << "arraySize = " << arraySize << "\n" << "processingCycles = " << processingCycles << "\n" << "returnRegardless = " << (returnRegardless?"true":"false") << "\n" << "lMax = " << lMax << "\n" << "pbarMom = " << pbarMom << "\n" << "errLogMode = " << strErrLogMode << "\n" << "LhMode = " << theLhMode << "\n" << endl; } } catch( std::exception & e ) { cerr << "Error parsing the command line:" << endl; cerr << e.what() << std::endl; cerr << "You can use -h or --help to obtain the description of the program parameters." << endl; return false; } catch(...){ std::cerr << "Error parsing the command line. Use -h or --help to see the description of the program paramters." << endl; return false; } return true; }