Index: trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h
===================================================================
--- trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h	(revision 3979)
+++ trunk/MagicSoft/Mars/mcalib/CalibLinkDef.h	(revision 3980)
@@ -34,4 +34,6 @@
 #pragma link C++ class MHCalibrationTestCam+;
 #pragma link C++ class MHCalibrationTestPix+;
+#pragma link C++ class MHCalibrationTestTimeCam+;
+#pragma link C++ class MHCalibrationTestTimePix+;
 
 #pragma link C++ class MMcCalibrationCalc++;
Index: trunk/MagicSoft/Mars/mcalib/MHCalibrationCam.cc
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MHCalibrationCam.cc	(revision 3979)
+++ trunk/MagicSoft/Mars/mcalib/MHCalibrationCam.cc	(revision 3980)
@@ -639,5 +639,5 @@
 {
 
-  if (bad.IsBad())
+  if (bad.IsUnsuitable(MBadPixelsPix::kUnsuitableRun))
     hist.SetExcluded();
   
Index: trunk/MagicSoft/Mars/mcalib/MHCalibrationTestTimeCam.cc
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MHCalibrationTestTimeCam.cc	(revision 3980)
+++ trunk/MagicSoft/Mars/mcalib/MHCalibrationTestTimeCam.cc	(revision 3980)
@@ -0,0 +1,503 @@
+/* ======================================================================== *\
+!
+! *
+! * 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   02/2004 <mailto:markus@ifae.es>
+!              
+!   Copyright: MAGIC Software Development, 2000-2004
+!
+!
+\* ======================================================================== */
+/////////////////////////////////////////////////////////////////////////////
+//                                                                        
+// MHCalibrationTestTimeCam                                                
+//                                                                        
+// Fills the calibrated signal from an MArrivalTime into 
+// MHCalibrationTestTimePix for every:
+//
+// - Pixel, stored in the TObjArray's MHCalibrationCam::fHiGainArray  
+//   or MHCalibrationCam::fHiGainArray, respectively.
+//
+// - Average pixel per AREA index (e.g. inner and outer for the MAGIC camera), 
+//   stored in the TObjArray's MHCalibrationCam::fAverageHiGainAreas and 
+//   MHCalibrationCam::fAverageHiGainAreas
+//
+// - Average pixel per camera SECTOR (e.g. sectors 1-6 for the MAGIC camera), 
+//   stored in the TObjArray's MHCalibrationCam::fAverageHiGainSectors 
+//   and MHCalibrationCam::fAverageHiGainSectors 
+//
+// The signals are filled into a histogram and an array, in order to perform 
+// a Fourier analysis (see MHGausEvents). The signals are moreover averaged on an 
+// event-by-event basis and written into the corresponding average pixels.
+//
+// The histograms are fitted to a Gaussian, mean and sigma with its errors 
+// and the fit probability are extracted. If none of these values are NaN's and 
+// if the probability is bigger than MHGausEvents::fProbLimit (default: 0.5%), 
+// the fit is declared valid.
+// Otherwise, the fit is repeated within ranges of the previous mean 
+// +- MHGausEvents::fPickupLimit (default: 5) sigma (see MHGausEvents::RepeatFit())
+// In case this does not make the fit valid, the histogram means and RMS's are 
+// taken directly (see MHGausEvents::BypassFit()) and the following flags are set:
+// - MBadPixelsPix::SetUncalibrated( MBadPixelsPix::kHiGainNotFitted ) and
+// - MBadPixelsPix::SetUnsuitable(   MBadPixelsPix::kUnreliableRun    ) 
+// 
+// Outliers of more than MHGausEvents::fPickupLimit (default: 5) sigmas 
+// from the mean are counted as Pickup events (stored in MHGausEvents::fPickup) 
+//
+// The class also fills arrays with the signal vs. event number, creates a fourier 
+// spectrum (see MHGausEvents::CreateFourierSpectrum()) and investigates if the 
+// projected fourier components follow an exponential distribution. 
+// In case that the probability of the exponential fit is less than 
+// MHGausEvents::fProbLimit (default: 0.5%), the following flags are set:
+// - MBadPixelsPix::SetUncalibrated( MBadPixelsPix::kHiGainOscillating ) and
+// - MBadPixelsPix::SetUnsuitable(   MBadPixelsPix::kUnreliableRun      )
+// 
+// This same procedure is performed for the average pixels.
+//
+// The following results are written into an MCalibrationCam:
+//
+// - MCalibrationPix::SetMean()
+// - MCalibrationPix::SetMeanErr()
+// - MCalibrationPix::SetSigma()
+// - MCalibrationPix::SetSigmaErr()
+// - MCalibrationPix::SetProb()
+// - MCalibrationPix::SetNumPickup()
+//
+// For all averaged areas, the fitted sigma is multiplied with the square root of 
+// the number involved pixels in order to be able to compare it to the average of 
+// sigmas in the camera.
+//                                                                         
+/////////////////////////////////////////////////////////////////////////////
+#include "MHCalibrationTestTimeCam.h"
+#include "MHCalibrationTestTimePix.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MCalibrationCam.h"
+#include "MCalibrationPix.h"
+
+#include "MArrivalTime.h"
+
+#include "MGeomCam.h"
+#include "MGeomPix.h"
+
+#include "MBadPixelsCam.h"
+#include "MBadPixelsPix.h"
+
+ClassImp(MHCalibrationTestTimeCam);
+
+using namespace std;
+// --------------------------------------------------------------------------
+//
+// Default Constructor. 
+//
+MHCalibrationTestTimeCam::MHCalibrationTestTimeCam(const char *name, const char *title) 
+{
+
+  fName  = name  ? name  : "MHCalibrationTestTimeCam";
+  fTitle = title ? title : "Histogram class for testing the calibration of arrival times";
+  
+}
+
+// --------------------------------------------------------------------------
+//
+// Gets or creates the pointers to:
+//
+// Searches pointer to:
+// - MArrivalTime
+//
+// Initializes, if empty to MGeomCam::GetNumAreas() for:
+// - MHCalibrationCam::fAverageHiGainAreas, MHCalibrationCam::fAverageLoGainAreas
+//
+// Initializes, if empty to MGeomCam::GetNumSectors() for:
+// - MHCalibrationCam::fAverageHiGainSectors, MHCalibrationCam::fAverageLoGainSectors
+// 
+// Calls MHCalibrationCam::InitHists() for every entry in:
+// - MHCalibrationCam::fHiGainArray
+// - MHCalibrationCam::fAverageHiGainAreas
+// - MHCalibrationCam::fAverageHiGainSectors
+//
+// Sets Titles and Names for the Histograms 
+// - MHCalibrationCam::fAverageHiGainAreas
+// - MHCalibrationCam::fAverageHiGainSectors
+// 
+// Sets number of bins to MHCalibrationCam::fAverageNbins for:
+// - MHCalibrationCam::fAverageHiGainAreas
+// - MHCalibrationCam::fAverageHiGainSectors
+//
+Bool_t MHCalibrationTestTimeCam::ReInitHists(MParList *pList)
+{
+
+  MArrivalTime *signal = (MArrivalTime*)pList->FindObject("MArrivalTime");
+  if (!signal)
+  {
+      *fLog << err << "MArrivalTime not found... abort." << endl;
+      return kFALSE;
+  }
+
+  const Int_t npixels  = fGeom->GetNumPixels();
+  const Int_t nsectors = fGeom->GetNumSectors();
+  const Int_t nareas   = fGeom->GetNumAreas();
+
+  if (fHiGainArray->GetEntries()==0)
+  {
+      fHiGainArray->Expand(npixels);
+      for (Int_t i=0; i<npixels; i++)
+      {
+	  (*fHiGainArray)[i] = new MHCalibrationTestTimePix("Calibrated Events Time",
+                                                "TestTime Calibration Pixel");
+          InitHists((*this)[i],(*fBadPixels)[i],i);
+      }
+  }
+
+  if (fLoGainArray->GetEntries()==0)
+  {
+      fLoGainArray->Expand(npixels);
+      for (Int_t i=0; i<npixels; i++)
+      {
+	  (*fLoGainArray)[i] = new MHCalibrationTestTimePix("Calibrated Events Time",
+                                                "TestTime Calibration Pixel");
+          InitHists((*this)(i),(*fBadPixels)[i],i);
+      }
+  }
+
+
+  if (fAverageHiGainAreas->GetEntries()==0)
+  {
+    fAverageHiGainAreas->Expand(nareas);
+    
+    for (Int_t j=0; j<nareas; j++)
+      {
+        (*fAverageHiGainAreas)[j] = 
+          new MHCalibrationTestTimePix("MHCalibrationTestTimeAverageArea",
+                           "Average TestTime Calibrations Area Idx ");
+
+        GetAverageHiGainArea(j).GetHGausHist()->SetTitle("TestTime Calibrations Area Idx ");
+        GetAverageHiGainArea(j).SetNbins(fAverageNbins);
+        GetAverageHiGainArea(j).InitBins();
+        GetAverageHiGainArea(j).ChangeHistId(j);
+        GetAverageHiGainArea(j).SetEventFrequency(fPulserFrequency);
+
+      }
+  }
+
+  if (fAverageLoGainAreas->GetEntries()==0)
+  {
+    fAverageLoGainAreas->Expand(nareas);
+    
+    for (Int_t j=0; j<nareas; j++)
+      {
+        (*fAverageLoGainAreas)[j] = 
+          new MHCalibrationTestTimePix("MHCalibrationTestTimeAverageArea",
+                           "Average TestTime Calibrations Area Idx ");
+
+        GetAverageLoGainArea(j).GetHGausHist()->SetTitle("TestTime Calibrations Area Idx ");
+        GetAverageLoGainArea(j).SetNbins(fAverageNbins);
+        GetAverageLoGainArea(j).InitBins();
+        GetAverageLoGainArea(j).ChangeHistId(j);
+        GetAverageLoGainArea(j).SetEventFrequency(fPulserFrequency);
+
+      }
+  }
+
+
+  if (fAverageHiGainSectors->GetEntries()==0)
+  {
+      fAverageHiGainSectors->Expand(nsectors);
+
+      for (Int_t j=0; j<nsectors; j++)
+      {
+	  (*fAverageHiGainSectors)[j] = 
+            new MHCalibrationTestTimePix("MHCalibrationTestTimeAverageSector",
+                             "Average TestTime Calibrations Sector ");
+
+          GetAverageHiGainSector(j).GetHGausHist()->SetTitle("TestTime Calibrations Sector ");
+          GetAverageHiGainSector(j).SetNbins(fAverageNbins);
+          GetAverageHiGainSector(j).InitBins();
+          GetAverageHiGainSector(j).ChangeHistId(j);
+          GetAverageHiGainSector(j).SetEventFrequency(fPulserFrequency);
+      }
+  }
+
+
+  if (fAverageLoGainSectors->GetEntries()==0)
+  {
+      fAverageLoGainSectors->Expand(nsectors);
+
+      for (Int_t j=0; j<nsectors; j++)
+      {
+	  (*fAverageLoGainSectors)[j] = 
+            new MHCalibrationTestTimePix("MHCalibrationTestTimeAverageSector",
+                             "Average TestTime Calibrations Sector ");
+
+          GetAverageLoGainSector(j).GetHGausHist()->SetTitle("TestTime Calibrations Sector ");
+          GetAverageLoGainSector(j).SetNbins(fAverageNbins);
+          GetAverageLoGainSector(j).InitBins();
+          GetAverageLoGainSector(j).ChangeHistId(j);
+          GetAverageLoGainSector(j).SetEventFrequency(fPulserFrequency);
+      }
+  }
+    
+
+  return kTRUE;
+}
+
+
+// -------------------------------------------------------------------------------
+//
+// Retrieves pointer to MArrivalTime:
+//
+// Retrieves from MGeomCam:
+// - number of pixels
+// - number of pixel areas
+// - number of sectors
+//
+// Fills HiGain or LoGain histograms (MHGausEvents::FillHistAndArray()), respectively
+// depending on MCerPhotPix::IsLoGainUsed(), with:
+// - MCerPhotPix::GetArrivalTime(pixid) - MCerPhotPix::GetArrivalTime(1);
+//   (i.e. the time difference between pixel i and pixel 1 (hardware number: 2) )
+//
+Bool_t MHCalibrationTestTimeCam::FillHists(const MParContainer *par, const Stat_t w)
+{
+
+  MArrivalTime *calibration = (MArrivalTime*)par;
+  if (!calibration)
+    {
+      gLog << err << "No argument in MHCalibrationRelTimeCam::Fill... abort." << endl;
+      return kFALSE;
+    }
+
+  const Int_t npixels  = fGeom->GetNumPixels();
+  const Int_t nareas   = fGeom->GetNumAreas();
+  const Int_t nsectors = fGeom->GetNumSectors();
+
+  Float_t sumareahi  [nareas]; 
+  Float_t sumsectorhi[nsectors];
+  Int_t   numareahi  [nareas]; 
+  Int_t   numsectorhi[nsectors];
+
+  memset(sumareahi,   0, nareas * sizeof(Float_t));
+  memset(sumsectorhi, 0, nsectors*sizeof(Float_t));
+  
+  for (Int_t i=0; i<npixels; i++)
+    {
+
+      MHGausEvents &histhi = (*this)[i];
+
+      if (histhi.IsExcluded())
+	continue;
+
+      const Float_t  time = (*calibration)[i];
+      const Int_t  aidx   = (*fGeom)[i].GetAidx();
+      const Int_t  sector = (*fGeom)[i].GetSector();
+
+      histhi.FillHistAndArray(time) ;
+      sumareahi  [aidx]   += time;
+      numareahi  [aidx]   ++;
+      sumsectorhi[sector] += time;
+      numsectorhi[sector] ++;
+    }
+  
+  for (Int_t j=0; j<nareas; j++)
+    {
+      MHGausEvents &histhi = GetAverageHiGainArea(j);
+      histhi.FillHistAndArray(numareahi[j] == 0 ? 0. : sumareahi[j]/numareahi[j]);
+
+    }
+  
+  for (Int_t j=0; j<nsectors; j++)
+    {
+      MHGausEvents &histhi = GetAverageHiGainSector(j);
+      histhi.FillHistAndArray(numsectorhi[j] == 0 ? 0. : sumsectorhi[j]/numsectorhi[j]);
+
+    }
+
+  return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// 
+Bool_t MHCalibrationTestTimeCam::FinalizeHists()
+{
+
+  for (Int_t i=0; i<fHiGainArray->GetSize(); i++)
+    {
+      
+      MHGausEvents &hist = (*this)[i];
+      
+      if (hist.IsExcluded())
+        continue;
+      
+      if (hist.IsEmpty())
+        continue;
+      
+      if (!hist.FitGaus())
+        if (!hist.RepeatFit())
+          {
+            hist.BypassFit();
+          }
+      
+      hist.CreateFourierSpectrum();
+      
+    }
+  
+  for (Int_t j=0; j<fAverageHiGainAreas->GetSize(); j++)
+    {
+      
+      MHGausEvents     &hist = GetAverageHiGainArea(j);      
+      if (hist.IsEmpty())
+        continue;
+      
+      if (!hist.FitGaus())
+        if (!hist.RepeatFit())
+          {
+            hist.BypassFit();
+          }
+      
+      hist.CreateFourierSpectrum();
+      
+
+  }
+
+  for (Int_t j=0; j<fAverageHiGainSectors->GetSize(); j++)
+    {
+      
+      MHGausEvents     &hist = GetAverageHiGainSector(j);      
+      if (hist.IsEmpty())
+        continue;
+      
+      if (!hist.FitGaus())
+        if (!hist.RepeatFit())
+          {
+            hist.BypassFit();
+          }
+      hist.CreateFourierSpectrum();
+      
+
+    }
+
+  return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+void MHCalibrationTestTimeCam::FinalizeBadPixels()
+{
+
+}
+
+// --------------------------------------------------------------------------
+//
+// The types are as follows:
+// 
+// Fitted values:
+// ============== 
+//
+// 0: Fitted Mean Time Calibration (MHGausEvents::GetMean())
+// 1: Error Mean Time Calibration  (MHGausEvents::GetMeanErr())
+// 2: Sigma fitted Time Calibration (MHGausEvents::GetSigma())
+// 3: Error Sigma Time Calibration (MHGausEvents::GetSigmaErr())
+//
+// Useful variables derived from the fit results:
+// =============================================
+//
+// 4: Returned probability of Gauss fit              (calls: MHGausEvents::GetProb())
+//
+// Localized defects:
+// ==================
+//
+// 5: Gaus fit not OK                               (calls: MHGausEvents::IsGausFitOK())
+// 6: Fourier spectrum not OK                       (calls: MHGausEvents::IsFourierSpectrumOK())
+//
+Bool_t MHCalibrationTestTimeCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
+{
+
+  if (fHiGainArray->GetSize() <= idx)
+    return kFALSE;
+
+  const MHGausEvents &pix = (*this)[idx];
+
+  if (pix.IsExcluded())
+    return kFALSE;
+
+  switch (type)
+    {
+    case 0:
+      val = pix.GetMean();
+      break;
+    case 1:
+      val = pix.GetMeanErr();
+      break;
+    case 2:
+      val = pix.GetSigma();
+      break;
+    case 3:
+      val = pix.GetSigmaErr();
+      break;
+    case 4:
+      val = pix.GetProb();
+      break;
+    case 5:
+      if (!pix.IsGausFitOK())
+        val = 1.;
+      break;
+    case 6:
+      if (!pix.IsFourierSpectrumOK())
+        val = 1.;
+      break;
+    default:
+      return kFALSE;
+    }
+  return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// Calls MHGausEvents::DrawClone() for pixel idx
+//
+void MHCalibrationTestTimeCam::DrawPixelContent(Int_t idx) const
+{
+ (*this)[idx].DrawClone();
+}
+
+
+//------------------------------------------------------------
+//
+// For all averaged areas, the fitted sigma is multiplied with the square root of 
+// the number involved pixels
+//
+void MHCalibrationTestTimeCam::CalcAverageSigma()
+{
+  
+  for (UInt_t j=0; j<fGeom->GetNumAreas(); j++)
+    {
+  
+      MHGausEvents &hist    = GetAverageHiGainArea(j);
+
+      const Float_t numsqr    = TMath::Sqrt((Float_t)fAverageAreaNum[j]);
+      fAverageAreaSigma[j]    = hist.GetSigma    () * numsqr;
+      fAverageAreaSigmaVar[j] = hist.GetSigmaErr () * hist.GetSigmaErr() * numsqr;
+
+      fAverageAreaRelSigma   [j]  = fAverageAreaSigma[j]    / hist.GetMean();
+      fAverageAreaRelSigmaVar[j]  = fAverageAreaSigmaVar[j] / (fAverageAreaSigma[j]*fAverageAreaSigma[j]);
+      fAverageAreaRelSigmaVar[j] += hist.GetMeanErr()*hist.GetMeanErr()/hist.GetMean()/hist.GetMean();
+      fAverageAreaRelSigmaVar[j] *= fAverageAreaRelSigma[j];
+    }
+}
Index: trunk/MagicSoft/Mars/mcalib/Makefile
===================================================================
--- trunk/MagicSoft/Mars/mcalib/Makefile	(revision 3979)
+++ trunk/MagicSoft/Mars/mcalib/Makefile	(revision 3980)
@@ -58,4 +58,6 @@
            MHCalibrationTestCam.cc \
            MHCalibrationTestPix.cc  \
+           MHCalibrationTestTimeCam.cc \
+           MHCalibrationTestTimePix.cc \
 	   MMcCalibrationCalc.cc \
 	   MHGausEvents.cc 
