** Warning **
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle dbname=lxr at /lxr/lib/LXR/Common.pm line 1103.
Last-Modified: Fri, 2 Feb 2023 23:24:35 GMT
Content-Type: text/html; charset=utf-8
/CMSSW_13_0_X_2023-02-02-2300/PhysicsTools/FWLite/src/CommandLineParser.cc
File indexing completed on 2021-02-14 13:32:23
0001
0002 #include <iostream>
0003 #include <fstream>
0004 #include <iomanip>
0005 #include <cstdlib>
0006 #include <cassert>
0007
0008 #include "TString.h"
0009
0010 #include "PhysicsTools /FWLite /interface /CommandLineParser.h "
0011 #include "PhysicsTools /FWLite /interface /dout.h "
0012 #include "PhysicsTools /FWLite /interface /dumpSTL.icc "
0013
0014 using namespace std ;
0015 using namespace optutl ;
0016
0017 const std ::string CommandLineParser ::kSpaces = " \t" ;
0018
0019 CommandLineParser ::CommandLineParser (const string &usage , unsigned int optionsType)
0020 : m_argv0 ("" ), m_usageString (usage ), m_printOptions (true ), m_optionsType (optionsType) {
0021 if (m_optionsType & kEventContOpt ) {
0022
0023 addOption ("totalSections" , kInteger , "Total number of sections" , 0);
0024 addOption ("section" , kInteger , "This section (from 1..totalSections inclusive)" , 0);
0025 addOption ("maxEvents" , kInteger , "Maximum number of events to run over (0 for whole file)" , 0);
0026 addOption ("jobID" , kInteger , "jobID given by CRAB,etc. (-1 means append nothing)" , -1);
0027 addOption ("outputEvery" , kInteger , "Output something once every N events (0 for never)" , 0);
0028
0029 addOption ("outputFile" , kString , "Output filename" , "output.root" );
0030 addOption ("storePrepend" , kString , "Prepend location on files starting with '/store/'" );
0031 addOption ("tag" , kString , "A 'tag' to append to output file (e.g., 'v2', etc.)" );
0032
0033 addOption ("logName" , kBool , "Print log name and exit" );
0034
0035 addOption ("inputFiles" , kStringVector , "List of input files" );
0036 addOption ("secondaryInputFiles" , kStringVector , "List of secondary input files (a.k.a. two-file-solution" );
0037 addOption ("orderedSecondaryFiles" , kBool , "Are the secondary files ordered?" , false );
0038 return ;
0039 }
0040
0041 cerr << "CommandLineParser() Error: type '" << optionsType << "' is not understood. Aborting." << endl ;
0042 assert (0);
0043 }
0044
0045 void CommandLineParser ::parseArguments (int argc , char **argv , bool returnArgs) {
0046 bool callHelp = false ;
0047 SVec argsVec ;
0048 m_argv0 = argv [0];
0049 m_fullArgVec .push_back (argv [0]);
0050 for (int loop = 1; loop < argc ; ++loop ) {
0051 string arg = argv [loop ];
0052 m_fullArgVec .push_back (arg );
0053 string ::size_type where = arg .find_first_of('=' );
0054 if (string ::npos != where ) {
0055 if (_setVariableFromString (arg )) {
0056 continue ;
0057 }
0058 if (_runVariableCommandFromString (arg )) {
0059 continue ;
0060 }
0061 cerr << "Don't understand: " << arg << endl ;
0062 exit (0);
0063 }
0064 else if (arg .at (0) == '-' ) {
0065 string ::size_type where = arg .find_first_not_of('-' );
0066 if (string ::npos == where ) {
0067
0068 cerr << "Don't understand: " << arg << endl ;
0069 exit (0);
0070 continue ;
0071 }
0072 lowercaseString (arg );
0073 char first = arg .at (where );
0074
0075 if ('p' == first ) {
0076 m_printOptions = true ;
0077 continue ;
0078 }
0079 if ('n' == first ) {
0080 m_printOptions = false ;
0081 continue ;
0082 }
0083
0084 if ('h' == first ) {
0085 callHelp = true ;
0086 continue ;
0087 }
0088
0089 cerr << "Don't understand: " << arg << endl ;
0090 exit (0);
0091 }
0092 if (returnArgs) {
0093 argsVec .push_back (arg );
0094 } else {
0095 cerr << "Don't understand: " << arg << endl ;
0096 exit (0);
0097 }
0098 }
0099 if (callHelp ) {
0100 help ();
0101 }
0102 }
0103
0104 void CommandLineParser ::help () {
0105 if (m_usageString .length ()) {
0106 cout << m_argv0 << " - " << m_usageString << endl ;
0107 }
0108 cout << "--help - This screen" << endl
0109 << "--noPrint - Do not print out all settings" << endl
0110 << "--print - Print out all settings" << endl ;
0111 printOptionValues ();
0112 exit (0);
0113 }
0114
0115 void CommandLineParser ::split (SVec &retval , string line , string match , bool ignoreComments) {
0116 if (ignoreComments) {
0117 removeComment (line );
0118 }
0119 retval .clear ();
0120
0121 string ::size_type start1 = line .find_first_not_of(kSpaces );
0122
0123 char firstCh = line [start1 ];
0124 if ('#' == firstCh ) {
0125
0126 return ;
0127 }
0128
0129 line += match ;
0130 string ::size_type last = string ::npos ;
0131 string ::size_type current = line .find_first_of(match );
0132 while (string ::npos != current ) {
0133 string ::size_type pos ;
0134 if (string ::npos != last ) {
0135 pos = last + 1;
0136 } else {
0137 pos = 0;
0138 }
0139 string part = line .substr (pos , current - last - 1);
0140
0141 if (part .length ()) {
0142 retval .push_back (part );
0143 }
0144 last = current ;
0145 current = line .find_first_of(match , current + 1);
0146 }
0147 }
0148
0149 void CommandLineParser ::removeComment (string &line ) {
0150 string ::size_type location = line .find ('#' );
0151 if (string ::npos != location ) {
0152
0153 line = line .substr (0, location - 1);
0154 }
0155 }
0156
0157 void CommandLineParser ::removeLeadingAndTrailingSpaces (std ::string &line ) {
0158 string ::size_type pos = line .find_first_not_of(kSpaces );
0159 if (string ::npos == pos ) {
0160
0161 return ;
0162 }
0163 if (pos ) {
0164
0165 line = line .substr (pos );
0166 }
0167 pos = line .find_last_not_of(kSpaces );
0168 if (pos + 1 != line .length ()) {
0169
0170 line = line .substr (0, pos + 1);
0171 }
0172 }
0173
0174 string CommandLineParser ::removeEnding (const string &input , const string &ending ) {
0175 string ::size_type position = input .rfind(ending );
0176 if (input .length () - ending .length () == position ) {
0177
0178 return input .substr (0, position );
0179 }
0180
0181 return input ;
0182 }
0183
0184 void CommandLineParser ::findCommand (const string &line , string &command , string &rest ) {
0185 command = rest = "" ;
0186 string ::size_type nonspace = line .find_first_not_of(kSpaces );
0187 if (string ::npos == nonspace ) {
0188
0189 return ;
0190 }
0191 string ::size_type space = line .find_first_of(kSpaces , nonspace );
0192 if (string ::npos == space ) {
0193
0194 command = line .substr (nonspace );
0195 return ;
0196 }
0197 command = line .substr (nonspace , space - nonspace );
0198 rest = line .substr (space + 1);
0199 removeLeadingAndTrailingSpaces (rest );
0200 }
0201
0202 void CommandLineParser ::printOptionValues () {
0203 cout << "------------------------------------------------------------------" << left << endl ;
0204
0205 if (!m_integerMap .empty ()) {
0206 cout << endl << "Integer options:" << endl ;
0207 }
0208 for (SIMapConstIter iter = m_integerMap .begin (); m_integerMap .end () != iter ; ++iter ) {
0209 const string &description = m_variableDescriptionMap [iter ->first ];
0210 cout << " " << setw (14) << iter ->first << " = " << setw (14) << iter ->second ;
0211 if (description .length ()) {
0212 cout << " - " << description ;
0213 }
0214 cout << endl ;
0215 }
0216
0217
0218 if (!m_doubleMap .empty ()) {
0219 cout << endl << "Double options:" << endl ;
0220 }
0221 for (SDMapConstIter iter = m_doubleMap .begin (); m_doubleMap .end () != iter ; ++iter ) {
0222 const string &description = m_variableDescriptionMap [iter ->first ];
0223 cout << " " << setw (14) << iter ->first << " = " << setw (14) << iter ->second ;
0224 if (description .length ()) {
0225 cout << " - " << description ;
0226 }
0227 cout << endl ;
0228 }
0229
0230
0231 if (!m_boolMap .empty ()) {
0232 cout << endl << "Bool options:" << endl ;
0233 }
0234 for (SBMapConstIter iter = m_boolMap .begin (); m_boolMap .end () != iter ; ++iter ) {
0235 const string &description = m_variableDescriptionMap [iter ->first ];
0236 cout << " " << setw (14) << iter ->first << " = " << setw (14);
0237 if (iter ->second ) {
0238 cout << "true" ;
0239 } else {
0240 cout << "false" ;
0241 }
0242 if (description .length ()) {
0243 cout << " - " << description ;
0244 }
0245 cout << endl ;
0246 }
0247
0248
0249 if (!m_stringMap .empty ()) {
0250 cout << endl << "String options:" << endl ;
0251 }
0252 for (SSMapConstIter iter = m_stringMap .begin (); m_stringMap .end () != iter ; ++iter ) {
0253 const string &description = m_variableDescriptionMap [iter ->first ];
0254 cout << " " << setw (14) << iter ->first << " = " ;
0255 const string value = "'" + iter ->second + "'" ;
0256 cout << setw (14) << "" ;
0257 if (description .length ()) {
0258 cout << " - " << description ;
0259 }
0260 cout << endl << " " << value << endl ;
0261 }
0262
0263
0264 if (!m_integerVecMap .empty ()) {
0265 cout << endl << "Integer Vector options:" << endl ;
0266 }
0267 for (SIVecMapConstIter iter = m_integerVecMap .begin (); m_integerVecMap .end () != iter ; ++iter ) {
0268 const string &description = m_variableDescriptionMap [iter ->first ];
0269 cout << " " << setw (14) << iter ->first << " = " ;
0270 dumpSTL (iter ->second );
0271 cout << endl ;
0272 if (description .length ()) {
0273 cout << " - " << description ;
0274 }
0275 cout << endl ;
0276 }
0277
0278
0279 if (!m_doubleVecMap .empty ()) {
0280 cout << endl << "Double Vector options:" << endl ;
0281 }
0282 for (SDVecMapConstIter iter = m_doubleVecMap .begin (); m_doubleVecMap .end () != iter ; ++iter ) {
0283 const string &description = m_variableDescriptionMap [iter ->first ];
0284 cout << " " << setw (14) << iter ->first << " = " ;
0285 dumpSTL (iter ->second );
0286 cout << endl ;
0287 if (description .length ()) {
0288 cout << " - " << description ;
0289 }
0290 cout << endl ;
0291 }
0292
0293
0294 if (!m_stringVecMap .empty ()) {
0295 cout << endl << "String Vector options:" << endl ;
0296 } else {
0297 cout << endl ;
0298 }
0299 for (SSVecMapConstIter iter = m_stringVecMap .begin (); m_stringVecMap .end () != iter ; ++iter ) {
0300 const string &description = m_variableDescriptionMap [iter ->first ];
0301 cout << " " << setw (14) << iter ->first << " = " ;
0302 if (description .length ()) {
0303 cout << setw (14) << ""
0304 << " - " << description ;
0305 }
0306 cout << endl ;
0307 dumpSTLeachEndl (iter ->second , 8);
0308 }
0309
0310 cout << "------------------------------------------------------------------" << right << endl ;
0311 }
0312
0313 bool CommandLineParser ::_setVariableFromString (const string &arg , bool dontOverrideChange, int offset ) {
0314 string ::size_type where = arg .find_first_of('=' , offset + 1);
0315 string varname = arg .substr (offset , where - offset );
0316 string value = arg .substr (where + 1);
0317 lowercaseString (varname );
0318
0319 SBMapConstIter sbiter = m_variableModifiedMap .find (varname );
0320 if (m_variableModifiedMap .end () == sbiter ) {
0321
0322 return false ;
0323 }
0324
0325
0326 if (dontOverrideChange && _valueHasBeenModified (varname )) {
0327
0328 return true ;
0329 }
0330
0331 SIMapIter integerIter = m_integerMap .find (varname );
0332 if (m_integerMap .end () != integerIter ) {
0333
0334
0335 integerIter ->second = (int )atof (value .c_str ());
0336 m_variableModifiedMap [varname ] = true ;
0337 return true ;
0338 }
0339
0340 SDMapIter doubleIter = m_doubleMap .find (varname );
0341 if (m_doubleMap .end () != doubleIter ) {
0342
0343 doubleIter ->second = atof (value .c_str ());
0344 m_variableModifiedMap [varname ] = true ;
0345 return true ;
0346 }
0347
0348 SSMapIter stringIter = m_stringMap .find (varname );
0349 if (m_stringMap .end () != stringIter ) {
0350
0351 stringIter ->second = value ;
0352 m_variableModifiedMap [varname ] = true ;
0353 return true ;
0354 }
0355
0356 SBMapIter boolIter = m_boolMap .find (varname );
0357 if (m_boolMap .end () != boolIter ) {
0358
0359 boolIter ->second = 0 != atoi (value .c_str ());
0360 m_variableModifiedMap [varname ] = true ;
0361 return true ;
0362 }
0363
0364 SIVecMapIter integerVecIter = m_integerVecMap .find (varname );
0365 if (m_integerVecMap .end () != integerVecIter ) {
0366
0367 SVec words ;
0368 split (words , value , "," );
0369 for (SVecConstIter wordIter = words .begin (); words .end () != wordIter; ++wordIter) {
0370 integerVecIter ->second .push_back ((int )atof (wordIter->c_str ()));
0371 }
0372
0373
0374
0375 return true ;
0376 }
0377
0378 SDVecMapIter doubleVecIter = m_doubleVecMap .find (varname );
0379 if (m_doubleVecMap .end () != doubleVecIter ) {
0380
0381 SVec words ;
0382 split (words , value , "," );
0383 for (SVecConstIter wordIter = words .begin (); words .end () != wordIter; ++wordIter) {
0384 doubleVecIter ->second .push_back (atof (wordIter->c_str ()));
0385 }
0386
0387
0388
0389 return true ;
0390 }
0391
0392 SSVecMapIter stringVecIter = m_stringVecMap .find (varname );
0393 if (m_stringVecMap .end () != stringVecIter ) {
0394
0395 SVec words ;
0396 split (words , value , "," );
0397 for (SVecConstIter wordIter = words .begin (); words .end () != wordIter; ++wordIter) {
0398 stringVecIter ->second .push_back (*wordIter);
0399 }
0400
0401
0402
0403 return true ;
0404 }
0405
0406
0407 cerr << "CommandLineParser::SetVeriableFromString() Error: "
0408 << "Unknown variable and internal fault. Aborting." << endl ;
0409 assert (0);
0410 return false ;
0411 }
0412
0413 bool CommandLineParser ::_setVariablesFromFile (const string &filename ) {
0414 ifstream source (filename .c_str (), ios ::in );
0415 if (!source ) {
0416 cerr << "file " << filename << "could not be opened" << endl ;
0417 return false ;
0418 }
0419 string line ;
0420 while (getline (source , line )) {
0421
0422 string ::size_type where = line .find_first_not_of(kSpaces );
0423 if (string ::npos == where ) {
0424
0425 continue ;
0426 }
0427 char first = line .at (where );
0428 if ('-' != first ) {
0429 continue ;
0430 }
0431 where = line .find_first_not_of(kSpaces , where + 1);
0432 if (string ::npos == where ) {
0433
0434 continue ;
0435 }
0436
0437
0438
0439 string withspaces = line .substr (where );
0440 string nospaces ;
0441 for (int position = 0; position < (int )withspaces .length (); ++position ) {
0442 char ch = withspaces [position ];
0443 if ('#' == ch ) {
0444
0445 break ;
0446 } else if (' ' == ch || '\t' == ch ) {
0447 continue ;
0448 }
0449 nospaces += ch ;
0450 }
0451 if (!_setVariableFromString (nospaces , true )) {
0452 cerr << "Don't understand line" << endl
0453 << line << endl
0454 << "in options file '" << filename << "'. Aborting." << endl ;
0455 exit (0);
0456 }
0457 }
0458 return true ;
0459 }
0460
0461 bool CommandLineParser ::_runVariableCommandFromString (const string &arg ) {
0462 SVec equalWords ;
0463 split (equalWords , arg , "=" );
0464 if (2 != equalWords .size ()) {
0465 return false ;
0466 }
0467 SVec commandWords ;
0468 split (commandWords , equalWords .at (0), "_" );
0469 if (2 != commandWords .size ()) {
0470 return false ;
0471 }
0472 string &command = commandWords .at (1);
0473 lowercaseString (command );
0474 if (command != "load" && command != "clear" ) {
0475 return false ;
0476 }
0477 const string &key = commandWords .at (0);
0478 OptionType type = hasOption (key );
0479 if (type < kIntegerVector || type > kStringVector ) {
0480 cerr << "Command '" << command << "' only works on vectors." << endl ;
0481 return false ;
0482 }
0483
0484
0485
0486
0487 if ("clear" == command ) {
0488 if (kIntegerVector == type ) {
0489 integerVector (key ).clear ();
0490 } else if (kDoubleVector == type ) {
0491 doubleVector (key ).clear ();
0492 } else if (kStringVector == type ) {
0493 stringVector (key ).clear ();
0494 } else {
0495
0496
0497 assert (0);
0498 }
0499 return true ;
0500 }
0501
0502
0503
0504
0505 const string &filename = equalWords .at (1);
0506 ifstream source (filename .c_str (), ios ::in );
0507 if (!source ) {
0508 cerr << "file " << filename << "could not be opened" << endl ;
0509 return false ;
0510 }
0511 string line ;
0512 while (getline (source , line )) {
0513
0514 string ::size_type where = line .find_first_not_of(kSpaces );
0515 if (string ::npos == where ) {
0516
0517 continue ;
0518 }
0519
0520 line = line .substr (where );
0521
0522 where = line .find_last_not_of(kSpaces );
0523 if (line .length () - 1 != where ) {
0524 line = line .substr (0, where + 1);
0525 }
0526 if ('#' == line .at (0)) {
0527
0528 continue ;
0529 }
0530 if (kIntegerVector == type ) {
0531 integerVector (key ).push_back ((int )atof (line .c_str ()));
0532 } else if (kDoubleVector == type ) {
0533 doubleVector (key ).push_back (atof (line .c_str ()));
0534 } else if (kStringVector == type ) {
0535 stringVector (key ).push_back (line );
0536 } else {
0537
0538
0539 assert (0);
0540 }
0541 }
0542 return true ;
0543 }
0544
0545 void CommandLineParser ::_getSectionFiles (const SVec &inputList , SVec &outputList , int section , int totalSections) {
0546
0547 assert (section > 0 && section <= totalSections);
0548
0549
0550
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562
0563 int entries = (int )inputList .size ();
0564 int perSection = entries / totalSections;
0565 int extra = entries % totalSections;
0566 --section ;
0567 int current = perSection * section ;
0568 int num = perSection - 1;
0569 if (section < extra ) {
0570 current += section ;
0571 ++num ;
0572 } else {
0573 current += extra ;
0574 }
0575 outputList .clear ();
0576
0577
0578 for (int loop = current ; loop <= current + num ; ++loop ) {
0579 outputList .push_back (inputList .at (loop ));
0580 }
0581 }
0582
0583 void CommandLineParser ::_finishDefaultOptions (std ::string tag ) {
0584 if (!(m_optionsType & kEventContOpt )) {
0585
0586 return ;
0587 }
0588
0589
0590
0591 if (integerValue ("totalSections" )) {
0592
0593
0594 tag += Form ("_sec%03d" , integerValue ("section" ));
0595 SVec tempVec ;
0596 _getSectionFiles (stringVector ("inputFiles" ), tempVec , integerValue ("section" ), integerValue ("totalSections" ));
0597 stringVector ("inputFiles" ) = tempVec ;
0598 }
0599
0600
0601
0602
0603 const string &kStorePrepend = stringValue ("storePrepend" );
0604 if (kStorePrepend .length ()) {
0605 string match = "/store/" ;
0606 int matchLen = match .length ();
0607 SVec tempVec ;
0608 SVec ¤tFiles = stringVector ("inputFiles" );
0609 for (SVecConstIter iter = currentFiles .begin (); currentFiles .end () != iter ; ++iter ) {
0610 const string &filename = *iter ;
0611 if ((int )filename .length () > matchLen && filename .substr (0, matchLen ) == match ) {
0612 tempVec .push_back (kStorePrepend + filename );
0613 } else {
0614 tempVec .push_back (filename );
0615 }
0616 }
0617 currentFiles = tempVec ;
0618 }
0619
0620
0621
0622
0623
0624
0625 string outputFile = stringValue ("outputFile" );
0626 bool modifyOutputFile = (outputFile .length ());
0627 outputFile = removeEnding (outputFile , ".root" );
0628 outputFile += tag ;
0629 if (integerValue ("maxEvents" )) {
0630 outputFile += Form ("_maxevt%03d" , integerValue ("maxEvents" ));
0631 }
0632 if (integerValue ("jobID" ) >= 0) {
0633 outputFile += Form ("_jobID%03d" , integerValue ("jobID" ));
0634 }
0635 if (stringValue ("tag" ).length ()) {
0636 outputFile += "_" + stringValue ("tag" );
0637 }
0638
0639
0640
0641
0642 if (boolValue ("logName" )) {
0643 cout << outputFile << ".log" << endl ;
0644 exit (0);
0645 }
0646 outputFile += ".root" ;
0647 if (modifyOutputFile ) {
0648 stringValue ("outputFile" ) = outputFile ;
0649 }
0650
0651
0652
0653 if (m_printOptions ) {
0654 printOptionValues ();
0655 }
0656 }
0657
0658
0659 ostream &operator <<(ostream &o_stream, const CommandLineParser &rhs ) { return o_stream; }