Index: trunk/MagicSoft/Mars/mcalib/MCalibrationPINDiode.cc
===================================================================
--- trunk/MagicSoft/Mars/mcalib/MCalibrationPINDiode.cc	(revision 2922)
+++ trunk/MagicSoft/Mars/mcalib/MCalibrationPINDiode.cc	(revision 2931)
@@ -44,13 +44,8 @@
 //
 MCalibrationPINDiode::MCalibrationPINDiode(const char *name, const char *title)
-  : fHist(NULL),
-    fCharge(-1.),
-    fErrCharge(-1.),
-    fPed(-1.),
-    fPedRms(-1.),
-    fSigmaCharge(-1.),
-    fErrSigmaCharge(-1.),
-    fTime(-1.),
-    fErrTime(-1.)
+    : fChargeLimit(3.),
+      fChargeErrLimit(0.),
+      fChargeRelErrLimit(1.),
+      fFlags(0)
 {
 
@@ -62,5 +57,7 @@
   if (!fHist)
     *fLog << warn << dbginf << " Could not create MHCalibrationPINDiode " << endl;
-  
+ 
+  Clear();
+
 }
 
@@ -77,15 +74,131 @@
 {
   fHist->Reset();
+
+  CLRBIT(fFlags, kExcluded);
+  CLRBIT(fFlags, kFitValid);
+  CLRBIT(fFlags, kFitted);
+
+  fCharge                           =  -1.;
+  fErrCharge                        =  -1.;
+  fSigmaCharge                      =  -1.;
+  fErrSigmaCharge                   =  -1.;
+  fRSigmaSquare                     =  -1.;
+  fChargeProb                       =  -1.;
+  fPed                              =  -1.;
+  fPedRms                           =  -1.;
+  fTime                             =  -1.;
+  fSigmaTime                        =  -1.;
+  fTimeChiSquare                    =  -1.;
+
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Set the pedestals from outside
+//
+void MCalibrationPINDiode::SetPedestal(Float_t ped, Float_t pedrms)
+{
+
+  fPed    = ped;    
+  fPedRms = pedrms;
+  
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the Excluded Bit from outside 
+//
+void MCalibrationPINDiode::SetExcluded(Bool_t b )
+{ 
+  b ?  SETBIT(fFlags, kExcluded) : CLRBIT(fFlags, kExcluded); 
+}
+
+
+// --------------------------------------------------------------------------
+//
+// Set the Excluded Bit from outside 
+//
+void MCalibrationPINDiode::SetExcludeQualityCheck(Bool_t b )
+{ 
+  b ?  SETBIT(fFlags, kExcludeQualityCheck) : CLRBIT(fFlags, kExcludeQualityCheck); 
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the Excluded Bit from outside 
+//
+void MCalibrationPINDiode::SetFitValid(Bool_t b )    
+{ 
+  b ?  SETBIT(fFlags, kFitValid) : CLRBIT(fFlags, kFitValid); 
+}
+
+// --------------------------------------------------------------------------
+//
+// Set the Excluded Bit from outside 
+//
+void MCalibrationPINDiode::SetFitted(Bool_t b )
+{ 
+  b ?  SETBIT(fFlags, kFitted) : CLRBIT(fFlags, kFitted); 
+}
+
+Bool_t MCalibrationPINDiode::IsExcluded() const
+ { 
+   return TESTBIT(fFlags,kExcluded);  
+ }
+
+Bool_t MCalibrationPINDiode::IsFitValid() const 
+{
+  return TESTBIT(fFlags, kFitValid);  
+}
+
+Bool_t MCalibrationPINDiode::IsFitted() const 
+{ 
+  return TESTBIT(fFlags, kFitted);    
 }
 
 Bool_t MCalibrationPINDiode::FitCharge() 
 {
-  if(!fHist->FitCharge())
-    return kFALSE;
-
+
+  //
+  // 1) Return if the charge distribution is already succesfully fitted  
+  //    or if the histogram is empty
+  //
+  if (fHist->IsFitOK() || fHist->IsEmpty())
+    return kTRUE;
+
+  //
+  // 4) Fit the Lo Gain histograms with a Gaussian
+  //
+  if(fHist->FitCharge())
+    {
+      SETBIT(fFlags,kFitted);
+    }
+  else
+    {
+      *fLog << warn << "WARNING: Could not fit charges of PINDiode " << endl;
+      //          
+      // 5) In case of failure print out the fit results
+      //
+      //	  fHist->PrintChargeFitResult();
+      CLRBIT(fFlags,kFitted);
+    }
+
+  //
+  // 6) Retrieve the results and store them in this class
+  //
   fCharge         = fHist->GetChargeMean();
   fErrCharge      = fHist->GetChargeMeanErr(); 
   fSigmaCharge    = fHist->GetChargeSigma();
   fErrSigmaCharge = fHist->GetChargeSigmaErr();
+  fChargeProb     = fHist->GetChargeProb();
+
+  if (CheckChargeFitValidity())
+    SETBIT(fFlags,kFitValid);
+  else
+    {
+      CLRBIT(fFlags,kFitValid);
+      return kFALSE;
+    }
 
   return kTRUE;
@@ -93,14 +206,97 @@
 }
 
+//
+// The check return kTRUE if:
+//
+// 1) PINDiode has a fitted charge greater than 5*PedRMS
+// 2) PINDiode has a fit error greater than 0.
+// 3) PINDiode has a fitted charge greater its charge error
+// 4) PINDiode has a fit Probability greater than 0.0001 
+// 5) PINDiode has a charge sigma bigger than its Pedestal RMS
+// 
+Bool_t MCalibrationPINDiode::CheckChargeFitValidity()
+{
+
+  if (TESTBIT(fFlags,kExcludeQualityCheck))
+    return kTRUE;
+
+  if (fCharge < fChargeLimit*GetPedRms())
+    {
+      *fLog << warn << "WARNING: Fitted Charge is smaller than "
+            << fChargeLimit << " Pedestal RMS in PINDiode " << endl;
+      return kFALSE;
+    }
+  
+  if (fErrCharge < fChargeErrLimit) 
+    {
+      *fLog << warn << "WARNING: Error of Fitted Charge is smaller than "
+            << fChargeErrLimit << " in PINDiode " << endl;
+      return kFALSE;
+    }
+      
+  if (fCharge < fChargeRelErrLimit*fErrCharge) 
+    {
+      *fLog << warn << "WARNING: Fitted Charge is smaller than "
+            << fChargeRelErrLimit << "* its error in PINDiode " << endl;
+      return kFALSE;
+    }
+      
+  if (!fHist->IsFitOK()) 
+    {
+      *fLog << warn << "WARNING: Probability of Fitted Charge too low in PINDiode " << endl;
+      return kFALSE;
+    }
+
+  if (fSigmaCharge < GetPedRms())
+    {
+      *fLog << warn << "WARNING: Sigma of Fitted Charge smaller than Pedestal RMS in PINDiode " << endl;
+      return kFALSE;
+    }
+  return kTRUE;
+}
+
+
+// --------------------------------------------------------------------------
+//
+// 1) Fit the arrival times
+// 2) Retrieve the results
+// 3) Note that because of the low number of bins, the NDf is sometimes 0, so 
+//    Root does not give a reasonable Probability, the Chisquare is more significant
+//
 Bool_t MCalibrationPINDiode::FitTime() 
 {
 
   if(!fHist->FitTimeHiGain())
-    return kFALSE;
-
-  fTime    = fHist->GetTime();
-  fErrTime = fHist->GetErrTime();
-  
+    {
+      *fLog << warn << "WARNING: Could not fit Hi Gain times of PIN Diode" << endl;
+      fHist->PrintTimeFitResult();
+      return kFALSE;
+    }
+  
+  fTime          = fHist->GetTimeMean();
+  fSigmaTime     = fHist->GetTimeSigma();
+  fTimeChiSquare = fHist->GetTimeChiSquare();
+  fTimeProb      = fHist->GetTimeProb();
+  
+  if (CheckTimeFitValidity())
+    SETBIT(fFlags,kFitValid);
+  else
+    CLRBIT(fFlags,kFitValid);
+
   return kTRUE;
-
-}
+}
+
+//
+// The check returns kTRUE if:
+//
+// The mean arrival time is at least 1.0 slices from the used edge slices 
+//
+Bool_t MCalibrationPINDiode::CheckTimeFitValidity()
+{
+
+  if (TESTBIT(fFlags,kExcludeQualityCheck))
+    return kTRUE;
+
+  return kTRUE;
+}
+
