Index: /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.cc	(revision 4405)
+++ /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.cc	(revision 4405)
@@ -0,0 +1,75 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Javier López , 7/2004 <mailto:jlopez@ifae.es>
+!
+!   Copyright: MAGIC Software Development, 2000-2004
+!
+!
+\* ======================================================================== */
+
+#include "MLiveTime.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+ClassImp(MLiveTime);
+
+using namespace std;
+
+MLiveTime::MLiveTime(UInt_t numberbins, const char *name, const char *title)
+{
+
+    fName  = name  ? name  : "MLiveTime";
+    fTitle = title ? title : "Container to hold the live time for a certain time bin";
+    
+    Set(numberbins);
+}
+
+void MLiveTime::Set(UInt_t numberbins)
+{
+  fNumberTimeBins = numberbins;
+  fLiveTimeBin.Set(numberbins);
+  fMeanRealTimeBin.Set(numberbins);
+  fWidthRealTimeBin.Set(numberbins);
+}
+
+void MLiveTime::Print(const Option_t* o) const
+{
+    TString opt = o;
+
+    Double_t totalLiveTime = 0;
+
+    if (opt.Contains("last", TString::kIgnoreCase))
+    {
+	*fLog << GetName() << ": Present real time bin " << setprecision(10) << fMeanRealTimeBin[fNumberTimeBins-1] << " +- " << setprecision(5) << fWidthRealTimeBin[fNumberTimeBins-1] << " [" <<  2*fWidthRealTimeBin[fNumberTimeBins-1]*24*60*60 << " sec] MJD" << endl;
+	*fLog << GetName() << ": Present live time " << fLiveTimeBin[fNumberTimeBins-1] << " sec" << endl;
+    }
+    else if (opt.Contains("all", TString::kIgnoreCase))
+    {
+	*fLog << GetName() << ": " << fNumberTimeBins << " time bins" << endl;
+	for (UInt_t bin = 0; bin<fNumberTimeBins; bin++)
+	{
+	    *fLog << GetName() << ": Present real time bin " << setprecision(10) << fMeanRealTimeBin[bin] << " +- " << setprecision(5) <<  fWidthRealTimeBin[bin] << " [" <<  2*fWidthRealTimeBin[bin]*24*60*60 << " sec] MJD" << endl;
+	    *fLog << GetName() << ": Present live time " << fLiveTimeBin[bin] << " sec" << endl;
+	    totalLiveTime += fLiveTimeBin[bin];
+	}		
+	*fLog << GetName() << ": Total live time " << totalLiveTime << endl;
+    }
+    else
+	*fLog << GetName() << warn << "::Print() Bad argument " << opt << endl; 
+}
Index: /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.h
===================================================================
--- /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.h	(revision 4405)
+++ /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTime.h	(revision 4405)
@@ -0,0 +1,51 @@
+#ifndef MARS_MLiveTime
+#define MARS_MLiveTime
+
+#ifndef MARS_MParContainer
+#include "MParContainer.h"
+#endif
+
+#ifndef ROOT_TArrayD
+#include <TArrayD.h>
+#endif
+
+class MLiveTime : public MParContainer
+{
+ private:
+  
+  UInt_t fNumberTimeBins;
+  TArrayD fLiveTimeBin;
+  TArrayD fMeanRealTimeBin;
+  TArrayD fWidthRealTimeBin;
+  
+  void Set(UInt_t numberbins);
+
+ public:
+
+  MLiveTime(UInt_t numberbins = 1, const char *name=NULL, const char *title=NULL);
+  //~MLiveTime;
+
+  void AddBin() { Set(fNumberTimeBins+1); }
+  void AddTime(Double_t time) { fLiveTimeBin[fNumberTimeBins-1]+=time; }
+  void SetRealTime (Double_t mean, Double_t width)
+      {
+	  fMeanRealTimeBin[fNumberTimeBins-1]=mean;
+	  fWidthRealTimeBin[fNumberTimeBins-1]=width;
+      }
+
+  UInt_t GetNumberTimeBins() { return fNumberTimeBins;}
+  Double_t GetLiveTime() { return fLiveTimeBin[fNumberTimeBins-1]; }
+  Double_t GetMeanRealTime() { return fMeanRealTimeBin[fNumberTimeBins-1]; }
+  Double_t GetWidthRealTime() { return fWidthRealTimeBin[fNumberTimeBins-1]; }
+
+  Double_t* GetLiveTimeArray()   { return fLiveTimeBin.GetArray(); }
+  Double_t* GetMeanRealTimeArray()   { return fMeanRealTimeBin.GetArray(); }
+  Double_t* GetWidthRealTimeArray()   { return fWidthRealTimeBin.GetArray(); }
+
+  void Print(const Option_t*) const;
+
+ ClassDef(MLiveTime, 1)    // Storage for the live time extracted from real data
+
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.cc	(revision 4405)
+++ /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.cc	(revision 4405)
@@ -0,0 +1,356 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!   Author(s): Javier López , 7/2004 <mailto:jlopez@ifae.es>
+!
+!   Copyright: MAGIC Software Development, 2000-2004
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+//  MLiveTimeCalc
+//
+/////////////////////////////////////////////////////////////////////////////
+#include "MLiveTimeCalc.h"
+
+#include "MRawRunHeader.h"
+#include "MRawEvtHeader.h"
+#include "MLiveTime.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+#include "MTaskList.h"
+
+ClassImp(MLiveTimeCalc)
+using namespace std;
+
+Bool_t Debug = kTRUE;
+Bool_t PrintNewRun = kTRUE;
+
+MLiveTimeCalc::MLiveTimeCalc(const char *name, const char *title) : kSecTomSec(1e3), kDayToSec(24.*60.*60.), fRunHeader(NULL), fEvtHeader(NULL), fPresentEventTime(NULL), fLiveTime(NULL)
+{
+
+  fName  = name  ? name  : "MLiveTimeCalc";
+  fTitle = title ? title : "Task to compute the live time from real data.";
+
+  for (Int_t i=0; i<10; i++)
+    fNumberLostEvents[i] = 0;
+  
+  fFirstEventMjd = 0.;
+  fPresentEventMjd = 0.;
+  fLastEventMjd = 0.;
+
+  fPresentEventNumber = 0;
+  fLastEventNumber = 0;
+
+  fPresentEventRunNumber = 0;
+  fLastEventRunNumber = 0;
+
+  fRealTimeBinSize = 0.;
+
+  fPrintNextEvent = kFALSE;
+}
+
+Int_t MLiveTimeCalc::PreProcess(MParList *pList)
+{
+  
+  fEvtHeader = (MRawEvtHeader*)pList->FindObject(AddSerialNumber("MRawEvtHeader"));
+  if (!fEvtHeader)
+    {
+      *fLog << err << AddSerialNumber("MRawEvtHeader") << " not found ... aborting" << endl;
+      return kFALSE;
+    }
+  
+  fRunHeader = (MRawRunHeader*)pList->FindObject(AddSerialNumber("MRawRunHeader"));
+  if (!fRunHeader)
+    {
+      *fLog << err << AddSerialNumber("MRawRunHeader") << " not found ... aborting" << endl;
+      return kFALSE;
+    }
+  
+  fPresentEventTime = (MTime*)pList->FindObject(AddSerialNumber("MTime"));
+  if (!fPresentEventTime)
+    {
+      *fLog << err << AddSerialNumber("MTime") << " not found ... aborting" << endl;
+      return kFALSE;
+    }
+  
+  
+  fLiveTime = (MLiveTime*)pList->FindCreateObj(AddSerialNumber("MLiveTime"));
+  if (!fLiveTime)
+    {
+      *fLog << err << AddSerialNumber("MLiveTime") << " cannot be created ... aborting" << endl;
+      return kFALSE;
+    }
+  
+  return kTRUE;
+}
+
+Int_t MLiveTimeCalc::Process()
+{
+
+  fPresentEventMjd       = fPresentEventTime->GetMjd(); 
+  fLastEventMjd          = fLastEventTime.GetMjd();
+  fPreaviusLastEventMjd  = fPreaviusLastEventTime.GetMjd();
+
+  fPresentEventNumber    = fEvtHeader->GetDAQEvtNumber();
+  fPresentEventRunNumber = fRunHeader->GetRunNumber();;
+  
+  if (fPrintNextEvent && Debug)
+  {
+      *fLog << dbg << GetName() << ": Printing next event" << endl;
+      Print("all");
+      fLiveTime->Print("last");
+      *fLog << inf << endl; 
+      fPrintNextEvent = kFALSE;
+  }
+	  
+  if (fFirstEventMjd == 0)
+  {
+      fFirstEventMjd = fPresentEventMjd;
+
+      fPreaviusLastEventTime = fLastEventTime;
+      fLastEventTime = *fPresentEventTime;
+
+      fPreaviusLastEventRunNumber = fLastEventRunNumber;
+      fLastEventRunNumber = fPresentEventRunNumber;
+
+      fPreaviusLastEventNumber = fLastEventNumber;
+      fLastEventNumber = fPresentEventNumber;
+  }
+  else
+  {
+      if (isTimeStampOk())
+      {
+	  if (fRealTimeBinSize > 0 &&
+	      (fPresentEventMjd - fFirstEventMjd)*kDayToSec > fRealTimeBinSize)
+	  {
+
+	      Double_t width = (fLastEventMjd - fFirstEventMjd)/2;
+	      Double_t mean  = fFirstEventMjd + width;
+	      
+	      fLiveTime->SetRealTime(mean,width);
+	      *fLog << inf << GetName() << ": New time bin" << endl;
+	      Print("all");
+	      *fLog << GetName() << ": First event time " << setprecision(10) << fFirstEventMjd << setprecision(5) << endl;
+	      fLiveTime->Print("last");
+	      
+	      fLiveTime->AddBin();
+	      fFirstEventMjd = fPresentEventMjd;
+	  }      
+
+	  if (fPresentEventRunNumber!=fLastEventRunNumber)
+	  {
+	      if (fLastEventRunNumber != 0 && PrintNewRun)
+	      {
+		  *fLog << dbg << GetName() << ": New run" << endl;
+		  Print("all");
+		  fLiveTime->Print("last");
+		  *fLog << inf << endl;
+	      }
+	      fLastEventRunNumber = fPresentEventRunNumber;
+	  }
+	  else
+	      fLiveTime->AddTime((fPresentEventMjd-fLastEventMjd)*kDayToSec);
+	  
+
+      
+      fPreaviusLastEventTime = fLastEventTime;
+      fLastEventTime = *fPresentEventTime;
+
+      fPreaviusLastEventRunNumber = fLastEventRunNumber;
+      fLastEventRunNumber = fPresentEventRunNumber;
+
+      fPreaviusLastEventNumber = fLastEventNumber;      
+      fLastEventNumber = fPresentEventNumber;
+
+      }
+  }
+
+  return kTRUE;
+}
+  
+Int_t MLiveTimeCalc::PostProcess()
+{
+  Double_t width = (fLastEventMjd - fFirstEventMjd)/2;
+  Double_t mean  = fFirstEventMjd + width;
+ 
+  fLiveTime->SetRealTime(mean,width);
+
+  *fLog << dbg << endl;
+  *fLog << dbg << GetName() << ": PostProcess" << endl;
+  fLiveTime->Print("all");
+  *fLog << inf << endl;
+
+  *fLog << GetName() << " execution statistics:" << endl;
+  *fLog << dec << setfill(' ');
+
+  ULong_t fTotalNumberLostEvents = 0;
+  for (Int_t i=0; i<6; i++)
+    fTotalNumberLostEvents += fNumberLostEvents[i];
+
+  *fLog << " " << setw(7) << fTotalNumberLostEvents << " (" << setw(3) ;
+  *fLog << (Int_t)(fTotalNumberLostEvents*100/GetNumExecutions()) ;
+  *fLog << "%) bad time stamp events" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[0]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) time stamp == 0" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[1]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) last time stamp  == 0" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[2]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) time stamp in the past" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[3]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) time stamp == last one" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[4]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) time stamp just with integer part" << endl;
+
+  *fLog << "\t\t(" << setw(3) << (Int_t)(fNumberLostEvents[5]*100/fTotalNumberLostEvents) ;
+  *fLog << "%) run number < last one" << endl;
+
+  return kTRUE;
+}
+
+Bool_t MLiveTimeCalc::isTimeStampOk()
+{
+
+  Bool_t result = kTRUE;
+  
+
+  if (fPresentEventMjd == 0)
+    {
+	
+      if (Debug)
+	{
+	    *fLog << err << GetName() << ": Present event time stamp equal to 0" << endl;
+	    Print("all");
+	}
+
+      fNumberLostEvents[0]++;
+      result = kFALSE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if (fLastEventMjd == 0)
+    {
+	
+      if (Debug)
+	{
+	    *fLog << err << GetName() << ": Last event time stamp equal to 0" << endl;
+	    Print("all");
+	}
+
+      fNumberLostEvents[1]++;
+      result = kFALSE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if (fPresentEventMjd-fLastEventMjd < 0)
+    {
+      
+      if (Debug)
+	{
+	    *fLog << err << GetName() << ": Present event with time stamp in the past" << endl;
+	    Print("all");
+	}
+	  
+      fNumberLostEvents[2]++;
+      result = kFALSE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if (fPresentEventMjd-fLastEventMjd == 0)
+    {
+      
+      if (Debug)
+	{
+	    *fLog << err << GetName() << ": Present event time stamp equal than last event" << endl;
+	    Print("all");
+	}
+      
+      fNumberLostEvents[3]++;
+      result = kFALSE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if (fPresentEventNumber- fLastEventNumber<= 0 && fPresentEventRunNumber == fLastEventRunNumber)
+    {
+      
+      if (Debug)
+	{
+	    *fLog << warn << GetName() << ": Present event number equal or smaller than last event" << endl;
+	  Print("all");
+	}
+
+      result = kTRUE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if ((Int_t)fPresentEventMjd == fPresentEventMjd)
+    {
+      
+      if (Debug)
+	{
+	    *fLog << err << GetName() << ": Present event time stamp idetical to midnight" << endl;
+	    Print("all");
+	}
+      
+      fNumberLostEvents[4]++;
+      result = kFALSE;
+      fPrintNextEvent = kTRUE;
+    }
+  else if  ((fPresentEventMjd-fLastEventMjd)*kDayToSec > 1.)
+  {
+      
+      if (Debug)
+      {
+	  *fLog << warn << GetName() << ": Time from last event bigger than 1 sec" << endl;
+	  Print("all");
+      }
+      
+      result = kTRUE;
+      fPrintNextEvent = kTRUE;
+  }
+  else if  (fPresentEventRunNumber-fLastEventRunNumber < 0)
+  {
+      
+      if (Debug)
+      {
+	  *fLog << warn << GetName() << ": Present run number previuos than last one" << endl;
+	  Print("all");
+      }
+      
+      fNumberLostEvents[5]++;
+      result = kTRUE;
+      fPrintNextEvent = kTRUE;
+  }
+
+  return result;
+}
+
+void MLiveTimeCalc::Print(const Option_t *o) const
+{
+
+  *fLog << "Present event run number       ["  << fPresentEventRunNumber << "] event number [" << fPresentEventNumber << ']' << endl;
+  *fLog << "Last event run number          ["  << fLastEventRunNumber << "] event number [" << fLastEventNumber << ']' << endl;
+  *fLog << "Preavius last event run number ["  << fPreaviusLastEventRunNumber << "] event number [" << fPreaviusLastEventNumber << ']' << endl;
+  *fLog << "Present, last and preavius to last event times:"  << endl;
+  fPresentEventTime->Print();
+  fLastEventTime.Print();
+  fPreaviusLastEventTime.Print();
+}
Index: /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.h
===================================================================
--- /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.h	(revision 4405)
+++ /trunk/MagicSoft/Mars/mtemp/mifae/library/MLiveTimeCalc.h	(revision 4405)
@@ -0,0 +1,71 @@
+#ifndef MARS_MLiveTimeCalc
+#define MARS_MLiveTimeCalc
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+#ifndef MARS_MTime
+#include "MTime.h"
+#endif
+
+class MRawRunHeader;
+class MRawEvtHeader;
+class MLiveTime;
+
+class MLiveTimeCalc : public MTask
+{
+ public:
+  
+  const Double_t kSecTomSec;
+  const Double_t kDayToSec;
+  
+ private:
+  
+  MRawRunHeader* fRunHeader;
+  MRawEvtHeader* fEvtHeader;
+
+  MTime*         fPresentEventTime;
+  MTime          fLastEventTime;
+  MTime          fPreaviusLastEventTime;
+
+  MLiveTime*     fLiveTime;
+
+  
+  UInt_t   fNumberLostEvents[10];
+
+  Double_t fFirstEventMjd;
+  Double_t fPresentEventMjd;
+  Double_t fLastEventMjd;
+  Double_t fPreaviusLastEventMjd;
+
+  Int_t    fPresentEventNumber;
+  Int_t    fLastEventNumber;
+  Double_t fPreaviusLastEventNumber;
+
+  Int_t    fPresentEventRunNumber;
+  Int_t    fLastEventRunNumber;
+  Double_t fPreaviusLastEventRunNumber;
+
+  Double_t fRealTimeBinSize;
+  
+  Bool_t fPrintNextEvent;
+
+ public:
+
+  MLiveTimeCalc(const char *name=NULL, const char *title=NULL);
+  //~MLiveTimeCalc;
+
+  Int_t PreProcess(MParList *pList);
+  Int_t Process();
+  Int_t PostProcess();
+
+  void SetRealTimeBinSize(Double_t time) { fRealTimeBinSize=time; }
+
+  Bool_t isTimeStampOk();
+  void Print(const Option_t *o) const;
+
+ ClassDef(MLiveTimeCalc, 0)    // Task to compute the live time from real data
+};
+
+#endif
