Index: trunk/MagicSoft/Mars/mjobs/MSequence.cc
===================================================================
--- trunk/MagicSoft/Mars/mjobs/MSequence.cc	(revision 9012)
+++ trunk/MagicSoft/Mars/mjobs/MSequence.cc	(revision 9015)
@@ -47,6 +47,6 @@
 //   Sequence:     31015
 //
-//   # Observation Period (not needed)
-//   Period:       18
+//   # Observation Period (not needed, calculated from Night)
+//   # Period:       18
 //
 //   # Date of sunrise of the observation night - necessary if the path
@@ -74,4 +74,7 @@
 //   # Total number of data-events in sequence (not needed)
 //   NumEvents:    250914
+//
+//   # Brightest light condition of the contained runs (not needed)
+//   LightCondition: Twilight
 //
 //   # Whether this is MC data or not (necessary in case of MCs if
@@ -661,8 +664,7 @@
     fLastRun   = GetEnvValue2(env, prefix, "LastRun",   -1);
     fNumEvents = GetEnvValue2(env, prefix, "NumEvents", -1);
-    fPeriod    = GetEnvValue2(env, prefix, "Period",    -1);
 
     TString str;
-    str = GetEnvValue2(env, prefix, "LightConditions", "n/a");
+    str = GetEnvValue2(env, prefix, "LightCondition", "n/a");
     fLightCondition = GetLightCondition(str);
 
@@ -673,4 +675,6 @@
     str += " 00:00:00";
     fNight.SetSqlDateTime(str);
+
+    fPeriod = fNight.GetMagicPeriod();
 
     fProject      = GetEnvValue2(env, prefix, "Project", "");
@@ -688,4 +692,5 @@
 
     // Dummies:
+    env.Touch("Period");
     env.Touch("ZdMin");
     env.Touch("ZdMax");
@@ -700,4 +705,16 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Create a sequence from the database, e.g.
+//
+//    TString mysql     = "mysql://MAGIC:password@vela/MyMagic";
+//    Int_t   sequence  = 100002;
+//    Int_t   telescope = 1;
+//
+//    MSequence seq(mysql, sequence, telescope);
+//
+// For more details see MSequenceSQL.
+//
 MSequence::MSequence(const char *fname, UInt_t seq, UShort_t tel)
 {
@@ -705,54 +722,102 @@
 }
 
+// --------------------------------------------------------------------------
+//
+// Some helper functions for the comparison functions
+//
 static int operator==(const TArrayI &a, const TArrayI &b)
 {
-    return a.GetSize()==b.GetSize() ?
-        memcmp(a.GetArray(), b.GetArray(), a.GetSize()*sizeof(Int_t))==0 :
-        false;
-}
-
-static int IsNull(const TArrayI &a)
-{
-    if (a.GetSize()==0)
-        return true;
-
-    return a.GetSize()==0 ? true : a==TArrayI(a.GetSize());
+    return a.GetSize()==b.GetSize() &&
+        memcmp(a.GetArray(), b.GetArray(), a.GetSize()*sizeof(Int_t));
 }
 
 static int IsNull(const TArrayI &a, const TArrayI &b)
 {
-    return IsNull(a) && IsNull(b);
-}
-
-Bool_t MSequence::IsSimilar(const MSequence &s) const
+    return a==TArrayI(a.GetSize()) && b==TArrayI(b.GetSize());
+}
+
+static int Check(const TArrayI &a, const TArrayI &b)
+{
+    return a==b || IsNull(a, b);
+}
+
+// --------------------------------------------------------------------------
+//
+// Here we test all things mandatory for a sequence:
+//   fTelescope
+//   fSequence
+//   fNight
+//   fMonteCarlo
+//   fCalRuns
+//   fCalRunsSub
+//   fPedRuns
+//   fPedRunsSub
+//   fDatRuns
+//   fDatRunsSub
+//   fExclRuns
+//   fExclRunsSub
+//
+Bool_t MSequence::IsCompatible(const MSequence &s) const
 {
     return // Mandatory
-        fTelescope==s.fTelescope && fSequence==s.fSequence &&
-        fNight==s.fNight
-        && fLightCondition==s.fLightCondition &&
-
-        fMonteCarlo==s.fMonteCarlo &&
-
-        (fRunsSub    ==s.fRunsSub     || IsNull(fRunsSub,     s.fRunsSub))     &&
-        (fCalRunsSub ==s.fCalRunsSub  || IsNull(fCalRunsSub,  s.fCalRunsSub))  &&
-        (fPedRunsSub ==s.fPedRunsSub  || IsNull(fPedRunsSub,  s.fPedRunsSub))  &&
-        (fDatRunsSub ==s.fDatRunsSub  || IsNull(fDatRunsSub,  s.fDatRunsSub))  &&
-        (fExclRunsSub==s.fExclRunsSub || IsNull(fExclRunsSub, s.fExclRunsSub))
-        ;
-}
-
+        fTelescope   == s.fTelescope   &&
+        fSequence    == s.fSequence    &&
+        fNight       == s.fNight       &&
+
+        fMonteCarlo  == s.fMonteCarlo  &&
+
+        fCalRuns     == s.fCalRuns     &&
+        fPedRuns     == s.fPedRuns     &&
+        fDatRuns     == s.fDatRuns     &&
+        fExclRuns    == s.fExclRuns    &&
+
+        Check(fCalRunsSub,  s.fCalRunsSub) &&
+        Check(fPedRunsSub,  s.fPedRunsSub) &&
+        Check(fDatRunsSub,  s.fDatRunsSub) &&
+        Check(fExclRunsSub, s.fExclRunsSub);
+}
+
+// --------------------------------------------------------------------------
+//
+// Here we test whether all values of a sequence are identical
+//   IsCompaticle(s)
+//   fStart
+//   fLastRun
+//   fNumEvents
+//   fPeriod
+//   fProject
+//   fSource
+//   fRuns
+//   fHvSettings
+//   fTriggerTable
+//   fLightCondition
+//   fRuns
+//   fRunsSub
+//
+Bool_t MSequence::operator==(const MSequence &s) const
+{
+    return IsCompatible(s) &&
+        // Unnecessary
+        fStart          == s.fStart          &&
+        fLastRun        == s.fLastRun        &&
+        fNumEvents      == s.fNumEvents      &&
+        fPeriod         == s.fPeriod         &&
+        fProject        == s.fProject        &&
+        fSource         == s.fSource         &&
+        fRuns           == s.fRuns           &&
+        fHvSettings     == s.fHvSettings     &&
+        fTriggerTable   == s.fTriggerTable   &&
+        fLightCondition == s.fLightCondition &&
+        Check(fRunsSub, s.fRunsSub);
+}
+
+// --------------------------------------------------------------------------
+//
+// Check whether the sequence has also identical source, i.e.
+// the sequence filepath and the datapath in addition to operator==
+//
 Bool_t MSequence::IsIdentical(const MSequence &s) const
 {
-    return IsSimilar(s) &&
-        // Unnecessary
-        fStart==s.fStart         && fLastRun==s.fLastRun   &&
-        fNumEvents==s.fNumEvents && fPeriod==s.fPeriod     &&
-        fProject==s.fProject     && fSource==s.fSource     &&
-        /*fTriggerTable==s.fTriggerTable &&*/ fHvSettings==s.fHvSettings;
-}
-
-Bool_t MSequence::operator==(const MSequence &s) const
-{
-    return IsIdentical(s) &&
+    return *this==s &&
         // Obsolete
         fDataPath==s.fDataPath && fFileName==s.fFileName;
@@ -981,5 +1046,5 @@
         out << pre << "Night:          " << fNight.GetStringFmt("%Y-%m-%d") << endl;
     out << endl;
-    out << pre << "LightConditions: ";
+    out << pre << "LightCondition: ";
     switch (fLightCondition)
     {
@@ -1018,4 +1083,8 @@
     else
     {
+        // FIXME: This needs more check!
+        // Could we make "Runs" an automatic summary of all runs?
+        // Should we add a check forbidding the same run in
+        // Cal/Ped/Data? What about the Exclude?
         str += PrintRuns(out, pre, "Runs:     ", fRuns,     fRunsSub);
         /*str +=*/ PrintRuns(out, pre, "CalRuns:  ", fCalRuns,  fCalRunsSub);
@@ -1196,4 +1265,8 @@
         f = &fCalRunsSub;
         break;
+    case 'X':
+        r = &fExclRuns;
+        f = &fExclRunsSub;
+        break;
     default:
         r = &fRuns;
@@ -1204,19 +1277,5 @@
     AddEntry(run, file, *r, *f);
 
-    MJob::SortArray(fExclRuns);
-}
-
-// --------------------------------------------------------------------------
-//
-// Exclude this run (i.e. add it to fExclRuns)
-//
-void MSequence::ExcludeFile(UInt_t run, UInt_t file/*, Bool_t force*/)
-{
-//    if (force && IsExcluded(run, file))
-//        return;
-
-    AddEntry(run, file, fExclRuns, fExclRunsSub);
-
-    MJob::SortArray(fExclRuns);
+    SortArrays(*r, *f);
 }
 
@@ -1268,5 +1327,5 @@
     fNight.SetSqlDateTime(night);
 
-    fPeriod = MAstro::GetMagicPeriod(fNight.GetMjd());
+    fPeriod = fNight.GetMagicPeriod();
 }
 
