12 #include <boost/program_options.hpp> 13 #include <boost/tokenizer.hpp> 14 #include <boost/regex.hpp> 15 #include <boost/swap.hpp> 16 #include <boost/algorithm/string/case_conv.hpp> 18 #include <stdair/ui/cmdline/SReadline.hpp> 20 #include <stdair/stdair_basic_types.hpp> 21 #include <stdair/stdair_json.hpp> 22 #include <stdair/basic/BasConst_General.hpp> 23 #include <stdair/basic/ProgressStatusSet.hpp> 24 #include <stdair/basic/DemandGenerationMethod.hpp> 25 #include <stdair/bom/EventStruct.hpp> 26 #include <stdair/bom/BookingRequestStruct.hpp> 27 #include <stdair/bom/BomDisplay.hpp> 28 #include <stdair/service/Logger.hpp> 53 "/rds01/demand05.csv");
58 const stdair::DemandGenerationMethod
60 stdair::DemandGenerationMethod::POI_PRO;
72 stdair::DEFAULT_RANDOM_SEED;
90 typedef std::vector<std::string> TokenList_T;
119 typedef boost::tokenizer<boost::char_separator<char> > Tokeniser_T;
122 const boost::char_separator<char> lSepatorList(
" .,;:|+-*/_=!@#$%`~^&(){}[]?'<>\"");
125 Tokeniser_T lTokens (iPhrase, lSepatorList);
126 for (Tokeniser_T::const_iterator tok_iter = lTokens.begin();
127 tok_iter != lTokens.end(); ++tok_iter) {
128 const std::string& lTerm = *tok_iter;
129 ioWordList.push_back (lTerm);
134 std::ostringstream oStr;
136 unsigned short idx = iWordList.size();
137 for (WordList_T::const_iterator itWord = iWordList.begin();
138 itWord != iWordList.end(); ++itWord, --idx) {
139 const std::string& lWord = *itWord;
152 template<
class T> std::ostream&
operator<< (std::ostream& os,
153 const std::vector<T>& v) {
154 std::copy (v.begin(), v.end(), std::ostream_iterator<T> (std::cout,
" "));
161 stdair::RandomSeed_T& ioRandomSeed,
162 stdair::Filename_T& ioInputFilename,
163 stdair::Filename_T& ioOutputFilename,
164 stdair::Filename_T& ioLogFilename,
165 stdair::DemandGenerationMethod& ioDemandGenerationMethod) {
168 char lDemandGenerationMethodChar;
174 boost::program_options::options_description
generic (
"Generic options");
175 generic.add_options()
176 (
"prefix",
"print installation prefix")
177 (
"version,v",
"print version string")
178 (
"help,h",
"produce help message");
182 boost::program_options::options_description config (
"Configuration");
185 "The sample BOM tree can be either built-in or parsed from an input file. That latter must then be given with the -i/--input option")
188 "Seed for the random generation")
189 (
"demandgeneration,G",
191 "Method used to generate the demand (i.e., the booking requests): Poisson Process (P) or Order Statistics (S)")
194 "(CSV) input file for the demand distributions")
197 "Filepath for the logs")
202 boost::program_options::options_description hidden (
"Hidden options");
205 boost::program_options::value< std::vector<std::string> >(),
206 "Show the copyright (license)");
208 boost::program_options::options_description cmdline_options;
209 cmdline_options.add(
generic).add(config).add(hidden);
211 boost::program_options::options_description config_file_options;
212 config_file_options.add(config).add(hidden);
214 boost::program_options::options_description visible (
"Allowed options");
215 visible.add(
generic).add(config);
217 boost::program_options::positional_options_description p;
218 p.add (
"copyright", -1);
220 boost::program_options::variables_map vm;
221 boost::program_options::
222 store (boost::program_options::command_line_parser (argc, argv).
223 options (cmdline_options).positional(p).run(), vm);
225 std::ifstream ifs (
"trademgen.cfg");
226 boost::program_options::store (parse_config_file (ifs, config_file_options),
228 boost::program_options::notify (vm);
230 if (vm.count (
"help")) {
231 std::cout << visible << std::endl;
235 if (vm.count (
"version")) {
240 if (vm.count (
"prefix")) {
241 std::cout <<
"Installation prefix: " <<
PREFIXDIR << std::endl;
245 if (vm.count (
"builtin")) {
248 const std::string isBuiltinStr = (ioIsBuiltin ==
true)?
"yes":
"no";
249 std::cout <<
"The BOM should be built-in? " << isBuiltinStr << std::endl;
251 if (ioIsBuiltin ==
false) {
254 if (vm.count (
"input")) {
255 ioInputFilename = vm[
"input"].as< std::string >();
256 std::cout <<
"Input filename is: " << ioInputFilename << std::endl;
261 std::cerr <<
"Either one among the -b/--builtin and -i/--input " 262 <<
"options must be specified" << std::endl;
266 if (vm.count (
"output")) {
267 ioOutputFilename = vm[
"output"].as< std::string >();
268 std::cout <<
"Output filename is: " << ioOutputFilename << std::endl;
271 if (vm.count (
"log")) {
272 ioLogFilename = vm[
"log"].as< std::string >();
273 std::cout <<
"Log filename is: " << ioLogFilename << std::endl;
276 if (vm.count (
"demandgeneration")) {
277 ioDemandGenerationMethod =
278 stdair::DemandGenerationMethod (lDemandGenerationMethodChar);
279 std::cout <<
"Date-time request generation method is: " 280 << ioDemandGenerationMethod.describe() << std::endl;
284 std::cout <<
"The random generation seed is: " << ioRandomSeed << std::endl;
290 void initReadline (swift::SReadline& ioInputReader) {
293 std::vector<std::string> Completers;
298 Completers.push_back (
"help");
299 Completers.push_back (
"list_event");
300 Completers.push_back (
"list_demand_stream");
301 Completers.push_back (
"reset");
302 Completers.push_back (
"generate_next_br");
303 Completers.push_back (
"generate_first_br");
304 Completers.push_back (
"generate_all_br");
305 Completers.push_back (
"next");
306 Completers.push_back (
"json_list");
307 Completers.push_back (
"quit");
311 ioInputReader.RegisterCompletions (Completers);
315 Command_T::Type_T extractCommand (TokenList_T& ioTokenList) {
316 Command_T::Type_T oCommandType = Command_T::LAST_VALUE;
319 if (ioTokenList.empty() ==
false) {
320 TokenList_T::iterator itTok = ioTokenList.begin();
321 std::string lCommand (*itTok);
322 boost::algorithm::to_lower (lCommand);
324 if (lCommand ==
"help") {
325 oCommandType = Command_T::HELP;
327 }
else if (lCommand ==
"list_event") {
328 oCommandType = Command_T::LIST_EVENT;
330 }
else if (lCommand ==
"list_demand_stream") {
331 oCommandType = Command_T::LIST_DEMAND_STREAM;
333 }
else if (lCommand ==
"reset") {
334 oCommandType = Command_T::RESET;
336 }
else if (lCommand ==
"delete_first") {
337 oCommandType = Command_T::NEXT;
339 }
else if (lCommand ==
"generate_first_br") {
340 oCommandType = Command_T::GENERATE_FIRST_BR;
342 }
else if (lCommand ==
"generate_next_br") {
343 oCommandType = Command_T::GENERATE_NEXT_BR;
345 }
else if (lCommand ==
"generate_all_br") {
346 oCommandType = Command_T::GENERATE_ALL_BR;
348 }
else if (lCommand ==
"json_list") {
349 oCommandType = Command_T::JSON_LIST;
351 }
else if (lCommand ==
"quit") {
352 oCommandType = Command_T::QUIT;
357 ioTokenList.erase (itTok);
360 oCommandType = Command_T::NOP;
367 std::string toString (
const TokenList_T& iTokenList) {
368 std::ostringstream oStr;
371 unsigned short idx = 0;
372 for (TokenList_T::const_iterator itTok = iTokenList.begin();
373 itTok != iTokenList.end(); ++itTok, ++idx) {
384 int main (
int argc,
char* argv[]) {
387 const unsigned int lHistorySize (100);
388 const std::string lHistoryFilename (
"trademgen.hist");
389 const std::string lHistoryBackupFilename (
"trademgen.hist.bak");
392 stdair::EventStruct lCurrentInteractiveEventStruct;
393 stdair::DateTime_T lCurrentInteractiveDateTime;
394 std::string lDefaultDemandStreamKey;
400 stdair::RandomSeed_T lRandomSeed;
403 stdair::Filename_T lInputFilename;
406 stdair::Filename_T lOutputFilename;
409 stdair::Filename_T lLogFilename;
412 stdair::DemandGenerationMethod
416 const int lOptionParserStatus =
418 lInputFilename, lOutputFilename, lLogFilename,
419 lDemandGenerationMethod);
426 std::ofstream logOutputFile;
428 logOutputFile.open (lLogFilename.c_str());
429 logOutputFile.clear();
432 const stdair::BasLogParams lLogParams (stdair::LOG::DEBUG, logOutputFile);
438 if (isBuiltin ==
true) {
440 trademgenService.buildSampleBom();
441 lDefaultDemandStreamKey =
"SIN-BKK 2010-Feb-08 Y";
446 trademgenService.parseAndLoad (lDemandFilePath);
447 lDefaultDemandStreamKey =
"SIN-BKK 2009-Feb-09 Y";
451 STDAIR_LOG_DEBUG (
"====================================================");
452 STDAIR_LOG_DEBUG (
"= Beginning of the interactive session =");
453 STDAIR_LOG_DEBUG (
"====================================================");
456 swift::SReadline lReader (lHistoryFilename, lHistorySize);
457 initReadline (lReader);
460 std::string lUserInput;
461 bool EndOfInput (
false);
462 Command_T::Type_T lCommandType (Command_T::NOP);
464 while (lCommandType != Command_T::QUIT && EndOfInput ==
false) {
471 std::ostringstream oPromptStr;
472 oPromptStr <<
"trademgen " <<
"> " ;
476 TokenList_T lTokenListByReadline;
477 lUserInput = lReader.GetLine (oPromptStr.str(), lTokenListByReadline,
481 lReader.SaveHistory (lHistoryBackupFilename);
485 std::cout << std::endl;
490 lCommandType = extractCommand (lTokenListByReadline);
492 switch (lCommandType) {
495 case Command_T::HELP: {
496 std::cout << std::endl;
497 std::cout <<
"Commands: " << std::endl;
498 std::cout <<
" help" <<
"\t\t\t" <<
"Display this help" << std::endl;
499 std::cout <<
" quit" <<
"\t\t\t" <<
"Quit the application" << std::endl;
500 std::cout <<
" list_event" <<
"\t\t" 501 <<
"List all the events in the queue" << std::endl;
502 std::cout <<
" list_demand_stream" <<
"\t" 503 <<
"List the streams used to generate demand" << std::endl;
504 std::cout <<
" reset" <<
"\t\t\t" <<
"Reset the service (including the " 505 <<
"event queue)" << std::endl;
506 std::cout <<
" generate_first_br" <<
"\t" <<
"Generate the first booking " 507 <<
"request for each demand stream and add it to the event queue" 509 std::cout <<
" generate_next_br" <<
"\t" <<
"Generate the next event for " 510 <<
"the specified demand stream and add it to the event queue" 511 <<
"\n\t\t\tFor instance:" 512 <<
"\n\t\t\t 'generate_next_br " << lDefaultDemandStreamKey
514 std::cout <<
" generate_all_br" <<
"\t" <<
"Generate all the events for " 515 <<
"the specified demand stream and add it to the event queue" 516 <<
"\n\t\t\tFor instance:" 517 <<
"\n\t\t\t 'generate_all_br " << lDefaultDemandStreamKey
519 std::cout <<
" delete_first" <<
"\t\t" 520 <<
"Pop the next event from the queue" 522 std::cout <<
" \nDebug Commands" << std::endl;
523 std::cout <<
" json_list" <<
"\t\t" 524 <<
"List events in the queue in a JSON format" 526 std::cout << std::endl;
531 case Command_T::QUIT: {
536 case Command_T::LIST_EVENT: {
538 std::cout <<
"List of events" << std::endl;
540 std::ostringstream oEventListStr;
541 oEventListStr << trademgenService.list ();
542 std::cout << oEventListStr.str() << std::endl;
543 STDAIR_LOG_DEBUG (oEventListStr.str());
550 case Command_T::LIST_DEMAND_STREAM: {
552 std::cout <<
"List of demand streams" << std::endl;
554 std::ostringstream oEventListStr;
555 oEventListStr << trademgenService.displayDemandStream ();
556 std::cout << oEventListStr.str() << std::endl;
557 STDAIR_LOG_DEBUG (oEventListStr.str());
564 case Command_T::RESET: {
566 std::cout <<
"Reset" << std::endl;
569 trademgenService.reset();
575 case Command_T::GENERATE_NEXT_BR: {
578 const stdair::DemandGeneratorKey_T lDemandStreamKey =
579 toString(lTokenListByReadline);
582 const bool hasDemandStream =
583 trademgenService.hasDemandStream(lDemandStreamKey);
585 if (hasDemandStream ==
false) {
587 std::ostringstream oNoDemandStreamStr;
588 oNoDemandStreamStr <<
"Wrong demand stream key: '" 589 << lDemandStreamKey <<
"'." 590 <<
"\nExisting demand streams are:\n" 591 << trademgenService.displayDemandStream();
592 std::cout << oNoDemandStreamStr.str() << std::endl;
593 STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
596 assert (hasDemandStream ==
true);
598 stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
599 const bool stillHavingRequestsToBeGenerated =
600 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
602 lDemandGenerationMethod);
603 if (stillHavingRequestsToBeGenerated ==
false) {
605 std::ostringstream oNoMoreEventToGenerateStr;
606 oNoMoreEventToGenerateStr <<
"No more events to generate for the demand " 607 <<
"stream: '" << lDemandStreamKey <<
"'.";
608 std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
609 STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
612 assert (stillHavingRequestsToBeGenerated ==
true);
614 trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
617 std::ostringstream oOneMoreEventGeneratedStr;
618 oOneMoreEventGeneratedStr <<
"One more event have been generated for the demand " 619 <<
"stream: '" << lDemandStreamKey <<
"'.";
620 std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
621 STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
627 case Command_T::GENERATE_FIRST_BR: {
629 std::cout <<
"Generate first requests" << std::endl;
632 trademgenService.generateFirstRequests (lDemandGenerationMethod);
638 case Command_T::GENERATE_ALL_BR: {
641 const stdair::DemandGeneratorKey_T lDemandStreamKey =
642 toString(lTokenListByReadline);
645 const bool hasDemandStream =
646 trademgenService.hasDemandStream(lDemandStreamKey);
648 if (hasDemandStream ==
false) {
650 std::ostringstream oNoDemandStreamStr;
651 oNoDemandStreamStr <<
"Wrong demand stream key: '" 652 << lDemandStreamKey <<
"'." 653 <<
"\nExisting demand streams are:\n" 654 << trademgenService.displayDemandStream();
655 std::cout << oNoDemandStreamStr.str() << std::endl;
656 STDAIR_LOG_DEBUG (oNoDemandStreamStr.str());
659 assert (hasDemandStream ==
true);
661 stdair::ProgressStatusSet lProgressStatusSet (stdair::EventType::BKG_REQ);
662 bool stillHavingRequestsToBeGenerated =
663 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
665 lDemandGenerationMethod);
668 if (stillHavingRequestsToBeGenerated ==
false) {
670 std::ostringstream oNoMoreEventToGenerateStr;
671 oNoMoreEventToGenerateStr <<
"No more events to generate for the demand " 672 <<
"stream: '" << lDemandStreamKey <<
"'.";
673 std::cout << oNoMoreEventToGenerateStr.str() << std::endl;
674 STDAIR_LOG_DEBUG (oNoMoreEventToGenerateStr.str());
677 assert (stillHavingRequestsToBeGenerated ==
true);
679 stdair::Count_T lNumberOfRequests = 0;
680 while (stillHavingRequestsToBeGenerated ==
true) {
682 trademgenService.generateNextRequest (lDemandStreamKey, lDemandGenerationMethod);
683 stillHavingRequestsToBeGenerated =
684 trademgenService.stillHavingRequestsToBeGenerated (lDemandStreamKey,
686 lDemandGenerationMethod);
691 std::ostringstream oOneMoreEventGeneratedStr;
692 oOneMoreEventGeneratedStr << lNumberOfRequests
693 <<
" more event(s) have been generated for the demand " 694 <<
"stream: '" << lDemandStreamKey <<
"'.";
695 std::cout << oOneMoreEventGeneratedStr.str() << std::endl;
696 STDAIR_LOG_DEBUG (oOneMoreEventGeneratedStr.str());
702 case Command_T::NEXT: {
704 std::cout <<
"Next" << std::endl;
706 if (trademgenService.isQueueDone() ==
true) {
709 std::ostringstream oEmptyQueueStr;
710 oEmptyQueueStr <<
"The event queue is empty: no event can be popped out.";
711 std::cout << oEmptyQueueStr.str() << std::endl;
712 STDAIR_LOG_DEBUG (oEmptyQueueStr.str());
720 trademgenService.popEvent (lCurrentInteractiveEventStruct);
723 std::ostringstream oEventStr;
724 oEventStr <<
"Poped event: '" 725 << lCurrentInteractiveEventStruct.describe() <<
"'.";
726 std::cout << oEventStr.str() << std::endl;
727 STDAIR_LOG_DEBUG (oEventStr.str());
734 case Command_T::JSON_LIST: {
736 std::cout <<
"JSON Event List" << std::endl;
738 std::ostringstream lMyCommandJSONstream;
739 lMyCommandJSONstream <<
"{\"event_list\":" 740 <<
"{ \"event_type\":\"" <<
"all" 744 const stdair::JSONString lJSONCommandString (lMyCommandJSONstream.str());
745 const std::string& lCSVEventListDump =
746 trademgenService.jsonHandler (lJSONCommandString);
749 std::cout << lCSVEventListDump << std::endl;
750 STDAIR_LOG_DEBUG (lCSVEventListDump);
756 case Command_T::NOP: {
760 case Command_T::LAST_VALUE:
763 std::ostringstream oStr;
764 oStr <<
"That command is not yet understood: '" << lUserInput
765 <<
"' => " << lTokenListByReadline;
766 STDAIR_LOG_DEBUG (oStr.str());
767 std::cout << oStr.str() << std::endl;
773 STDAIR_LOG_DEBUG (
"End of the session. Exiting.");
774 std::cout <<
"End of the session. Exiting." << std::endl;
777 logOutputFile.close();
const stdair::RandomSeed_T K_TRADEMGEN_DEFAULT_RANDOM_SEED
class holding the services related to Travel Demand Generation.
int main(int argc, char *argv[])
std::string createStringFromWordList(const WordList_T &iWordList)
const char K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD_CHAR
const int K_TRADEMGEN_EARLY_RETURN_STATUS
#define STDAIR_SAMPLE_DIR
const stdair::DemandGenerationMethod K_TRADEMGEN_DEFAULT_DEMAND_GENERATION_METHOD
std::ostream & operator<<(std::ostream &os, const std::vector< T > &v)
std::vector< std::string > WordList_T
const stdair::Filename_T K_TRADEMGEN_DEFAULT_LOG_FILENAME("trademgen_generateDemand.log")
int readConfiguration(int argc, char *argv[], bool &ioIsBuiltin, stdair::RandomSeed_T &ioRandomSeed, NbOfRuns_T &ioRandomRuns, stdair::Filename_T &ioInputFilename, stdair::Filename_T &ioOutputFilename, stdair::Filename_T &ioLogFilename, stdair::DemandGenerationMethod &ioDemandGenerationMethod)
const stdair::Filename_T K_TRADEMGEN_DEFAULT_INPUT_FILENAME(STDAIR_SAMPLE_DIR "/demand01.csv")
void tokeniseStringIntoWordList(const std::string &iPhrase, WordList_T &ioWordList)
const bool K_TRADEMGEN_DEFAULT_BUILT_IN_INPUT