3 #include <boost/regex.hpp> 5 #include <mysql++/mysql++.h> 155 time_duration runtimec(0, fDurationCalRun, 0);
156 time_duration runtimep(0, fDurationPedRun, 0);
157 time_duration repostime(0, fDurationRepos, 0);
158 time_duration mintime(1, 0, 0);
160 const ptime startsched(microsec_clock::local_time());
161 const ptime stopsched=startsched+years(1);
164 str <<
"Scheduling for the period from " << startsched <<
" to " << stopsched;
167 static const boost::regex expr(
"([[:word:].-]+):(.+)@([[:word:].-]+)(:([[:digit:]]+))?/([[:word:].-]+)");
175 if (!boost::regex_match(fDatabase, what, expr, boost::match_extra))
178 msg <<
"Regex to parse database '" << fDatabase <<
"' empty.";
186 msg <<
"Parsing database name failed: '" << fDatabase <<
"'";
191 const string user = what[1];
192 const string passwd = what[2];
193 const string server = what[3];
194 const string db = fDBName.empty() ? what[6] : fDBName;
195 const int port = stoi(what[5]);
197 ostringstream dbnamemsg;
198 dbnamemsg <<
"Scheduling started -> using database " << db <<
".";
199 T::Message(dbnamemsg);
202 str <<
"Connecting to '";
213 mysqlpp::Connection conn(db.c_str(), server.c_str(), user.c_str(), passwd.c_str(), port);
225 const mysqlpp::StoreQueryResult res =
226 conn.query(
"SELECT fObservationKEY, fStartTime, fStopTime, fDuration, fSourceName, fSourceKEY, fSplitFlag, fFluxWeight, fSlope, fFlux, fRightAscension, fDeclination, fObservationModeKEY, fObservationTypeKEY , fTelescopeSetupKEY FROM ObservationParameters LEFT JOIN Source USING(fSourceKEY) ORDER BY fStartTime").store();
239 str <<
"Found " << res.num_rows() <<
" Observation Parameter sets.";
243 vector<FixedObs> obsfixedlist;
244 vector<StdObs> obsstdlist;
245 vector<ScheduledObs> obslist;
246 vector<ScheduledRun> runlist;
253 cout <<
"Obs: <obskey> <sourcename>(<sourcekey>, <fluxweight>) from <starttime> to <stoptime>" << endl;
254 for (vector<mysqlpp::Row>::const_iterator v=res.begin(); v<res.end(); v++)
256 cout <<
" Obs: " << (*v)[0].c_str() <<
" " << (*v)[4].c_str() <<
"(" << (*v)[5].c_str() << flush;
257 cout <<
", " << (*v)[7].c_str() <<
")" << flush;
258 cout <<
" from " << (*v)[1].c_str() <<
" to " << (*v)[2].c_str() << endl;
278 t1 << (*v)[1].c_str();
279 t2 << (*v)[2].c_str();
280 t3 << (*v)[3].c_str();
286 const time_period
period(olist[counter].
start, olist[counter].stop);
291 if (!(*v)[0].is_null())
293 if (!(*v)[12].is_null())
295 if (!(*v)[13].is_null())
297 if (!(*v)[14].is_null())
299 if (!(*v)[6].is_null())
301 if (!(*v)[7].is_null())
305 if (!(*v)[8].is_null())
307 if (!(*v)[9].is_null())
309 if (!(*v)[10].is_null())
311 if (!(*v)[11].is_null())
351 if (!(olist[counter].stop.is_not_a_date_time()
353 && olist[counter].fluxweight==0
356 obsfixedlist.resize(counter2+1);
365 obsfixedlist[counter2].ra=olist[
counter].
ra;
366 obsfixedlist[counter2].dec=olist[
counter].
dec;
371 if (olist[counter].stop.is_not_a_date_time()
376 obsstdlist.resize(counter3+1);
386 obsstdlist[counter3].ra_std=olist[
counter].
ra;
387 obsstdlist[counter3].dec_std=olist[
counter].
dec;
393 ostringstream fixedobsmsg;
394 fixedobsmsg << obsfixedlist.size() <<
" fixed observations found. ";
395 T::Message(fixedobsmsg);
396 cout << obsfixedlist.size() <<
" fixed observations found. " << endl;
398 ostringstream stdobsmsg;
399 stdobsmsg << obsstdlist.size() <<
" standard observations found. ";
400 T::Message(stdobsmsg);
401 cout << obsstdlist.size() <<
" standard observations found. " << endl;
413 ptime finalobsfixedstart;
414 ptime finalobsfixedstop;
415 time_duration delta0(0,0,0);
417 cout <<
"Fixed Observations: " << endl;
418 for (
struct vector<FixedObs>::const_iterator vobs=obsfixedlist.begin(); vobs!=obsfixedlist.end(); vobs++)
420 if (obsfixedlist[counter2].
start < startsched
421 || obsfixedlist[counter2].stop > stopsched)
423 ostringstream skipfixedobsmsg;
424 skipfixedobsmsg <<
"Skip 1 fixed observation (obskey ";
425 skipfixedobsmsg << obsfixedlist[counter2].obskey;
426 skipfixedobsmsg <<
") as it is out of scheduling time range.";
427 T::Message(skipfixedobsmsg);
435 time_duration delta1=delta0;
436 time_duration delta2=delta0;
438 finalobsfixedstart=obsfixedlist[counter2].start;
439 finalobsfixedstop=obsfixedlist[counter2].stop;
441 for (
struct vector<FixedObs>::const_iterator vobs5=obsfixedlist.begin(); vobs5!=obsfixedlist.end(); vobs5++)
443 if (vobs5->start < obsfixedlist[counter2].stop
444 && obsfixedlist[counter2].stop <= vobs5->stop
445 && obsfixedlist[counter2].start <= vobs5->start
446 && counter2!=counter3)
448 delta1=(obsfixedlist[counter2].stop-vobs5->start)/2;
449 finalobsfixedstop=obsfixedlist[counter2].stop-delta1;
451 ostringstream warndelta1;
452 warndelta1 <<
"Overlap between two fixed observations (";
453 warndelta1 << obsfixedlist[counter2].obskey <<
" ";
454 warndelta1 << vobs5->obskey <<
"). The stoptime of ";
455 warndelta1 << obsfixedlist[counter2].obskey <<
" has been changed.";
458 if (vobs5->start <= obsfixedlist[counter2].start
459 && obsfixedlist[counter2].start < vobs5->stop
460 && obsfixedlist[counter2].stop >= vobs5->stop
461 && counter2!=counter3)
463 delta2=(vobs5->stop-obsfixedlist[counter2].start)/2;
464 finalobsfixedstart=obsfixedlist[counter2].start+delta2;
466 ostringstream warndelta2;
467 warndelta2 <<
"Overlap between two fixed observations (";
468 warndelta2 << obsfixedlist[counter2].obskey <<
" ";
469 warndelta2 << vobs5->obskey <<
"). The starttime of ";
470 warndelta2 << obsfixedlist[counter2].obskey <<
" has been changed.";
477 const int num=counter2-skipcounter;
478 obslist.resize(num+1);
479 obslist[num].obsstart=finalobsfixedstart;
480 obslist[num].obsstop=finalobsfixedstop;
481 obslist[num].sourcename_obs=obsfixedlist[counter2].sourcename;
482 obslist[num].obsmode_obs=obsfixedlist[counter2].obsmode;
483 obslist[num].obstype_obs=obsfixedlist[counter2].obstype;
484 obslist[num].telsetup_obs=obsfixedlist[counter2].telsetup;
485 obslist[num].sourcekey_obs=obsfixedlist[counter2].sourcekey;
486 obslist[num].obskey_obs=obsfixedlist[counter2].obskey;
489 cout <<
" " << vobs->sourcename <<
" " << vobs->start;
490 cout <<
" - " << vobs->stop << endl;
492 ostringstream obsmsg;
493 obsmsg <<
"Added " << obslist.size() <<
" fixed observations to ScheduledObs. ";
495 cout <<
"Added " << obslist.size() <<
" fixed observations to ScheduledObs. " << endl;
497 for (
int i=0;
i<(int)obsstdlist.size();
i++)
499 for (
int j=0; j<(int)obsstdlist.size(); j++)
501 if (obsstdlist[
i].sourcekey_std == obsstdlist[j].sourcekey_std &&
i!=j)
503 cout <<
"One double sourcekey in std observations: " << obsstdlist[j].sourcekey_std << endl;
504 ostringstream errdoublestd;
505 errdoublestd <<
"One double sourcekey in std observations: " << obsstdlist[j].sourcekey_std <<
" (" << obsstdlist[j].sourcename_std <<
").";
507 T::Message(
"Scheduling stopped.");
508 return error ? T::kSM_Error : T::kSM_Ready;
522 cout <<
"Standard Observations: " << endl;
523 for (
struct vector<StdObs>::const_iterator vobs2=obsstdlist.begin(); vobs2!=obsstdlist.end(); vobs2++)
525 cout <<
" " << vobs2->sourcename_std << endl;
532 for (
struct vector<ScheduledObs>::const_iterator vobs3=obslist.begin(); vobs3!=obslist.end(); vobs3++)
534 runlist.resize(counter2+1);
535 runlist[counter2].runstart=obslist[counter2].obsstart;
536 runlist[counter2].runstop=obslist[counter2].obsstop;
537 runlist[counter2].sourcename_run=obslist[counter2].sourcename_obs;
538 runlist[counter2].obsmode_run=obslist[counter2].obsmode_obs;
539 runlist[counter2].obstype_run=obslist[counter2].obstype_obs;
540 runlist[counter2].telsetup_run=obslist[counter2].telsetup_obs;
541 runlist[counter2].sourcekey_run=obslist[counter2].sourcekey_obs;
542 runlist[counter2].obskey_run=obslist[counter2].obskey_obs;
548 const mysqlpp::SimpleResult res0 =
549 conn.query(
"DELETE FROM ScheduledRun").execute();
566 ptime finalstarttime;
568 for (
struct vector<ScheduledRun>::const_iterator vobs4=runlist.begin(); vobs4!=runlist.end(); vobs4++)
570 for (
int i=2;
i<5;
i++)
575 finalstarttime=runlist[counter3].runstart+repostime+runtimec+runtimep;
576 finalstoptime=runlist[counter3].runstop;
579 finalstarttime=runlist[counter3].runstart+repostime;
580 finalstoptime=runlist[counter3].runstart+runtimep+repostime;
583 finalstarttime=runlist[counter3].runstart+runtimep+repostime;
584 finalstoptime=runlist[counter3].runstart+repostime+runtimep+runtimec;
589 q1 <<
"INSERT ScheduledRun set fStartTime='" <<
Time::sql << finalstarttime;
590 q1 <<
"', fStopTime='" <<
Time::sql << finalstoptime;
591 q1 <<
"', fSourceKEY='" << (*vobs4).sourcekey_run;
592 q1 <<
"', fObservationKEY='" << (*vobs4).obskey_run;
593 q1 <<
"', fRunTypeKEY='" <<
i;
594 q1 <<
"', fTelescopeSetupKEY='" << (*vobs4).telsetup_run;
595 q1 <<
"', fObservationTypeKEY='" << (*vobs4).obstype_run;
596 q1 <<
"', fObservationModeKEY='" << (*vobs4).obsmode_run;
601 const mysqlpp::SimpleResult res1 = conn.query(q1.str()).
execute();
616 ostringstream insertmsg;
617 insertmsg <<
"Inserted " << insertcount <<
" runs into the DB.";
618 T::Message(insertmsg);
620 T::Message(
"Scheduling done.");
643 AutoScheduler(ostream &out=cout) : T(out,
"SCHEDULER"), fNextIsPreview(true), fDBName(
"")
645 AddStateName(kSM_Scheduling,
"Scheduling",
"Scheduling in progress.");
647 AddEvent(kSM_Scheduling,
"SCHEDULE",
"C", T::kSM_Ready)
648 (
"FIXME FIXME FIXME (explanation for the command)" 649 "|database[string]:FIXME FIXME FIMXE (meaning and format)");
651 AddEvent(T::kSM_Ready,
"RESET", T::kSM_Error)
652 (
"Reset command to get out of the error state");
656 T::PrintListOfEvents();
661 switch (T::GetCurrentState())
666 return Schedule() ? T::kSM_Error : T::kSM_Ready;
668 catch (
const mysqlpp::Exception &e)
670 T::Error(
string(
"MySQL: ")+e.what());
678 return T::GetCurrentState();
683 switch (evt.GetTargetState())
691 return evt.GetTargetState();
696 fDatabase = conf.
Get<
string>(
"schedule-database");
697 fDurationCalRun = conf.
Get<
int>(
"duration-cal-run");
698 fDurationPedRun = conf.
Get<
int>(
"duration-ped-run");
699 fDurationRepos = conf.
Get<
int>(
"duration-repos");
701 if (!conf.
Has(
"schedule"))
704 fDBName = conf.
Get<
string>(
"schedule");
714 template<
class T,
class S>
717 return Main::execute<T, AutoScheduler<S>>(conf);
722 po::options_description control(
"Scheduler options");
723 control.add_options()
724 (
"no-dim",
po_switch(),
"Disable dim services")
725 (
"schedule-database", var<string>()
726 #if BOOST_VERSION >= 104200 729 ,
"Database link as in\n\tuser:password@server[:port]/database\nOverwrites options from the default configuration file.")
730 (
"schedule", var<string>(),
"")
731 (
"mintime", var<int>(),
"minimum observation time")
732 (
"duration-cal-run", var<int>()
733 #if BOOST_VERSION >= 104200 736 ,
"duration of calibration run [min]")
737 (
"duration-ped-run", var<int>()
738 #if BOOST_VERSION >= 104200 741 ,
"duration of pedestal run [min]")
742 (
"duration-repos", var<int>()
743 #if BOOST_VERSION >= 104200 746 ,
"duration of repositioning [min]")
749 po::positional_options_description p;
750 p.add(
"schedule", 1);
759 "The scheduler... TEXT MISSING\n" 761 "The default is that the program is started without user intercation. " 762 "All actions are supposed to arrive as DimCommands. Using the -c " 763 "option, a local shell can be initialized. With h or help a short " 764 "help message about the usuage can be brought to the screen.\n" 766 "Usage: scheduler [-c type] [OPTIONS] <schedule-database>\n" 767 " or: scheduler [OPTIONS] <schedule-database>\n";
777 int main(
int argc,
const char* argv[])
784 po::variables_map vm;
787 vm = conf.
Parse(argc, argv);
789 #if BOOST_VERSION > 104000 790 catch (po::multiple_occurrences &e)
792 cerr <<
"Program options invalid due to: " << e.what() <<
" of '" << e.get_option_name() <<
"'." << endl;
798 cerr <<
"Program options invalid due to: " << e.what() << endl;
805 if (!conf.
Has(
"console"))
807 if (conf.
Get<
bool>(
"no-dim"))
808 return RunShell<LocalStream, StateMachine>(conf);
810 return RunShell<LocalStream, StateMachineDim>(conf);
813 if (conf.
Get<
bool>(
"no-dim"))
815 if (conf.
Get<
int>(
"console")==0)
816 return RunShell<LocalShell, StateMachine>(conf);
818 return RunShell<LocalConsole, StateMachine>(conf);
822 if (conf.
Get<
int>(
"console")==0)
823 return RunShell<LocalShell, StateMachineDim>(conf);
825 return RunShell<LocalConsole, StateMachineDim>(conf);
AutoScheduler(ostream &out=cout)
void SetupConfiguration(Configuration &conf)
static const _time_format sql
set to format to the iso standard
const char * GetText() const
void SetupConfiguration(Configuration &conf)
void SetPrintUsage(const std::function< void(void)> &func)
T Get(const std::string &var)
po::typed_value< bool > * po_switch()
int RunShell(Configuration &conf)
void SetArgumentPositions(const po::positional_options_description &desc)
time_duration duration_db
bool Has(const std::string &var)
void AddOptions(const po::options_description &opt, bool visible=true)
size_t GetSize() const
Return the size of the data.
Commandline parsing, resource file parsing and database access.
int execute(Configuration &conf, bool dummy=false)
Concerete implementation of an EventImp stroring name, format, data and time.
int Transition(const Event &evt)
const po::variables_map & Parse(int argc, const char **argv, const std::function< void()> &func=std::function< void()>())
int EvalOptions(Configuration &conf)
int main(int argc, const char *argv[])