source: src/UIElements/CommandLineUI/CommandLineParser.cpp@ 7d9416

Action_Thermostats Add_AtomRandomPerturbation Add_FitFragmentPartialChargesAction Add_RotateAroundBondAction Add_SelectAtomByNameAction Added_ParseSaveFragmentResults AddingActions_SaveParseParticleParameters Adding_Graph_to_ChangeBondActions Adding_MD_integration_tests Adding_ParticleName_to_Atom Adding_StructOpt_integration_tests AtomFragments Automaking_mpqc_open AutomationFragmentation_failures Candidate_v1.5.4 Candidate_v1.6.0 Candidate_v1.6.1 ChangeBugEmailaddress ChangingTestPorts ChemicalSpaceEvaluator CombiningParticlePotentialParsing Combining_Subpackages Debian_Package_split Debian_package_split_molecuildergui_only Disabling_MemDebug Docu_Python_wait EmpiricalPotential_contain_HomologyGraph EmpiricalPotential_contain_HomologyGraph_documentation Enable_parallel_make_install Enhance_userguide Enhanced_StructuralOptimization Enhanced_StructuralOptimization_continued Example_ManyWaysToTranslateAtom Exclude_Hydrogens_annealWithBondGraph FitPartialCharges_GlobalError Fix_BoundInBox_CenterInBox_MoleculeActions Fix_ChargeSampling_PBC Fix_ChronosMutex Fix_FitPartialCharges Fix_FitPotential_needs_atomicnumbers Fix_ForceAnnealing Fix_IndependentFragmentGrids Fix_ParseParticles Fix_ParseParticles_split_forward_backward_Actions Fix_PopActions Fix_QtFragmentList_sorted_selection Fix_Restrictedkeyset_FragmentMolecule Fix_StatusMsg Fix_StepWorldTime_single_argument Fix_Verbose_Codepatterns Fix_fitting_potentials Fixes ForceAnnealing_goodresults ForceAnnealing_oldresults ForceAnnealing_tocheck ForceAnnealing_with_BondGraph ForceAnnealing_with_BondGraph_continued ForceAnnealing_with_BondGraph_continued_betteresults ForceAnnealing_with_BondGraph_contraction-expansion FragmentAction_writes_AtomFragments FragmentMolecule_checks_bonddegrees GeometryObjects Gui_Fixes Gui_displays_atomic_force_velocity ImplicitCharges IndependentFragmentGrids IndependentFragmentGrids_IndividualZeroInstances IndependentFragmentGrids_IntegrationTest IndependentFragmentGrids_Sole_NN_Calculation JobMarket_RobustOnKillsSegFaults JobMarket_StableWorkerPool JobMarket_unresolvable_hostname_fix MoreRobust_FragmentAutomation ODR_violation_mpqc_open PartialCharges_OrthogonalSummation PdbParser_setsAtomName PythonUI_with_named_parameters QtGui_reactivate_TimeChanged_changes Recreated_GuiChecks Rewrite_FitPartialCharges RotateToPrincipalAxisSystem_UndoRedo SaturateAtoms_findBestMatching SaturateAtoms_singleDegree StoppableMakroAction Subpackage_CodePatterns Subpackage_JobMarket Subpackage_LinearAlgebra Subpackage_levmar Subpackage_mpqc_open Subpackage_vmg Switchable_LogView ThirdParty_MPQC_rebuilt_buildsystem TrajectoryDependenant_MaxOrder TremoloParser_IncreasedPrecision TremoloParser_MultipleTimesteps TremoloParser_setsAtomName Ubuntu_1604_changes stable
Last change on this file since 7d9416 was 7d9416, checked in by Frederik Heber <heber@…>, 13 years ago

Turned query<Box> into query<RealSpaceMatrix>

  • Property mode set to 100644
File size: 20.2 KB
Line 
1/*
2 * Project: MoleCuilder
3 * Description: creates and alters molecular systems
4 * Copyright (C) 2010-2012 University of Bonn. All rights reserved.
5 * Please see the LICENSE file or "Copyright notice" in builder.cpp for details.
6 */
7
8/*
9 * CommandLineParser.cpp
10 *
11 * Created on: May 8, 2010
12 * Author: heber
13 */
14
15// include config.h
16#ifdef HAVE_CONFIG_H
17#include <config.h>
18#endif
19
20#include "CodePatterns/MemDebug.hpp"
21
22#include <boost/filesystem.hpp>
23#include <boost/program_options.hpp>
24#include <fstream>
25#include <iostream>
26#include <set>
27#include <map>
28
29#include "Actions/Action.hpp"
30#include "Actions/ActionRegistry.hpp"
31#include "Actions/ActionTrait.hpp"
32#include "Actions/OptionRegistry.hpp"
33#include "Actions/OptionTrait.hpp"
34#include "Actions/Values.hpp"
35#include "CodePatterns/Log.hpp"
36#include "CodePatterns/Verbose.hpp"
37#include "CommandLineParser.hpp"
38#include "CommandLineParser_validate.hpp"
39
40#include "CodePatterns/Singleton_impl.hpp"
41
42using namespace MoleCuilder;
43
44class element;
45
46/** Constructor of class CommandLineParser.
47 *
48 */
49CommandLineParser::CommandLineParser() :
50 analysis("Analysis options"),
51 atom("Atom options"),
52 command("Command options"),
53 fill("fill options"),
54 fragmentation("Fragmentation options"),
55 graph("Graph options"),
56 molecule("Molecule options"),
57 options("Secondary options"),
58 parser("Parser options"),
59 selection("Selection options"),
60 tesselation("Tesselation options"),
61 world("World options")
62{
63 // put all options lists into a lookup
64 CmdParserLookup["analysis"] = &analysis;
65 CmdParserLookup["atom"] = &atom;
66 CmdParserLookup["command"] = &command;
67 CmdParserLookup["edit"] = &edit;
68 CmdParserLookup["fill"] = &fill;
69 CmdParserLookup["fragmentation"] = &fragmentation;
70 CmdParserLookup["graph"] = &graph;
71 CmdParserLookup["options"] = &options;
72 CmdParserLookup["molecule"] = &molecule;
73 CmdParserLookup["parser"] = &parser;
74 CmdParserLookup["selection"] = &selection;
75 CmdParserLookup["tesselation"] = &tesselation;
76 CmdParserLookup["world"] = &world;
77}
78
79/** Destructor of class CommandLineParser.
80 *
81 */
82CommandLineParser::~CommandLineParser()
83{}
84
85/** Initializes command arguments to accept.
86 * Goes through ActionRegistry and puts all actions therein into the map.
87 */
88void CommandLineParser::InitializeCommandArguments()
89{
90 // we need a list of already added options, otherwise we get ambigious exceptions
91 std::set<std::string> AlreadyAddedOptionNames;
92
93 ActionRegistry &AR = ActionRegistry::getInstance();
94 bool ActionAlreadyAdded_flag = false;
95 for (ActionRegistry::const_iterator actioniter = AR.getBeginIter(); actioniter != AR.getEndIter(); ++actioniter) {
96 ActionAlreadyAdded_flag = false;
97 Action* const currentAction = actioniter->second;
98 //std::cout << "Current Action to initialize is: " << actioniter->first << std::endl;
99
100 for (ActionTrait::options_const_iterator optioniter = currentAction->Traits.getBeginIter();
101 optioniter != currentAction->Traits.getEndIter();
102 ++optioniter) {
103 if (optioniter->first == actioniter->first)
104 ActionAlreadyAdded_flag = true;
105 ASSERT( OptionRegistry::getInstance().isOptionPresentByName(optioniter->first),
106 "CommandLineParser::Init() - Option "+optioniter->first+" not present in OptionRegistry." );
107 const OptionTrait* const currentOption = OptionRegistry::getInstance().getOptionByName(optioniter->first);
108
109 if (AlreadyAddedOptionNames.find(optioniter->first) == AlreadyAddedOptionNames.end()) {
110 // add the option
111// std::cout << "Registering Option "
112// << currentOption->getName()
113// << " with type '" << currentOption->getTypeName() << "' "
114// << " with description '" << currentOption->getDescription() << "' ";
115// if (currentOption->hasShortForm())
116// std::cout << ", with short form " << currentOption->getShortForm();
117// else
118// std::cout << ", with no short form ";
119// if (currentOption->hasDefaultValue())
120// std::cout << ", with default value " << currentOption->getDefaultValue();
121// else
122// std::cout << ", with no default value ";
123// std::cout << std::endl;
124
125 AddOptionToParser(currentOption, (CmdParserLookup["options"]));
126
127 AlreadyAddedOptionNames.insert(optioniter->first);
128 } else {
129// std::cout << "Option " << currentOption->getName() << " already registered." << std::endl;
130 }
131 }
132
133 if (!ActionAlreadyAdded_flag) {
134 // add the action
135// std::cout << "Registering Action "
136// << currentAction->Traits.getName()
137// << " in menu " << currentAction->Traits.getMenuName()
138// << " with type '" << currentAction->Traits.getTypeName() << "' "
139// << " with description '" << currentAction->Traits.getDescription() << "' ";
140// if (currentAction->Traits.hasShortForm())
141// std::cout << ", with short form " << currentAction->Traits.getShortForm();
142// else
143// std::cout << ", with no short form ";
144// if (currentAction->Traits.hasDefaultValue())
145// std::cout << ", with default value " << currentAction->Traits.getDefaultValue();
146// else
147// std::cout << ", with no default value ";
148// std::cout << std::endl;
149
150 ASSERT(CmdParserLookup.find(currentAction->Traits.getMenuName()) != CmdParserLookup.end(),
151 "CommandLineParser: boost::program_options::options_description for this Action not present.");
152 AddOptionToParser(dynamic_cast<const OptionTrait * const>(&(currentAction->Traits)),(CmdParserLookup[currentAction->Traits.getMenuName()]));
153 }
154 }
155 // note: positioning is not important on the command line
156}
157
158/** Adds an Action or Option to the CommandLineParser.
159 * Note that Action is derived from Option(Trait)
160 *
161 * This ugly switch function is necessary because of the compile-time problem:
162 * po::value<T> has to be instantiated at compile-time however we do know the type not until run-time.
163 * Not even a templated function like po::value<T> getProgramOptionValuefromType() does help, specialized
164 * to each available type, as the signatures of all the functions differ. Hence, they cannot not put into
165 * one type_info -> po::value<T> map ...
166 *
167 * \param *currentOption pointer to Action/Option to add
168 * \param *OptionList program_options list to add to
169 */
170void CommandLineParser::AddOptionToParser(const OptionTrait * const currentOption, po::options_description* OptionList)
171{
172 // check whether dynamic_cast in Init() suceeded
173 ASSERT(currentOption != NULL, "CommandLineParser::AddOptionToParser() - currentOption is NULL!");
174 // add other options
175// std::cout << "Adding Action " << currentOption->getName() << " with type "
176// << currentOption->getType()->name() << ", " << (currentOption->hasDefaultValue() ? "with" : "without")
177// << " default value, and KeyandShortform " << currentOption->getKeyAndShortForm()
178// << " to CommandLineParser." << std::endl;
179 switch(TypeToEnums.getEnumforType(currentOption->getType())) {
180 default:
181 case TypeEnumContainer::NoneType:
182 OptionList->add_options()
183 (currentOption->getKeyAndShortForm().c_str(), currentOption->getDescription().c_str())
184 ;
185 break;
186 case TypeEnumContainer::BooleanType:
187 OptionList->add_options()
188 (currentOption->getKeyAndShortForm().c_str(),
189 currentOption->hasDefaultValue() ?
190 po::value < bool >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
191 po::value < bool >(),
192 currentOption->getDescription().c_str())
193 ;
194 break;
195 case TypeEnumContainer::FileType:
196 OptionList->add_options()
197 (currentOption->getKeyAndShortForm().c_str(),
198// currentOption->hasDefaultValue() ?
199// po::value < boost::filesystem::path >()->default_value(boost::lexical_cast<boost::filesystem::path>(currentOption->getDefaultValue().c_str())) :
200 po::value < boost::filesystem::path >(),
201 currentOption->getDescription().c_str())
202 ;
203 break;
204 case TypeEnumContainer::ListOfFilesType:
205 OptionList->add_options()
206 (currentOption->getKeyAndShortForm().c_str(),
207// currentOption->hasDefaultValue() ?
208// po::value < std::vector<boost::filesystem::path> >()->default_value(boost::lexical_cast< std::vector<boost::filesystem::path> >(currentOption->getDefaultValue().c_str())) :
209 po::value < std::vector<boost::filesystem::path> >()->multitoken(),
210 currentOption->getDescription().c_str())
211 ;
212 break;
213 case TypeEnumContainer::IntegerType:
214 OptionList->add_options()
215 (currentOption->getKeyAndShortForm().c_str(),
216 currentOption->hasDefaultValue() ?
217 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
218 po::value < int >(),
219 currentOption->getDescription().c_str())
220 ;
221 break;
222 case TypeEnumContainer::ListOfIntegersType:
223 OptionList->add_options()
224 (currentOption->getKeyAndShortForm().c_str(),
225// currentOption->hasDefaultValue() ?
226// po::value < std::vector<int> >()->default_value(boost::lexical_cast< std::vector<int> >(currentOption->getDefaultValue().c_str())) :
227 po::value < std::vector<int> >()->multitoken(),
228 currentOption->getDescription().c_str())
229 ;
230 break;
231 case TypeEnumContainer::UnsignedIntegerType:
232 OptionList->add_options()
233 (currentOption->getKeyAndShortForm().c_str(),
234 currentOption->hasDefaultValue() ?
235 po::value < unsigned int >()->default_value(boost::lexical_cast<unsigned int>(currentOption->getDefaultValue().c_str())) :
236 po::value < unsigned int >(),
237 currentOption->getDescription().c_str())
238 ;
239 break;
240 case TypeEnumContainer::ListOfUnsignedIntegersType:
241 OptionList->add_options()
242 (currentOption->getKeyAndShortForm().c_str(),
243// currentOption->hasDefaultValue() ?
244// po::value < std::vector<unsigned int> >()->default_value(boost::lexical_cast< std::vector<unsigned int> >(currentOption->getDefaultValue().c_str())) :
245 po::value < std::vector<unsigned int> >()->multitoken(),
246 currentOption->getDescription().c_str())
247 ;
248 break;
249 case TypeEnumContainer::DoubleType:
250 OptionList->add_options()
251 (currentOption->getKeyAndShortForm().c_str(),
252 currentOption->hasDefaultValue() ?
253 po::value < double >()->default_value(boost::lexical_cast<double>(currentOption->getDefaultValue().c_str())) :
254 po::value < double >(),
255 currentOption->getDescription().c_str())
256 ;
257 break;
258 case TypeEnumContainer::ListOfDoublesType:
259 OptionList->add_options()
260 (currentOption->getKeyAndShortForm().c_str(),
261// currentOption->hasDefaultValue() ?
262// po::value < std::vector<double> >()->default_value(boost::lexical_cast< std::vector<double> >(currentOption->getDefaultValue().c_str())) :
263 po::value < std::vector<double> >()->multitoken(),
264 currentOption->getDescription().c_str())
265 ;
266 break;
267 case TypeEnumContainer::StringType:
268 OptionList->add_options()
269 (currentOption->getKeyAndShortForm().c_str(),
270 currentOption->hasDefaultValue() ?
271 po::value < std::string >()->default_value(currentOption->getDefaultValue()) :
272 po::value < std::string >(),
273 currentOption->getDescription().c_str())
274 ;
275 break;
276 case TypeEnumContainer::ListOfStringsType:
277 OptionList->add_options()
278 (currentOption->getKeyAndShortForm().c_str(),
279// currentOption->hasDefaultValue() ?
280// po::value < std::vector<std::string> >()->default_value(boost::lexical_cast< std::vector<std::string> >(currentOption->getDefaultValue().c_str())) :
281 po::value < std::vector<std::string> >()->multitoken(),
282 currentOption->getDescription().c_str())
283 ;
284 break;
285 case TypeEnumContainer::VectorType:
286 OptionList->add_options()
287 (currentOption->getKeyAndShortForm().c_str(),
288// currentOption->hasDefaultValue() ?
289// po::value < VectorValue >()->default_value(boost::lexical_cast<VectorValue>(currentOption->getDefaultValue().c_str())) :
290 po::value < VectorValue >(),
291 currentOption->getDescription().c_str())
292 ;
293 break;
294 case TypeEnumContainer::ListOfVectorsType:
295 OptionList->add_options()
296 (currentOption->getKeyAndShortForm().c_str(),
297// currentOption->hasDefaultValue() ?
298// po::value < std::vector<VectorValue> >()->default_value(boost::lexical_cast< std::vector<VectorValue> >(currentOption->getDefaultValue().c_str())) :
299 po::value < std::vector<VectorValue> >()->multitoken(),
300 currentOption->getDescription().c_str())
301 ;
302 break;
303 case TypeEnumContainer::MoleculeType:
304 OptionList->add_options()
305 (currentOption->getKeyAndShortForm().c_str(),
306// currentOption->hasDefaultValue() ?
307// po::value < const molecule * >()->default_value(boost::lexical_cast<const molecule *>(currentOption->getDefaultValue().c_str())) :
308 po::value < int >(),
309 currentOption->getDescription().c_str())
310 ;
311 break;
312 case TypeEnumContainer::ListOfMoleculesType:
313 OptionList->add_options()
314 (currentOption->getKeyAndShortForm().c_str(),
315// currentOption->hasDefaultValue() ?
316// po::value < std::vector<const molecule *> >()->default_value(boost::lexical_cast< std::vector<const molecule *> >(currentOption->getDefaultValue().c_str())) :
317 po::value < std::vector<int> >()->multitoken(),
318 currentOption->getDescription().c_str())
319 ;
320 break;
321 case TypeEnumContainer::AtomType:
322 OptionList->add_options()
323 (currentOption->getKeyAndShortForm().c_str(),
324 currentOption->hasDefaultValue() ?
325 po::value < int >()->default_value(boost::lexical_cast<int>(currentOption->getDefaultValue().c_str())) :
326 po::value < int >(),
327 currentOption->getDescription().c_str())
328 ;
329 break;
330 case TypeEnumContainer::ListOfAtomsType:
331 OptionList->add_options()
332 (currentOption->getKeyAndShortForm().c_str(),
333// currentOption->hasDefaultValue() ?
334// po::value < std::vector<const atom *> >()->default_value(boost::lexical_cast< std::vector<const atom *> >(currentOption->getDefaultValue().c_str())) :
335 po::value < std::vector<int> >()->multitoken(),
336 currentOption->getDescription().c_str())
337 ;
338 break;
339 case TypeEnumContainer::ElementType:
340 OptionList->add_options()
341 (currentOption->getKeyAndShortForm().c_str(),
342// currentOption->hasDefaultValue() ?
343// po::value < const element * >()->default_value(boost::lexical_cast<const element *>(currentOption->getDefaultValue().c_str())) :
344 po::value < int >(),
345 currentOption->getDescription().c_str())
346 ;
347 break;
348 case TypeEnumContainer::ListOfElementsType:
349 OptionList->add_options()
350 (currentOption->getKeyAndShortForm().c_str(),
351// currentOption->hasDefaultValue() ?
352// po::value < std::vector<const element *> >()->default_value(boost::lexical_cast< std::vector<const element *> >(currentOption->getDefaultValue().c_str())) :
353 po::value < std::vector<int> >()->multitoken(),
354 currentOption->getDescription().c_str())
355 ;
356 break;
357 case TypeEnumContainer::RandomNumberDistribution_ParametersType:
358 OptionList->add_options()
359 (currentOption->getKeyAndShortForm().c_str(),
360 currentOption->hasDefaultValue() ?
361 po::value < std::string >()->default_value(boost::lexical_cast< std::string >(currentOption->getDefaultValue().c_str())) :
362 po::value < std::string >(),
363 currentOption->getDescription().c_str())
364 ;
365 break;
366 case TypeEnumContainer::RealSpaceMatrixType:
367 OptionList->add_options()
368 (currentOption->getKeyAndShortForm().c_str(),
369// currentOption->hasDefaultValue() ?
370// po::value < RealSpaceMatrixValue >()->default_value(boost::lexical_cast<BoxValue>(currentOption->getDefaultValue().c_str())) :
371 po::value < RealSpaceMatrixValue >(),
372 currentOption->getDescription().c_str())
373 ;
374 break;
375 }
376}
377
378/** States whether there are command line arguments.
379 * \return true - there are none, false - there is at least one command line argument
380 */
381bool CommandLineParser::isEmpty()
382{
383 return vm.empty();
384}
385
386/** Sets the options.
387 * \param _argc arg count from main()
388 * \param **_argv argument array from main()
389 */
390void CommandLineParser::setOptions(int _argc, char **_argv)
391{
392 argc = _argc;
393 argv = _argv;
394 config_file_options.add(options);
395 // append all option_descriptions to both cmdline_options and visible
396 for (CmdParserLookupMap::iterator iter = CmdParserLookup.begin();
397 iter != CmdParserLookup.end();
398 ++iter) {
399 cmdline_options.add(*(iter->second));
400 visible.add(*(iter->second));
401 }
402}
403
404/** Parses the command line arguments.
405 * Calls program_options::store() and program_options::notify()
406 */
407void CommandLineParser::Parse()
408{
409 po::store(po::command_line_parser(argc,argv).options(cmdline_options).run(), vm);
410 std::ifstream input;
411 input.open("example.cfg");
412 if (!input.fail())
413 po::store(po::parse_config_file(input, config_file_options), vm);
414 input.close();
415 po::notify(vm);
416}
417
418/** Scan the argument list for -a or --arguments and store their order for later use.
419 */
420void CommandLineParser::scanforSequenceOfArguments()
421{
422 std::map <std::string, std::string> ShortFormToActionMap = getShortFormToActionMap();
423 LOG(0, "Scanning command line arguments and recognizing Actions.");
424 // go through all arguments
425 for (int i=1;i<argc;i++) {
426 LOG(2, "Checking on " << argv[i]);
427 // check whether they
428 if (argv[i][0] == '-') { // .. begin with -
429 LOG(2, "Possible argument: " << argv[i]);
430 if (argv[i][1] == '-') { // .. or --
431 LOG(1, "Putting " << argv[i] << " into the sequence.");
432 SequenceOfActions.push_back(&(argv[i][2]));
433 // .. and check that next letter is not numeric, if so insert
434 } else if (((argv[i][1] < '0') || (argv[i][1] > '9')) && ((argv[i][1] != '.'))) {
435 std::map <std::string, std::string>::iterator iter = ShortFormToActionMap.find(&(argv[i][1]));
436 if (iter != ShortFormToActionMap.end()) {
437 LOG(1, "Putting " << iter->second << " for " << iter->first << " into the sequence.");
438 SequenceOfActions.push_back(iter->second);
439 }
440 }
441 }
442 }
443}
444
445/** Makes the Parser parse the command line options with current known options.
446 * \param _argc arg count from main()
447 * \param **_argv argument array from main()
448 */
449void CommandLineParser::Run(int _argc, char **_argv)
450{
451 setOptions(_argc,_argv);
452 Parse();
453 scanforSequenceOfArguments();
454}
455
456/** Go through all Actions and create a map from short form to their token.
457 * \return map from Action's ShortForm to token.
458 */
459std::map <std::string, std::string> CommandLineParser::getShortFormToActionMap() const
460{
461 std::map <std::string, std::string> result;
462
463 ActionRegistry &AR = ActionRegistry::getInstance();
464 for (ActionRegistry::const_iterator iter = AR.getBeginIter(); iter != AR.getEndIter(); ++iter)
465 if ((iter->second)->Traits.hasShortForm()) {
466 ASSERT(result.find((iter->second)->Traits.getShortForm()) == result.end(),
467 "Short form "+toString((iter->second)->Traits.getShortForm())+
468 " for action "+toString(iter->first)+" already present from "+
469 std::string(result[(iter->second)->Traits.getShortForm()])+"!");
470 result[(iter->second)->Traits.getShortForm()] = (iter->second)->getName();
471 }
472
473 return result;
474}
475
476CONSTRUCT_SINGLETON(CommandLineParser)
Note: See TracBrowser for help on using the repository browser.