Index: trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h	(revision 3913)
+++ trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h	(revision 3917)
@@ -11,4 +11,5 @@
 #pragma link C++ class MCalibrationCam+;
 #pragma link C++ class MCalibrationPix+;
+#pragma link C++ class MCalibrationRelTimeCalc+;
 #pragma link C++ class MCalibrationRelTimeCam+;
 #pragma link C++ class MCalibrationRelTimePix+;
Index: trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.cc
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.cc	(revision 3917)
+++ trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.cc	(revision 3917)
@@ -0,0 +1,512 @@
+/* ======================================================================== *\
+!
+! *
+! * 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): Markus Gaug  04/2004 <mailto:markus@ifae.es>
+!
+!   Copyright: MAGIC Software Development, 2000-2004
+!
+!
+\* ======================================================================== */
+
+//////////////////////////////////////////////////////////////////////////////
+//
+//   MCalibrationRelTimeCalc
+//
+//   Task to finalize the relative time calibration obtained 
+//   from the fit results to the summed FADC slice distributions delivered by 
+//   MCalibrationRelTimeCam, calculated and filled by MHCalibrationRelTimeCam, 
+//
+//   PreProcess(): Initialize pointers to MCalibrationRelTimeCam, 
+//               
+//   ReInit():     Initializes pointer to MBadPixelsCam
+//
+//   Process():    Nothing to be done, histograms getting filled by MHCalibrationChargeCam
+//
+//   PostProcess(): - FinalizeRelTimes()
+//                  - FinalizeBadPixels()
+//
+//  Input Containers:
+//   MCalibrationRelTimeCam
+//   MBadPixelsCam
+//   MGeomCam
+//
+//  Output Containers:
+//   MCalibrationRelTimeCam
+//   MBadPixelsCam
+//
+//  
+//////////////////////////////////////////////////////////////////////////////
+#include "MCalibrationRelTimeCalc.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MGeomCam.h"
+#include "MGeomPix.h"
+
+#include "MCalibrationRelTimeCam.h"
+#include "MCalibrationRelTimePix.h"
+
+#include "MBadPixelsCam.h"
+#include "MBadPixelsPix.h"
+
+
+ClassImp(MCalibrationRelTimeCalc);
+
+using namespace std;
+
+const Float_t MCalibrationRelTimeCalc::fgRelTimeRelErrLimit      = 3.;
+// --------------------------------------------------------------------------
+//
+// Default constructor. 
+//
+// Sets all pointers to NULL
+// 
+// Initializes:
+// - fRelTimeRelErrLimit to fgRelTimeRelErrLimit
+//
+// Calls:
+// - Clear()
+//
+MCalibrationRelTimeCalc::MCalibrationRelTimeCalc(const char *name, const char *title)
+    : fBadPixels(NULL), fCam(NULL), fGeom(NULL)
+{
+        
+  fName  = name  ? name  : "MCalibrationRelTimeCalc";
+  fTitle = title ? title : "Task to finalize the relative time calibration";
+  
+  SetRelTimeRelErrLimit();
+ 
+  Clear();
+  
+}
+
+// --------------------------------------------------------------------------
+//
+// Sets:
+// - all flags to kFALSE
+//
+void MCalibrationRelTimeCalc::Clear(const Option_t *o)
+{
+    SkipHiLoGainCalibration( kFALSE );    
+}
+
+
+// -----------------------------------------------------------------------------------
+//
+// The following containers are searched and created if they were not found:
+//
+//  - MBadPixelsCam
+//
+Int_t MCalibrationRelTimeCalc::PreProcess(MParList *pList)
+{
+  
+
+  fBadPixels = (MBadPixelsCam*)pList->FindCreateObj("MBadPixelsCam");
+  if (!fBadPixels)
+    {
+      *fLog << err << "Could not find or create MBadPixelsCam ... aborting." << endl;
+      return kFALSE;
+    }
+
+  
+  
+  return kTRUE;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Search for the following input containers and abort if not existing:
+//  - MGeomCam
+//  - MCalibrationRelTimeCam
+// 
+// It defines the PixId of every pixel in:
+//
+// - MCalibrationRelTimeCam 
+//
+// It sets all pixels in excluded which have the flag fBadBixelsPix::IsBad() set in:
+// 
+// - MCalibrationRelTimePix
+//
+Bool_t MCalibrationRelTimeCalc::ReInit(MParList *pList )
+{
+
+  fGeom = (MGeomCam*)pList->FindObject("MGeomCam");
+  if (!fGeom)
+    {
+      *fLog << err << "No MGeomCam found... aborting." << endl;
+      return kFALSE;
+    }
+  
+  fCam = (MCalibrationRelTimeCam*)pList->FindObject("MCalibrationRelTimeCam");
+  if (!fCam)
+    {
+      *fLog << err << "Cannot find MCalibrationRelTimeCam... aborting" << endl;
+      *fLog << err << "Maybe you forget to call an MFillH for the MHCalibrationRelTimeCam before..." << endl;
+      return kFALSE;
+    }
+
+  
+  UInt_t npixels     = fGeom->GetNumPixels();
+  
+  for (UInt_t i=0; i<npixels; i++)
+    {
+      
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)(*fCam)  [i];
+      MBadPixelsPix         &bad = (*fBadPixels)[i];
+      
+      pix.SetPixId(i);
+      
+      if (bad.IsBad())
+        {
+          pix.SetExcluded();
+          continue;
+        }
+      
+    }
+
+  return kTRUE;
+}
+
+// ----------------------------------------------------------------------------------
+//  
+// Nothing to be done in Process, but have a look at MHCalibrationRelTimeCam, instead
+// 
+Int_t MCalibrationRelTimeCalc::Process()
+{
+  return kTRUE;
+}
+
+// -----------------------------------------------------------------------
+//
+// Return if number of executions is null.
+//
+// First loop over pixels, average areas and sectors, call: 
+//  - FinalizeRelTimes()
+// for every entry. Count number of valid pixels in loop and return kFALSE
+// if there are none (the "Michele check").
+//
+// Call FinalizeBadPixels()
+//
+// Call MParContainer::SetReadyToSave() for fCam
+//
+// Print out some statistics
+//
+Int_t MCalibrationRelTimeCalc::PostProcess()
+{
+
+  if (GetNumExecutions()==0)
+    return kFALSE;
+
+  //
+  // First loop over pixels, call FinalizePedestals and FinalizeRelTimes
+  //
+  Int_t   nvalid      = 0;
+
+  for (Int_t pixid=0; pixid<fCam->GetSize(); pixid++)
+    {
+
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)(*fCam)[pixid];
+      //
+      // Check if the pixel has been excluded from the fits
+      //
+      if (pix.IsExcluded())
+        continue;
+
+      MBadPixelsPix &bad = (*fBadPixels)[pixid];
+
+      if (FinalizeRelTimes(pix,bad))
+        nvalid++;
+    }
+  
+  //
+  // The Michele check ...
+  //
+  if (nvalid == 0)
+  {
+      *fLog << err << GetDescriptor() << ": All pixels have non-valid calibration. " 
+	    << "Did you forget to fill the histograms "
+            << "(filling MHCalibrationRelTimeCam from MArrivalTimeCam using MFillH) ? " << endl;
+      *fLog << err << GetDescriptor() << ": Or, maybe, you have used a pedestal run " 
+            << "instead of a calibration run " << endl;
+    return kFALSE;
+  }
+
+  for (UInt_t aidx=0; aidx<fGeom->GetNumAreas(); aidx++)
+    {
+
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)fCam->GetAverageArea(aidx);
+      FinalizeRelTimes(pix, fCam->GetAverageBadArea(aidx));
+    }
+  
+  for (UInt_t sector=0; sector<fGeom->GetNumSectors(); sector++)
+    {
+
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)fCam->GetAverageSector(sector);
+      FinalizeRelTimes(pix, fCam->GetAverageBadSector(sector));
+    }
+  
+  //
+  // Finalize Bad Pixels
+  // 
+  FinalizeBadPixels();
+
+  //
+  // Finalize calibration statistics
+  //
+  FinalizeUnsuitablePixels();
+
+  fCam      ->SetReadyToSave();
+  fBadPixels->SetReadyToSave();
+
+  *fLog << inf << endl;
+  *fLog << GetDescriptor() << ": Errors statistics:" << endl;  
+
+  PrintUncalibrated(MBadPixelsPix::kDeviatingTimeResolution,    
+                    Form("%s%2.1f%s","Time resolution less than ",fRelTimeRelErrLimit," sigma from Mean:           "));
+  PrintUncalibrated(MBadPixelsPix::kRelTimeOscillating,   
+                    "Pixels with changing Rel. Times   over time:      ");
+  PrintUncalibrated(MBadPixelsPix::kRelTimeNotFitted,     
+                    "Pixels with unsuccesful Gauss fit to the times:   ");
+  return kTRUE;
+}
+
+
+// ----------------------------------------------------------------------------------------------------
+//
+//
+// First loop: Calculate a mean and mean RMS of time resolution per area index 
+//             Include only pixels which are not MBadPixelsPix::kUnsuitableRun or 
+//             MBadPixelsPix::kUnreliableRun (see FinalizeBadPixels())
+//              
+// Second loop: Exclude those deviating by more than fRelTimeRelErrLimit mean 
+//              sigmas from the mean (obtained in first loop). Set 
+//              MBadPixelsPix::kDeviatingTimeResolution if excluded.
+// 
+Bool_t MCalibrationRelTimeCalc::FinalizeRelTimes(MCalibrationRelTimePix &cal, MBadPixelsPix &bad)
+{
+
+  const UInt_t npixels  = fGeom->GetNumPixels();
+  const UInt_t nareas   = fGeom->GetNumAreas();
+
+  Float_t lowlim      [nareas];
+  Float_t upplim      [nareas];
+  Float_t areaerrs    [nareas];
+  Float_t areamean    [nareas];
+  Int_t   numareavalid[nareas];
+
+  memset(lowlim        ,0, nareas   * sizeof(Float_t));
+  memset(upplim        ,0, nareas   * sizeof(Float_t));
+  memset(areaerrs      ,0, nareas   * sizeof(Float_t));
+  memset(areamean      ,0, nareas   * sizeof(Float_t));
+  memset(numareavalid  ,0, nareas   * sizeof(Int_t  ));
+
+  //
+  // First loop: Get mean time resolution the RMS
+  //             The loop is only to recognize later pixels with very deviating numbers
+  //
+  for (UInt_t i=0; i<npixels; i++)
+    {
+      
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)(*fCam)  [i];
+      MBadPixelsPix         &bad = (*fBadPixels)[i];
+      
+      if (!pix.IsExcluded())
+        continue;
+
+      if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
+        continue;
+
+      if (bad.IsUnsuitable(MBadPixelsPix::kUnreliableRun))
+        continue;
+      
+      const Float_t res  = pix.GetTimePrecision();
+      const Float_t perr  = pix.GetTimePrecisionErr();
+      const Int_t   aidx  = (*fGeom)[i].GetAidx();
+
+      areamean    [aidx] += res;
+      areaerrs    [aidx] += perr;
+      numareavalid[aidx] ++;
+    } 
+
+
+
+  for (UInt_t i=0; i<nareas; i++)
+    {
+      if (numareavalid[i] == 0)
+        {
+          *fLog << warn << GetDescriptor() << ": No pixels with valid number of photo-electrons found "
+                << "in area index: " << i << endl;
+          continue;
+        }
+ 
+      areamean[i] = areamean[i] / numareavalid[i];
+      areaerrs[i] = areaerrs[i] / numareavalid[i];
+      lowlim  [i] = areamean[i] - fRelTimeRelErrLimit*areaerrs[i];
+      upplim  [i] = areamean[i] + fRelTimeRelErrLimit*areaerrs[i];
+    }
+
+
+
+  //
+  // Second loop: Exclude pixels deviating by more than fRelTimeErrLimit sigma. 
+  // 
+  for (UInt_t i=0; i<npixels; i++)
+    {
+      
+      MCalibrationRelTimePix &pix = (MCalibrationRelTimePix&)(*fCam)[i];
+
+      if (!pix.IsExcluded())
+        continue;
+
+      const Float_t res  = pix.GetTimePrecision();
+
+      MBadPixelsPix         &bad = (*fBadPixels)[i];
+      const Int_t   aidx   = (*fGeom)[i].GetAidx();
+
+      if ( res < lowlim[aidx] || res > upplim[aidx] )
+        {
+          *fLog << warn << GetDescriptor() << ": Deviating time resolution: " 
+                << Form("%4.2f",res) << " out of accepted limits: [" 
+                << Form("%4.2f%s%4.2f",lowlim[aidx],",",upplim[aidx]) << "] in pixel " << i << endl;
+          bad.SetUncalibrated( MBadPixelsPix::kDeviatingTimeResolution);
+          bad.SetUnsuitable  ( MBadPixelsPix::kUnsuitableRun    );
+          pix.SetExcluded();
+        }
+    }
+  
+  return kTRUE;
+}
+
+
+
+// -----------------------------------------------------------------------------------
+//
+// Sets pixel to MBadPixelsPix::kUnsuitableRun, if one of the following flags is set:
+// - MBadPixelsPix::kRelTimeIsPedestal
+// - MBadPixelsPix::kRelTimeErrNotValid 
+// - MBadPixelsPix::kRelTimeRelErrNotValid 
+//
+// - Call MCalibrationPix::SetExcluded() for the bad pixels
+//
+void MCalibrationRelTimeCalc::FinalizeBadPixels()
+{
+  
+  for (Int_t i=0; i<fBadPixels->GetSize(); i++)
+    {
+      
+      MBadPixelsPix    &bad    = (*fBadPixels)[i];
+      MCalibrationPix  &pix    = (*fCam)[i];
+
+      if (bad.IsUncalibrated( MBadPixelsPix::kDeviatingTimeResolution))
+        bad.SetUnsuitable(   MBadPixelsPix::kUnsuitableRun   );
+ 
+      if (bad.IsUncalibrated( MBadPixelsPix::kRelTimeNotFitted))
+        bad.SetUnsuitable(   MBadPixelsPix::kUnreliableRun   );
+ 
+      if (bad.IsUncalibrated( MBadPixelsPix::kRelTimeOscillating))
+        bad.SetUnsuitable(   MBadPixelsPix::kUnreliableRun   );
+ 
+      if (bad.IsUnsuitable(   MBadPixelsPix::kUnsuitableRun    ))
+        pix.SetExcluded();
+
+    }
+}
+
+
+// -----------------------------------------------------------------------------------------------
+//
+// - Print out statistics about BadPixels of type UnsuitableType_t 
+// - store numbers of bad pixels of each type in fCam
+//
+void MCalibrationRelTimeCalc::FinalizeUnsuitablePixels()
+{
+  
+  *fLog << inf << endl;
+  *fLog << GetDescriptor() << ": Calibration statistics:" << endl;
+  *fLog << dec << setfill(' ');
+
+  const Int_t nareas = fGeom->GetNumAreas();
+
+  Int_t counts[nareas];
+  memset(counts,0,nareas*sizeof(Int_t));
+
+  for (Int_t i=0; i<fBadPixels->GetSize(); i++)
+    {
+      MBadPixelsPix &bad = (*fBadPixels)[i];
+      if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
+        {
+          const Int_t aidx = (*fGeom)[i].GetAidx();
+          counts[aidx]++;
+        }
+    }
+
+  for (Int_t aidx=0; aidx<nareas; aidx++)
+    fCam->SetNumUncalibrated(counts[aidx], aidx);
+
+  if (fGeom->InheritsFrom("MGeomCamMagic"))
+    *fLog << " " << setw(7) << "Uncalibrated Pixels:            " 
+          << Form("%s%3i%s%3i","Inner: ",counts[0]," Outer: ",counts[1]) << endl;
+
+  memset(counts,0,nareas*sizeof(Int_t));
+
+  for (Int_t i=0; i<fBadPixels->GetSize(); i++)
+    {
+      MBadPixelsPix &bad = (*fBadPixels)[i];
+      if (bad.IsUnsuitable(MBadPixelsPix::kUnreliableRun))
+        {
+          const Int_t aidx = (*fGeom)[i].GetAidx();
+          counts[aidx]++;
+        }
+    }
+
+  for (Int_t aidx=0; aidx<nareas; aidx++)
+    fCam->SetNumUnreliable(counts[aidx], aidx);
+
+  *fLog << " " << setw(7) << "Unreliable Pixels:              "
+        << Form("%s%3i%s%3i","Inner: ",counts[0]," Outer: ",counts[1]) << endl;
+
+}
+
+// -----------------------------------------------------------------------------------------------
+//
+// Print out statistics about BadPixels of type UncalibratedType_t 
+// 
+void MCalibrationRelTimeCalc::PrintUncalibrated(MBadPixelsPix::UncalibratedType_t typ, const char *text) const 
+{
+  
+  UInt_t countinner = 0;
+  UInt_t countouter = 0;
+  for (Int_t i=0; i<fBadPixels->GetSize(); i++)
+    {
+      MBadPixelsPix &bad = (*fBadPixels)[i];
+      if (bad.IsUncalibrated(typ))
+        {
+          if (fGeom->GetPixRatio(i) == 1.)
+            countinner++;
+          else
+            countouter++;
+        }
+    }
+
+  *fLog << " " << setw(7) << text  
+        << Form("%s%3i%s%3i","Inner: ",countinner," Outer: ",countouter) << endl;
+}
+
Index: trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.h
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.h	(revision 3917)
+++ trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCalc.h	(revision 3917)
@@ -0,0 +1,74 @@
+#ifndef MARS_MCalibrationRelTimeCalc
+#define MARS_MCalibrationRelTimeCalc
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                                         //
+// MCalibrationRelTimeCalc                                                   //
+//                                                                         //
+// Integrates the time slices of the all pixels of a calibration event     //
+// and substract the pedestal value                                        //
+//                                                                         //
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef MARS_MTask
+#include "MTask.h"
+#endif
+
+#ifndef MARS_MBadPixelsPix
+#include "MBadPixelsPix.h"
+#endif
+
+#ifndef MARS_MCalibrationRelTimeCam
+#include "MCalibrationRelTimeCam.h"
+#endif
+
+class MCalibrationRelTimePix;
+class MCalibrationRelTimeCam;
+class MGeomCam;
+class MBadPixelsCam;
+class MBadPixelsPix;
+class MCalibrationRelTimeCalc : public MTask
+{
+private:
+
+  static const Float_t fgRelTimeRelErrLimit;      //! Default for fRelTimeRelErrLimit      (now set to: 1.)
+ 
+  // Variables
+  Float_t fRelTimeRelErrLimit;                  // Limit acceptance rel. error mean (in abs. numbers)
+  Byte_t  fFlags;                              // Bit-field for the flags
+
+  // Pointers
+  MBadPixelsCam              *fBadPixels;      //  Bad Pixels 
+  MCalibrationRelTimeCam     *fCam;            //  Calibrated RelTimes of all pixels 
+  MGeomCam                   *fGeom;           //! Camera geometry
+
+  // enums
+  enum  { kHiLoGainCalibration };
+
+  // functions
+  Bool_t FinalizeRelTimes        ( MCalibrationRelTimePix &cal, MBadPixelsPix &bad      );
+  void   FinalizeBadPixels      ();
+  void   FinalizeUnsuitablePixels();
+
+  void   PrintUncalibrated( MBadPixelsPix::UncalibratedType_t typ, const char *text) const;
+
+  Int_t  PreProcess (MParList *pList);
+  Bool_t ReInit     (MParList *pList); 
+  Int_t  Process    ();
+  Int_t  PostProcess();
+
+public:
+
+  MCalibrationRelTimeCalc(const char *name=NULL, const char *title=NULL);
+
+  void Clear(const Option_t *o="");
+  
+  void SetRelTimeRelErrLimit ( const Float_t f=fgRelTimeRelErrLimit      ) { fRelTimeRelErrLimit = f;   }
+
+  void SkipHiLoGainCalibration ( const Bool_t b=kTRUE )
+      { b ? CLRBIT(fFlags, kHiLoGainCalibration) : SETBIT(fFlags, kHiLoGainCalibration); }
+
+  ClassDef(MCalibrationRelTimeCalc, 1)   // Task finalizing the relative time Calibration 
+};
+
+#endif
Index: trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCam.h
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCam.h	(revision 3913)
+++ trunk/MagicSoft/Mars/mcalib/MCalibrationRelTimeCam.h	(revision 3917)
@@ -6,12 +6,23 @@
 #endif
 
+#ifndef ROOT_TArrayI
+#include "TArrayI.h"
+#endif
+
+
 class MCalibrationRelTimeCam : public MCalibrationCam
 {
 private:
   
+  TArrayI fNumUncalibrated;
+  TArrayI fNumUnreliable;
+
 public:
 
   MCalibrationRelTimeCam(const char *name=NULL, const char *title=NULL);
   ~MCalibrationRelTimeCam() {}
+
+  Int_t  GetNumUncalibrated        ( const Int_t aidx) const   { return fNumUncalibrated[aidx]; }
+  Int_t  GetNumUnreliable          ( const Int_t aidx) const   { return fNumUnreliable  [aidx]; }
 
   // Prints
@@ -21,4 +32,7 @@
   Bool_t GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type=0) const;
   void DrawPixelContent(Int_t num) const;    
+
+  void   SetNumUncalibrated    ( const Int_t i, const Int_t aidx)   { fNumUncalibrated[aidx] = i; }
+  void   SetNumUnreliable      ( const Int_t i, const Int_t aidx)   { fNumUnreliable  [aidx] = i; }
   
   ClassDef(MCalibrationRelTimeCam, 1)	// Container Rel. Arrival Time Calibration Results Camera
Index: trunk/MagicSoft/Mars/mcalib/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mcalib/Makefile	(revision 3913)
+++ trunk/MagicSoft/Mars/mcalib/Makefile	(revision 3917)
@@ -45,4 +45,5 @@
            MCalibrationRelTimeCam.cc \
            MCalibrationRelTimePix.cc \
+	   MCalibrationRelTimeCalc.cc \
            MCalibrationQECam.cc \
            MCalibrationQEPix.cc  \
