Index: /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.cc
===================================================================
--- /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.cc	(revision 3283)
+++ /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.cc	(revision 3283)
@@ -0,0 +1,417 @@
+/* ======================================================================== *\
+!
+! *
+! * 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
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//                                                               
+// MHCalibrationChargeCam                                               
+//                                                               
+// Contains a list of MHCalibrationPix 
+// plus the MHCalibrationBlindPix 
+// and the  MHCalibrationPINDiode
+/////////////////////////////////////////////////////////////////////////////
+#include "MHCalibrationChargeCam.h"
+
+#include "MLog.h"
+#include "MLogManip.h"
+
+#include "MParList.h"
+
+#include "MHCalibrationChargeHiGainPix.h"
+#include "MHCalibrationChargeLoGainPix.h"
+
+#include "MCalibrationChargeCam.h"
+#include "MCalibrationChargePix.h"
+
+#include "MRawEvtData.h"
+#include "MRawEvtPixelIter.h"
+
+#include "MExtractedSignalCam.h"
+#include "MExtractedSignalPix.h"
+
+ClassImp(MHCalibrationChargeCam);
+
+using namespace std;
+
+const Float_t MHCalibrationChargeCam::fgNumHiGainSaturationLimit = 0.01;
+const Float_t MHCalibrationChargeCam::fgNumLoGainSaturationLimit = 0.01;
+//
+//
+//
+MHCalibrationChargeCam::MHCalibrationChargeCam(const char *name, const char *title)
+{
+    fName  = name  ? name  : "MHCalibrationChargeCam";
+    fTitle = title ? title : "";
+
+    fHiGainArray = new TObjArray;
+    fHiGainArray->SetOwner();
+    
+    fLoGainArray = new TObjArray;
+    fLoGainArray->SetOwner();
+
+    SetNumHiGainSaturationLimit();
+    SetNumLoGainSaturationLimit();
+}
+
+// --------------------------------------------------------------------------
+//
+// Delete the TClonesArray of MHCalibrationChargePix containers
+// Delete the MHCalibrationPINDiode and the MHCalibrationBlindPix
+//
+// Delete the histograms if they exist
+//
+MHCalibrationChargeCam::~MHCalibrationChargeCam()
+{
+  delete fHiGainArray;
+  delete fLoGainArray;
+}
+
+// --------------------------------------------------------------------------
+//
+// Get i-th pixel (pixel number)
+//
+MHCalibrationChargeHiGainPix &MHCalibrationChargeCam::operator[](UInt_t i)
+{
+  return *static_cast<MHCalibrationChargeHiGainPix*>(fHiGainArray->UncheckedAt(i));
+}
+
+// --------------------------------------------------------------------------
+//
+// Get i-th pixel (pixel number)
+//
+const MHCalibrationChargeHiGainPix &MHCalibrationChargeCam::operator[](UInt_t i) const
+{
+  return *static_cast<MHCalibrationChargeHiGainPix*>(fHiGainArray->UncheckedAt(i));
+}
+
+// --------------------------------------------------------------------------
+//
+// Get i-th pixel (pixel number)
+//
+MHCalibrationChargeLoGainPix &MHCalibrationChargeCam::operator()(UInt_t i)
+{
+  return *static_cast<MHCalibrationChargeLoGainPix*>(fLoGainArray->UncheckedAt(i));
+}
+
+// --------------------------------------------------------------------------
+//
+// Get i-th pixel (pixel number)
+//
+const MHCalibrationChargeLoGainPix &MHCalibrationChargeCam::operator()(UInt_t i) const
+{
+  return *static_cast<MHCalibrationChargeLoGainPix*>(fLoGainArray->UncheckedAt(i));
+}
+
+// --------------------------------------------------------------------------
+//
+// Our own clone function is necessary since root 3.01/06 or Mars 0.4
+// I don't know the reason
+//
+TObject *MHCalibrationChargeCam::Clone(const char *) const
+{
+    const Int_t nhi = fHiGainArray->GetSize();
+    const Int_t nlo = fLoGainArray->GetSize();
+
+    //
+    // FIXME, this might be done faster and more elegant, by direct copy.
+    //
+    MHCalibrationChargeCam *cam = new MHCalibrationChargeCam;
+
+    cam->fHiGainArray->Expand(nhi);
+    cam->fLoGainArray->Expand(nlo);
+
+    for (int i=0; i<nhi; i++)
+    {
+        delete (*cam->fHiGainArray)[i];
+        (*cam->fHiGainArray)[i] = (*fHiGainArray)[i]->Clone();
+    }
+    for (int i=0; i<nlo; i++)
+    {
+        delete (*cam->fLoGainArray)[i];
+        (*cam->fLoGainArray)[i] = (*fLoGainArray)[i]->Clone();
+    }
+    return cam;
+}
+
+// --------------------------------------------------------------------------
+//
+// To setup the object we get the number of pixels from a MGeomCam object
+// in the Parameter list.
+//
+Bool_t MHCalibrationChargeCam::SetupFill(const MParList *pList)
+{
+  
+  fHiGainArray->Delete();
+  fLoGainArray->Delete();
+  return kTRUE;
+
+}
+
+Bool_t MHCalibrationChargeCam::ReInit(MParList *pList)
+{
+
+  fCam = (MCalibrationChargeCam*)pList->FindCreateObj("MCalibrationChargeCam");
+  if (!fCam)
+  {
+      gLog << err << GetDescriptor() << ": ERROR: Could not find MCalibrationChargeCam ... aborting " << endl;
+      return kFALSE;
+  }
+
+  fRawEvt = (MRawEvtData*)pList->FindObject("MRawEvtData");
+  if (!fRawEvt)
+  {
+      gLog << err << dbginf << "MRawEvtData not found... aborting." << endl;
+      return kFALSE;
+  }
+
+  MExtractedSignalCam *signal = (MExtractedSignalCam*)pList->FindObject("MExtractedSignalCam");
+  if (!signal)
+    {
+      gLog << err << "No argument in MExtractedSignalCam::ReInit... abort." << endl;
+      return kFALSE;
+    }
+  
+  const Int_t n = signal->GetSize();
+
+  fHiGainArray->Expand(n);
+  
+  for (Int_t i=0; i<n; i++)
+  {
+      (*fHiGainArray)[i] = new MHCalibrationChargeHiGainPix;
+      (*this)[i].Init();
+      (*this)[i].ChangeHistId(i);
+      
+  }
+
+  fLoGainArray->Expand(n);
+  
+  for (Int_t i=0; i<n; i++)
+  {
+      (*fLoGainArray)[i] = new MHCalibrationChargeLoGainPix;
+      (*this)(i).Init();
+      (*this)(i).ChangeHistId(i);
+  }
+  
+  return kTRUE;
+}
+
+
+// --------------------------------------------------------------------------
+Bool_t MHCalibrationChargeCam::Fill(const MParContainer *par, const Stat_t w)
+{
+
+  MExtractedSignalCam *signal = (MExtractedSignalCam*)par;
+  if (!signal)
+    {
+      gLog << err << "No argument in MExtractedSignalCam::Fill... abort." << endl;
+      return kFALSE;
+    }
+  
+  const Int_t n = signal->GetSize();
+
+  if (fHiGainArray->GetEntries() != n)
+    {
+      gLog << err << "ERROR - Size mismatch... abort." << endl;
+      return kFALSE;
+    }
+
+  if (fLoGainArray->GetEntries() != n)
+    {
+      gLog << err << "ERROR - Size mismatch... abort." << endl;
+      return kFALSE;
+    }
+  
+  for (int i=0; i<n; i++)
+    {
+      const MExtractedSignalPix &pix = (*signal)[i];
+      
+      const Float_t sumhi  = pix.GetExtractedSignalHiGain();
+      const Float_t sumlo  = pix.GetExtractedSignalLoGain();
+      
+      (*this)[i].FillHistAndArray(sumhi);
+      (*this)(i).FillHistAndArray(sumlo);
+
+      (*this)[i].SetSaturated((Int_t)pix.GetNumHiGainSaturated()); 
+      (*this)(i).SetSaturated((Int_t)pix.GetNumLoGainSaturated()); 
+    }
+
+  MRawEvtPixelIter pixel(fRawEvt);
+  
+  while (pixel.Next())
+    {
+      
+      const UInt_t pixid = pixel.GetPixelId();
+      
+      const Float_t timehi = (Float_t)pixel.GetIdxMaxHiGainSample();
+      const Float_t timelo = (Float_t)pixel.GetIdxMaxLoGainSample();
+
+      (*this)[pixid].FillAbsTime(timehi);
+      (*this)(pixid).FillAbsTime(timelo);
+
+    }
+
+  return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// 1) Return if the charge distribution is already succesfully fitted  
+//    or if the histogram is empty
+// 2) Fit the histograms with a Gaussian
+// 3) In case of failure set the bit kFitted to false and take histogram means and RMS
+// 4) Check for pickup noise
+// 5) Check the fourier spectrum 
+// 5) Retrieve the results and store them in this class
+//
+Bool_t MHCalibrationChargeCam::Finalize()
+{
+    
+    for (int i=0; i<fHiGainArray->GetSize(); i++)
+    {
+     
+	MHCalibrationChargeHiGainPix &pixhi = (*this)[i];
+	MCalibrationChargePix        &pix   = (*fCam)[i];
+
+        if (pixhi.IsEmpty())
+            continue;
+
+	if (pixhi.GetSaturated() > fNumHiGainSaturationLimit*pixhi.GetHGausHist()->GetEntries())
+	{
+	    pix.SetHiGainSaturation();
+	    continue;
+	}
+
+        //
+        // 2) Fit the Hi Gain histograms with a Gaussian
+        //
+	if (pixhi.FitGaus())
+	    pix.SetHiGainFitted();
+        //
+        // 3) In case of failure set the bit kFitted to false and take histogram means and RMS
+        //
+	else if (pixhi.RepeatFit())
+	    pix.SetHiGainFitted();
+	else
+	    pixhi.BypassFit();
+
+	//
+	// 4) Check for pickup
+	//
+	pixhi.CountPickup();
+
+        //
+        // 5) Check for oscillations
+        // 
+	pixhi.CreateFourierSpectrum();
+
+	//
+        // 6) Retrieve the results and store them in this class
+	//
+	pix.SetHiGainMeanCharge(     pixhi.GetMean()     );
+	pix.SetHiGainMeanChargeErr(  pixhi.GetMeanErr()  );
+	pix.SetHiGainSigmaCharge(    pixhi.GetSigma()    );
+	pix.SetHiGainSigmaChargeErr( pixhi.GetSigmaErr() );
+	pix.SetHiGainChargeProb    ( pixhi.GetProb()     );
+
+	pix.SetAbsTimeMean         ( pixhi.GetAbsTimeMean());
+	pix.SetAbsTimeRms          ( pixhi.GetAbsTimeRms() );
+
+	pix.SetHiGainOscillating   ( !pixhi.IsFourierSpectrumOK() );
+	pix.SetHiGainNumPickup     (  pixhi.GetPickup()           );
+    }
+
+    for (int i=0; i<fLoGainArray->GetSize(); i++)
+    {
+     
+	MHCalibrationChargeLoGainPix &pixlo = (*this)(i);
+	MCalibrationChargePix        &pix   = (*fCam)[i];
+
+        if (pixlo.IsEmpty())
+            continue;
+
+	if (pixlo.GetSaturated() > fNumHiGainSaturationLimit*pixlo.GetHGausHist()->GetEntries())
+	{
+	    pix.SetLoGainSaturation();
+	    continue;
+	}
+        //
+        // 2) Fit the Lo Gain histograms with a Gaussian
+        //
+	if (pixlo.FitGaus())
+	    pix.SetLoGainFitted();
+        //
+        // 3) In case of failure set the bit kFitted to false and take histogram means and RMS
+        //
+	else if (pixlo.RepeatFit())
+	    pix.SetLoGainFitted();
+	else
+	    pixlo.BypassFit();
+
+	//
+	// 4) Check for pickup
+	//
+	pixlo.CountPickup();
+
+        //
+        // 5) Check for oscillations
+        // 
+	pixlo.CreateFourierSpectrum();
+
+	//
+        // 6) Retrieve the results and store them in this class
+	//
+	pix.SetLoGainMeanCharge(     pixlo.GetMean()     );
+	pix.SetLoGainMeanChargeErr(  pixlo.GetMeanErr()  );
+	pix.SetLoGainSigmaCharge(    pixlo.GetSigma()    );
+	pix.SetLoGainSigmaChargeErr( pixlo.GetSigmaErr() );
+	pix.SetLoGainChargeProb    ( pixlo.GetProb()     );
+
+	if (pix.IsHiGainSaturation())
+	{
+	    pix.SetAbsTimeMean     ( pixlo.GetAbsTimeMean());
+	    pix.SetAbsTimeRms      ( pixlo.GetAbsTimeRms() );
+	}	    
+
+	pix.SetLoGainOscillating   ( !pixlo.IsFourierSpectrumOK() );
+	pix.SetLoGainNumPickup     (  pixlo.GetPickup()           );
+
+    }
+
+    return kTRUE;
+}
+
+Bool_t MHCalibrationChargeCam::GetPixelContent(Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type) const
+{
+  return kTRUE;
+}
+
+// --------------------------------------------------------------------------
+//
+// What MHCamera needs in order to draw an individual pixel in the camera
+//
+void MHCalibrationChargeCam::DrawPixelContent(Int_t idx) const
+{
+  (*this)[idx].DrawClone();
+}
+
Index: /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.h
===================================================================
--- /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.h	(revision 3283)
+++ /trunk/MagicSoft/Mars/mcalib/MHCalibrationChargeCam.h	(revision 3283)
@@ -0,0 +1,76 @@
+#ifndef MARS_MHCalibrationChargeCam
+#define MARS_MHCalibrationChargeCam
+
+#ifndef ROOT_TObjArray
+#include <TObjArray.h>
+#endif
+
+#ifndef MARS_MH
+#include "MH.h"
+#endif
+#ifndef MARS_MCamEvent
+#include "MCamEvent.h"
+#endif
+
+class MRawEvtData;
+class MCalibrationChargeCam;
+class MHCalibrationChargeHiGainPix;
+class MHCalibrationChargeLoGainPix;
+class MHCalibrationChargeCam : public MH, public MCamEvent
+{
+private:
+
+  static const Float_t fgNumHiGainSaturationLimit; // The default number of fNumHiGainSaturationLimit
+  static const Float_t fgNumLoGainSaturationLimit; // The default number of fNumLoGainSaturationLimit
+
+  Float_t fNumHiGainSaturationLimit;      // The rel. number of saturated higain FADC slices in the whole run upon which the pixel is called saturated
+  Float_t fNumLoGainSaturationLimit;      // The rel. number of saturated logain FADC slices in the whole run upon which the pixel is called saturated
+  
+  TObjArray *fHiGainArray;                //-> Array of MHCalibrationChargePix with hists
+  TObjArray *fLoGainArray;                //-> Array of MHCalibrationChargePix with hists
+  
+  MCalibrationChargeCam  *fCam;           //!  Class holding the results
+  MRawEvtData            *fRawEvt;        //!  Raw event data (time slices)
+
+
+public:
+
+  MHCalibrationChargeCam(const char *name=NULL, const char *title=NULL);
+  ~MHCalibrationChargeCam();
+
+  void SetNumHiGainSaturationLimit( const Float_t lim=fgNumHiGainSaturationLimit) { fNumHiGainSaturationLimit = lim; }
+  void SetNumLoGainSaturationLimit( const Float_t lim=fgNumLoGainSaturationLimit) { fNumLoGainSaturationLimit = lim; }
+
+  Float_t GetNumHiGainSaturationLimit()                             const  { return fNumHiGainSaturationLimit; }
+  Float_t GetNumLoGainSaturationLimit()                             const  { return fNumLoGainSaturationLimit; }
+
+  
+  MHCalibrationChargeHiGainPix &operator[](UInt_t i);
+  const MHCalibrationChargeHiGainPix &operator[](UInt_t i) const;
+
+  MHCalibrationChargeLoGainPix &operator()(UInt_t i);
+  const MHCalibrationChargeLoGainPix &operator()(UInt_t i) const;
+
+  Bool_t SetupFill(const MParList *pList);
+  Bool_t ReInit   (      MParList *pList);
+  Bool_t Fill     (const MParContainer *par, const Stat_t w=1);
+  Bool_t Finalize ( );
+  
+  TObject *Clone(const char *) const;
+
+  Bool_t GetPixelContent ( Double_t &val, Int_t idx, const MGeomCam &cam, Int_t type=0) const;
+  void   DrawPixelContent( Int_t num )  const;    
+
+  ClassDef(MHCalibrationChargeCam, 1)	// Container for calibration information of the camera
+};
+
+#endif
+
+
+
+
+
+
+
+
+
