FACT++  1.0
template<class T >
int AutoScheduler< T >::Schedule ( )
inline

Definition at line 151 of file scheduler.cc.

References counter, Debug, AutoScheduler< T >::ObservationParameters::dec, AutoScheduler< T >::ObservationParameters::duration_db, Error(), Main::execute(), AutoScheduler< T >::ObservationParameters::flux, AutoScheduler< T >::ObservationParameters::fluxweight, i, AutoScheduler< T >::ObservationParameters::obskey, AutoScheduler< T >::ObservationParameters::obsmode, AutoScheduler< T >::ObservationParameters::obstype, period, AutoScheduler< T >::ObservationParameters::ra, AutoScheduler< T >::ObservationParameters::slope, AutoScheduler< T >::ObservationParameters::sourcekey, AutoScheduler< T >::ObservationParameters::sourcename, AutoScheduler< T >::ObservationParameters::splitflag, Time::sql, AutoScheduler< T >::ObservationParameters::start, start(), AutoScheduler< T >::ObservationParameters::stop, str, and AutoScheduler< T >::ObservationParameters::telsetup.

152  {
153  bool error = false;
154 
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);
159 
160  const ptime startsched(microsec_clock::local_time());
161  const ptime stopsched=startsched+years(1);
162 
163  ostringstream str;
164  str << "Scheduling for the period from " << startsched << " to " << stopsched;
165  T::Message(str);
166 
167  static const boost::regex expr("([[:word:].-]+):(.+)@([[:word:].-]+)(:([[:digit:]]+))?/([[:word:].-]+)");
168  // 2: user
169  // 4: pass
170  // 5: server
171  // 7: port
172  // 9: db
173 
174  boost::smatch what;
175  if (!boost::regex_match(fDatabase, what, expr, boost::match_extra))
176  {
177  ostringstream msg;
178  msg << "Regex to parse database '" << fDatabase << "' empty.";
179  T::Error(msg);
180  return T::kSM_Error;
181  }
182 
183  if (what.size()!=7)
184  {
185  ostringstream msg;
186  msg << "Parsing database name failed: '" << fDatabase << "'";
187  T::Error(msg);
188  return T::kSM_Error;
189  }
190 
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]);
196 
197  ostringstream dbnamemsg;
198  dbnamemsg << "Scheduling started -> using database " << db << ".";
199  T::Message(dbnamemsg);
200 
201  str.str("");
202  str << "Connecting to '";
203  if (!user.empty())
204  str << user << "@";
205  str << server;
206  if (port)
207  str << ":" << port;
208  if (!db.empty())
209  str << "/" << db;
210  str << "'";
211  T::Info(str);
212 
213  mysqlpp::Connection conn(db.c_str(), server.c_str(), user.c_str(), passwd.c_str(), port);
214  /* throws exceptions
215  if (!conn.connected())
216  {
217  ostringstream msg;
218  msg << "MySQL connection error: " << conn.error();
219  T::Error(msg);
220  return T::kSM_Error;
221  }*/
222 
223  // get observation parameters from DB
224  // maybe order by priority?
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();
227  // FIXME: Maybe we have to check for a successfull
228  // query but an empty result
229  /* thorws exceptions?
230  if (!res)
231  {
232  ostringstream msg;
233  msg << "MySQL query failed: " << query.error();
234  T::Error(msg);
235  return T::kSM_Error;
236  }*/
237 
238  str.str("");
239  str << "Found " << res.num_rows() << " Observation Parameter sets.";
240  T::Debug(str);
241 
242  ObservationParameters olist[res.num_rows()];
243  vector<FixedObs> obsfixedlist;
244  vector<StdObs> obsstdlist;
245  vector<ScheduledObs> obslist;
246  vector<ScheduledRun> runlist;
247 
248  // loop over observation parameters from DB
249  // fill these parameters into FixedObs and StdObs
250  int counter=0;
251  int counter2=0;
252  int counter3=0;
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++)
255  {
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;
259 
260  //0: obskey
261  //1: startime
262  //2: stoptime
263  //3: duration
264  //4: sourcename
265  //5: sourcekey
266  //6: splitflag
267  //7: fluxweight
268  //8: slope
269  //9: flux
270  //10: ra
271  //11: dec
272  //12: obsmode
273  //13: obstype
274  //14: telsetup
275  stringstream t1;
276  stringstream t2;
277  stringstream t3;
278  t1 << (*v)[1].c_str();
279  t2 << (*v)[2].c_str();
280  t3 << (*v)[3].c_str();
281 
282  //boost::posix_time::time_duration mintime(0,conf.Get<int>("mintime"), 0);
283  t1 >> Time::sql >> olist[counter].start;
284  t2 >> Time::sql >> olist[counter].stop;
285  t3 >> olist[counter].duration_db;
286  const time_period period(olist[counter].start, olist[counter].stop);
287 
288  olist[counter].sourcename=(*v)[4].c_str();
289  olist[counter].sourcekey=(*v)[5];
290 
291  if (!(*v)[0].is_null())
292  olist[counter].obskey=(*v)[0];
293  if (!(*v)[12].is_null())
294  olist[counter].obsmode=(*v)[12];
295  if (!(*v)[13].is_null())
296  olist[counter].obstype=(*v)[13];
297  if (!(*v)[14].is_null())
298  olist[counter].telsetup=(*v)[14];
299  if (!(*v)[6].is_null())
300  olist[counter].splitflag=(*v)[6];
301  if (!(*v)[7].is_null())
302  olist[counter].fluxweight=(*v)[7];
303  else
304  olist[counter].fluxweight=0;//set fluxweight to 0 for check below
305  if (!(*v)[8].is_null())
306  olist[counter].slope=(*v)[8];
307  if (!(*v)[9].is_null())
308  olist[counter].flux=(*v)[9];
309  if (!(*v)[10].is_null())
310  olist[counter].ra=(*v)[10];
311  if (!(*v)[11].is_null())
312  olist[counter].dec=(*v)[11];
313 
314  // time_duration cannot be used, as only up to 99 hours are handeled
315  // const time_duration duration = period.length();
316 
317  /*
318  if (olist[counter].stoptime < olist[counter].starttime+mintime)
319  cout << " ====> WARN: Observation too short. " << endl;
320 
321  if (olist[counter].starttime.is_not_a_date_time())
322  cout << " WARN: starttime not a date_time. " << endl;
323  else
324  cout << " start: " << Time::sql << olist[counter].starttime << endl;
325  if (olist[counter].stoptime.is_not_a_date_time())
326  cout << " WARN: stoptime not a date_time. " << endl;
327  else
328  cout << " stop: " << Time::sql << olist[counter].stoptime << endl;
329  if (!(olist[counter].starttime.is_not_a_date_time() || olist[counter].stoptime.is_not_a_date_time()))
330  cout << " diff: " << period << endl;
331  if (olist[counter].stoptime < olist[counter].starttime)
332  cout << " ====> WARN: stop time (" << olist[counter].stoptime << ") < start time (" << olist[counter].starttime << "). " << endl;
333  cout << "diff: " << duration << flush;
334  cout << "dur_db: " << olist[counter].duration_db << endl;
335  */
336 
337  // always filled: obstype
338  //
339  // fixed observations:
340  // filled: starttime, stoptime
341  // not filled: fluxweight
342  // maybe filled: obsmode, telsetup, source (not filled for FixedSlotObs)
343  // maybe filled: duration (filled for FloatingObs and FloatingSplittedObs)
344  // maybe filled: splitflag (filled for FloatingSplittedObs)
345  //
346  // std observations:
347  // filled: fluxweight, telsetup, obsmore, source
348  // not filled: starttime, stoptime, duration
349 
350  // fixed observations
351  if (!(olist[counter].stop.is_not_a_date_time()
352  && olist[counter].start.is_not_a_date_time())
353  && olist[counter].fluxweight==0
354  )
355  {
356  obsfixedlist.resize(counter2+1);
357  obsfixedlist[counter2].start=olist[counter].start;
358  obsfixedlist[counter2].stop=olist[counter].stop;
359  obsfixedlist[counter2].sourcename=olist[counter].sourcename;
360  obsfixedlist[counter2].obskey=olist[counter].obskey;
361  obsfixedlist[counter2].obstype=olist[counter].obstype;
362  obsfixedlist[counter2].obsmode=olist[counter].obsmode;
363  obsfixedlist[counter2].telsetup=olist[counter].telsetup;
364  obsfixedlist[counter2].sourcekey=olist[counter].sourcekey;
365  obsfixedlist[counter2].ra=olist[counter].ra;
366  obsfixedlist[counter2].dec=olist[counter].dec;
367  counter2++;
368  }
369 
370  // std obs
371  if (olist[counter].stop.is_not_a_date_time()
372  && olist[counter].start.is_not_a_date_time()
373  && olist[counter].fluxweight>0
374  )
375  {
376  obsstdlist.resize(counter3+1);
377  obsstdlist[counter3].sourcename_std=olist[counter].sourcename;
378  obsstdlist[counter3].obskey_std=olist[counter].obskey;
379  obsstdlist[counter3].obsmode_std=olist[counter].obsmode;
380  obsstdlist[counter3].obstype_std=olist[counter].obstype;
381  obsstdlist[counter3].telsetup_std=olist[counter].telsetup;
382  obsstdlist[counter3].sourcekey_std=olist[counter].sourcekey;
383  obsstdlist[counter3].fluxweight_std=olist[counter].fluxweight;
384  obsstdlist[counter3].flux_std=olist[counter].flux;
385  obsstdlist[counter3].slope_std=olist[counter].slope;
386  obsstdlist[counter3].ra_std=olist[counter].ra;
387  obsstdlist[counter3].dec_std=olist[counter].dec;
388  counter3++;
389  }
390 
391  counter++;
392  }
393  ostringstream fixedobsmsg;
394  fixedobsmsg << obsfixedlist.size() << " fixed observations found. ";
395  T::Message(fixedobsmsg);
396  cout << obsfixedlist.size() << " fixed observations found. " << endl;
397 
398  ostringstream stdobsmsg;
399  stdobsmsg << obsstdlist.size() << " standard observations found. ";
400  T::Message(stdobsmsg);
401  cout << obsstdlist.size() << " standard observations found. " << endl;
402 
403  // loop to add the fixed observations to the ScheduledObs list
404  // performed checks:
405  // * overlap of fixed observations: the overlap is split half-half
406  // * check for scheduling time range: only take into account fixed obs within the range
407  // missing checks and evaluation
408  // * check for mintime (pb with overlap checks)
409  // * check for sun
410  // * check for moon
411  counter2=0;
412  int skipcounter=0;
413  ptime finalobsfixedstart;
414  ptime finalobsfixedstop;
415  time_duration delta0(0,0,0);
416 
417  cout << "Fixed Observations: " << endl;
418  for (struct vector<FixedObs>::const_iterator vobs=obsfixedlist.begin(); vobs!=obsfixedlist.end(); vobs++)
419  {
420  if (obsfixedlist[counter2].start < startsched
421  || obsfixedlist[counter2].stop > stopsched)
422  {
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);
428 
429  counter2++;
430  skipcounter++;
431  continue;
432  }
433  counter3=0;
434 
435  time_duration delta1=delta0;
436  time_duration delta2=delta0;
437 
438  finalobsfixedstart=obsfixedlist[counter2].start;
439  finalobsfixedstop=obsfixedlist[counter2].stop;
440 
441  for (struct vector<FixedObs>::const_iterator vobs5=obsfixedlist.begin(); vobs5!=obsfixedlist.end(); vobs5++)
442  {
443  if (vobs5->start < obsfixedlist[counter2].stop
444  && obsfixedlist[counter2].stop <= vobs5->stop
445  && obsfixedlist[counter2].start <= vobs5->start
446  && counter2!=counter3)
447  {
448  delta1=(obsfixedlist[counter2].stop-vobs5->start)/2;
449  finalobsfixedstop=obsfixedlist[counter2].stop-delta1;
450 
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.";
456  T::Warn(warndelta1);
457  }
458  if (vobs5->start <= obsfixedlist[counter2].start
459  && obsfixedlist[counter2].start < vobs5->stop
460  && obsfixedlist[counter2].stop >= vobs5->stop
461  && counter2!=counter3)
462  {
463  delta2=(vobs5->stop-obsfixedlist[counter2].start)/2;
464  finalobsfixedstart=obsfixedlist[counter2].start+delta2;
465 
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.";
471 
472  T::Warn(warndelta2);
473  }
474  counter3++;
475  }
476 
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;
487  counter2++;
488 
489  cout << " " << vobs->sourcename << " " << vobs->start;
490  cout << " - " << vobs->stop << endl;
491  }
492  ostringstream obsmsg;
493  obsmsg << "Added " << obslist.size() << " fixed observations to ScheduledObs. ";
494  T::Message(obsmsg);
495  cout << "Added " << obslist.size() << " fixed observations to ScheduledObs. " << endl;
496 
497  for (int i=0; i<(int)obsstdlist.size(); i++)
498  {
499  for (int j=0; j<(int)obsstdlist.size(); j++)
500  {
501  if (obsstdlist[i].sourcekey_std == obsstdlist[j].sourcekey_std && i!=j)
502  {
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 << ").";
506  T::Error(errdoublestd);
507  T::Message("Scheduling stopped.");
508  return error ? T::kSM_Error : T::kSM_Ready;
509  }
510  }
511  }
512 
513  // loop over nights
514  // calculate sunset and sunrise
515  // check if there is already scheduled obs in that night
516  //
517 
518  // in this loop the standard observations shall be
519  // checked, evaluated
520  // the observation times shall be calculated
521  // and the observations added to the ScheduledObs list
522  cout << "Standard Observations: " << endl;
523  for (struct vector<StdObs>::const_iterator vobs2=obsstdlist.begin(); vobs2!=obsstdlist.end(); vobs2++)
524  {
525  cout << " " << vobs2->sourcename_std << endl;
526  }
527 
528  // in this loop the ScheduledRuns are filled
529  // (only data runs -> no runtype yet)
530  // might be merged with next loop
531  counter2=0;
532  for (struct vector<ScheduledObs>::const_iterator vobs3=obslist.begin(); vobs3!=obslist.end(); vobs3++)
533  {
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;
543  counter2++;
544  //cout << (*vobs3).sourcename_obs << endl;
545  }
546 
547  //delete old scheduled runs from the DB
548  const mysqlpp::SimpleResult res0 =
549  conn.query("DELETE FROM ScheduledRun").execute();
550  // FIXME: Maybe we have to check for a successfull
551  // query but an empty result
552  /* throws exceptions
553  if (!res0)
554  {
555  ostringstream msg;
556  msg << "MySQL query failed: " << query0.error();
557  T::Error(msg);
558  return T::kSM_Error;
559  }*/
560 
561  // in this loop the ScheduledRuns are inserted to the DB
562  // before the runtimes are adapted according to
563  // duration of P-Run, C-Run and repositioning
564  counter3=0;
565  int insertcount=0;
566  ptime finalstarttime;
567  ptime finalstoptime;
568  for (struct vector<ScheduledRun>::const_iterator vobs4=runlist.begin(); vobs4!=runlist.end(); vobs4++)
569  {
570  for (int i=2; i<5; i++)
571  {
572  switch(i)
573  {
574  case 2:
575  finalstarttime=runlist[counter3].runstart+repostime+runtimec+runtimep;
576  finalstoptime=runlist[counter3].runstop;
577  break;
578  case 3:
579  finalstarttime=runlist[counter3].runstart+repostime;
580  finalstoptime=runlist[counter3].runstart+runtimep+repostime;
581  break;
582  case 4:
583  finalstarttime=runlist[counter3].runstart+runtimep+repostime;
584  finalstoptime=runlist[counter3].runstart+repostime+runtimep+runtimec;
585  break;
586  }
587  ostringstream q1;
588  //cout << (*vobs4).sourcename_run << endl;
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;
597  q1 << "'";
598 
599  //cout << "executing query: " << q1.str() << endl;
600 
601  const mysqlpp::SimpleResult res1 = conn.query(q1.str()).execute();
602  // FIXME: Maybe we have to check for a successfull
603  // query but an empty result
604  /* throws exceptions
605  if (!res1)
606  {
607  ostringstream msg;
608  msg << "MySQL query failed: " << query1.error();
609  T::Error(str);
610  return T::kSM_Error;
611  }*/
612  insertcount++;
613  }
614  counter3++;
615  }
616  ostringstream insertmsg;
617  insertmsg << "Inserted " << insertcount << " runs into the DB.";
618  T::Message(insertmsg);
619  //usleep(3000000);
620  T::Message("Scheduling done.");
621 
622  return error;
623  }
int start(int initState)
Definition: feeserver.c:1740
int fDurationRepos
Definition: scheduler.cc:149
float period
Definition: HeadersSQM.h:92
string fDatabase
Definition: scheduler.cc:145
static const _time_format sql
set to format to the iso standard
Definition: Time.h:42
int fDurationPedRun
Definition: scheduler.cc:148
int i
Definition: db_dim_client.c:21
char str[80]
Definition: test_client.c:7
int execute(Configuration &conf, bool dummy=false)
Definition: Main.h:88
int counter
Definition: db_dim_client.c:19
static int Debug
Definition: dns.c:78
Error()
Definition: HeadersFTM.h:197
string fDBName
Definition: scheduler.cc:146
int fDurationCalRun
Definition: scheduler.cc:147

+ Here is the call graph for this function: