Index: trunk/MagicSoft/Mars/mimage/MImgCleanStd.cc
===================================================================
--- trunk/MagicSoft/Mars/mimage/MImgCleanStd.cc	(revision 8619)
+++ trunk/MagicSoft/Mars/mimage/MImgCleanStd.cc	(revision 8646)
@@ -21,5 +21,5 @@
 !   Author(s): Stefan Ruegamer, 03/2006 <mailto:snruegam@astro.uni-wuerzburg.de>
 !
-!   Copyright: MAGIC Software Development, 2000-2006
+!   Copyright: MAGIC Software Development, 2000-2007
 !
 !
@@ -279,4 +279,12 @@
 //
 //
+//  Class Version 4:
+//  ----------------
+//   + Float_t  fTimeLvl2;
+//   - Bool_t   fKeepSinglePixels;
+//   + Bool_t   fKeepIsolatedPixels;
+//   + Int_t    fRecoverIsolatedPixels;
+//
+//
 //  Input Containers:
 //   MGeomCam
@@ -302,4 +310,5 @@
 #include "MLogManip.h"
 
+#include "MArrayI.h"
 #include "MParList.h"
 #include "MCameraData.h"
@@ -339,11 +348,30 @@
 MImgCleanStd::MImgCleanStd(const Float_t lvl1, const Float_t lvl2,
                            const char *name, const char *title)
-    : fCleaningMethod(kStandard), fCleanLvl1(lvl1),
-    fCleanLvl2(lvl2), fCleanRings(1), fKeepSinglePixels(kFALSE),
-    fNamePedPhotCam(gsNamePedPhotCam), fNameGeomCam(gsNameGeomCam),
-    fNameSignalCam(gsNameSignalCam)
+    : fCleaningMethod(kStandard), fCleanLvl0(lvl1), fCleanLvl1(lvl1),
+    fCleanLvl2(lvl2), fTimeLvl1(1.5), fTimeLvl2(1.5), fCleanRings(1),
+    fKeepIsolatedPixels(kFALSE), fRecoverIsolatedPixels(0),
+    fPostCleanType(0), fNamePedPhotCam(gsNamePedPhotCam),
+    fNameGeomCam(gsNameGeomCam), fNameSignalCam(gsNameSignalCam)
 {
     fName  = name  ? name  : gsDefName.Data();
     fTitle = title ? title : gsDefTitle.Data();
+}
+
+void MImgCleanStd::ResetCleaning() const
+{
+    //
+    // check the number of all pixels against the noise level and
+    // set them to 'unused' state if necessary
+    //
+    const UInt_t npixevt = fEvt->GetNumPixels();
+    for (UInt_t idx=0; idx<npixevt; idx++)
+    {
+        MSignalPix &pix = (*fEvt)[idx];
+        if (pix.IsPixelUnmapped())
+            continue;
+
+        pix.SetPixelUnused();
+        pix.SetPixelCore(kFALSE);
+    }
 }
 
@@ -367,7 +395,118 @@
 //
 //
-void MImgCleanStd::CleanStep1()
-{
+Bool_t MImgCleanStd::HasCoreNeighbors(const MGeomPix &gpix) const
+{
+//    if (fKeepIsolatedPixels)
+//        return kTRUE;
+
+#ifdef DEBUG
     const TArrayD &data = fData->GetData();
+#else
+    const Double_t *data = fData->GetData().GetArray();
+#endif
+
+    //loop on the neighbors to check if they are used
+    const Int_t n = gpix.GetNumNeighbors();
+    for (Int_t i=0; i<n; i++)
+    {
+        const Int_t idx = gpix.GetNeighbor(i);
+
+        // Check if a neighborpixel of our core pixel is
+        // also a core pixel
+        if (data[idx]<=fCleanLvl1)
+            continue;
+
+        // Ignore unmapped pixels
+        MSignalPix &pix = (*fEvt)[idx];
+        if (pix.IsPixelUnmapped())
+            continue;
+
+        return kTRUE;
+    }
+
+    return kFALSE;
+}
+
+Bool_t MImgCleanStd::HasUsedNeighbors(const MGeomPix &gpix) const
+{
+    //loop on the neighbors to check if they are used
+    const Int_t n = gpix.GetNumNeighbors();
+    for (Int_t i=0; i<n; i++)
+    {
+        const Int_t idx = gpix.GetNeighbor(i);
+
+        MSignalPix &pix = (*fEvt)[idx];
+
+        // Check if a neighborpixel of our core pixel is
+        // also a core pixel
+        if (pix.IsPixelUsed() && !pix.IsPixelUnmapped())
+            return kTRUE;
+    }
+
+    return kFALSE;
+}
+
+
+void MImgCleanStd::SetUsedNeighbors(const MGeomPix &gpix, Int_t r) const
+{
+    if (r>fCleanRings)
+        return;
+
+#ifdef DEBUG
+    const TArrayD &data = fData->GetData();
+#else
+    const Double_t *data = fData->GetData().GetArray();
+#endif
+
+    // At least one neighbor has been identified as core,
+    // that means we will keep the pixel
+    const Int_t n = gpix.GetNumNeighbors();
+    for (Int_t i=0; i<n; i++)
+    {
+        const Int_t idx = gpix.GetNeighbor(i);
+
+        MSignalPix &pix = (*fEvt)[idx];
+
+        // If the pixel has been assigned to the same or a previous
+        // ring we don't have to proceed. We have to try to set the
+        // ring number of each pixel as low as possible. This means
+        // we are only allowed to increase the ring number.
+        if (pix.IsPixelUsed() && pix.GetRing()<=r)
+            continue;
+
+        // All pixels below the second cleaning level should be ignored
+        if (data[idx] <= fCleanLvl2)
+            continue;
+
+        // Ignore unmapped pixels (remark: used (aka. ring>0)
+        // and unmapped status is exclusive
+        if (pix.IsPixelUnmapped())
+            continue;
+
+        // Set or reset the ring number
+        pix.SetRing(r);
+
+        // Step forward to the surrounding pixels
+        SetUsedNeighbors((*fCam)[idx], r+1);
+    }
+}
+
+// --------------------------------------------------------------------------
+//
+// Here we do the cleaning. We search for all the possible core candidates
+// and from them on we recursively search for used pixels with
+// SetUsedNeighbors. To check the validity of a core pixel
+// either fTimeLvl2 and/or HasCoreNeighbors is used.
+// The size of all removed
+Int_t MImgCleanStd::DoCleaning(Float_t &size) const
+{
+    Int_t n = 0;
+    size = 0;
+
+#ifdef DEBUG
+    const TArrayD &data = fData->GetData();
+#else
+    const Double_t *data = fData->GetData().GetArray();
+#endif
 
     //
@@ -378,183 +517,213 @@
     for (UInt_t idx=0; idx<npixevt; idx++)
     {
-        // The default for pixels is "used" set by
-        // MParContainer::Reset before processing
-        if (data[idx]>fCleanLvl1)
-            continue;
-
-        // Setting a pixel to unused if it is unmapped would overwrite
-        // the unmapped-status. Therefor this pixels are excluded.
         MSignalPix &pix = (*fEvt)[idx];
-        if (!pix.IsPixelUnmapped())
-            pix.SetPixelUnused();
-    }
-}
-
-// --------------------------------------------------------------------------
-//
-//  Check if the survived pixel have a neighbor, that also
-//  survived. Set all single pixels Unused if !fKeepSinglePixels. Now we
-//  declare all pixels that survived previous CleanSteps as CorePixels.
-//  Return number of single pixels, and there cumulative size in size.
-//
-Short_t MImgCleanStd::CleanStep2(Float_t &size)
-{
-    Short_t n=0;
-    size = 0;
-
+
+        // Check if this pixel is a possible candidate for a core pixel
+        if (data[idx] <= fCleanLvl1)
+            continue;
+
+        // Ignore unmapped pixels
+        if (pix.IsPixelUnmapped())
+            continue;
+
+        const MGeomPix &gpix = (*fCam)[idx];
+
+        // Check if the pixel is an isolated core pixel
+        if (!HasCoreNeighbors(gpix))
+        {
+            // Count size and number of isolated core pixels
+            size += pix.GetNumPhotons();
+            n++;
+
+            // If isolated pixels should not be kept or the pixel
+            // is lower than the cleaning level for isolated core
+            // pixels. It is not treated as core pixel.
+            if (!fKeepIsolatedPixels || data[idx]<=fCleanLvl0)
+                continue;
+        }
+
+        // Mark pixel as used and core
+        pix.SetPixelUsed();
+        pix.SetPixelCore();
+
+        // Check if neighbor pixels should be marked as used
+        // This is done recursively depening on fCleanRings
+        SetUsedNeighbors(gpix);
+    }
+
+    return n;
+}
+
+/*
+Float_t MImgCleanStd::GetArrivalTimeNeighbor(const MGeomPix &gpix) const
+{
+    Float_t min = FLT_MAX;
+
+    const Int_t n = gpix.GetNumNeighbors();
+    for (int i=0; i<n; i++)
+    {
+        const Int_t idx = gpix.GetNeighbor(i);
+
+        const MSignalPix &pix = (*fEvt)[idx];
+        // FIXME: Check also used pixels?
+        if (!pix.IsCorePixel())
+            continue;
+
+        const Float_t tm = pix.GetArrivalTime();
+        if (tm<min)
+            min = tm;
+    }
+
+    return tm;
+}
+
+void MImgCleanStd::CheckUsedPixelsForArrivalTime(Float_t timediff) const
+{
+    const MArrayD &data = fData->GetData();
+
+    //
+    // check the number of all pixels against the noise level and
+    // set them to 'unused' state if necessary
+    //
     const UInt_t npixevt = fEvt->GetNumPixels();
     for (UInt_t idx=0; idx<npixevt; idx++)
     {
-        // Exclude all unused (this includes all unmapped) pixels
         MSignalPix &pix = (*fEvt)[idx];
+
+        // If pixel has previously been marked used, ignore
+        if (!pix.IsPixelUsed() || pix.IsPixelCore())
+            continue;
+
+        const MGeomPix &gpix = (*fCam)[idx];
+
+        // If isolated possible-corepixel doesn't have used
+        // neighbors, ignore it
+        const Float_t tm0 = pix.GetArrivalTime();
+        const Float_t tm1 = GetArrivalTimeCoreNeighbor(gpix);
+
+        if (TMath::Abs(tm0-tm1)<timediff)
+            continue;
+
+        // Mark pixel as used and core
+        pix.SetPixelUnused();
+    }
+}
+*/
+
+Int_t MImgCleanStd::RecoverIsolatedPixels(Float_t &size) const
+{
+#ifdef DEBUG
+    const TArrayD &data = fData->GetData();
+#else
+    const Double_t *data = fData->GetData().GetArray();
+#endif
+
+    Int_t n = 0;
+
+    //
+    // check the number of all pixels against the noise level and
+    // set them to 'unused' state if necessary
+    //
+    const UInt_t npixevt = fEvt->GetNumPixels();
+    for (UInt_t idx=0; idx<npixevt; idx++)
+    {
+        MSignalPix &pix = (*fEvt)[idx];
+
+        // If pixel has previously been marked used, ignore
+        if (pix.IsPixelUsed())
+            continue;
+
+        // If pixel is not a candidate for a core pixel, ignore
+        if (data[idx] <= fCleanLvl1)
+            continue;
+
+        const MGeomPix &gpix = (*fCam)[idx];
+
+        // If isolated possible-corepixel doesn't have used
+        // neighbors, ignore it
+        if (!HasUsedNeighbors(gpix))
+            continue;
+
+        // Mark pixel as used and core
+        pix.SetPixelUsed();
+        pix.SetPixelCore();
+
+        // Check if neighbor pixels should be marked as used
+        // This is done recursively depening on fCleanRings
+        SetUsedNeighbors(gpix);
+
+        size -= pix.GetNumPhotons();
+        n++;
+    }
+
+    return n;
+}
+
+void MImgCleanStd::CleanTime(Int_t n, Double_t lvl) const
+{
+    MArrayI indices;
+
+    const UInt_t npixevt = fEvt->GetNumPixels();
+    for (UInt_t idx=0; idx<npixevt; idx++)
+    {
+        // check if pixel is used or not
+        const MSignalPix &pix = (*fEvt)[idx];
         if (!pix.IsPixelUsed())
             continue;
- 
-        // check for 'used' neighbors of this pixel
-        const MGeomPix &gpix  = (*fCam)[idx];
-        const Int_t     nnmax = gpix.GetNumNeighbors();
-
-        Bool_t hasNeighbor = kFALSE;
-
-	//loop on the neighbors to check if they are used
-        for (Int_t j=0; j<nnmax; j++)
+
+        // get arrival time
+        const Double_t tm0 = pix.GetArrivalTime();
+
+        // loop over its neighbpors
+        const MGeomPix &gpix = (*fCam)[idx];
+
+        Int_t cnt = 0;
+        for (Int_t i=0; i<gpix.GetNumNeighbors(); i++)
         {
-            const Int_t idx2 = gpix.GetNeighbor(j);
-
-            // when you find an used neighbor (this excludes unused
-            // and unmapped pixels) break the loop
-            if ((*fEvt)[idx2].IsPixelUsed())
-            {
-                hasNeighbor = kTRUE;
+            // Get index of neighbor
+            const Int_t idx2 = gpix.GetNeighbor(i);
+
+            // check if neighbor is used or not
+            const MSignalPix &npix = (*fEvt)[idx2];
+            if (!npix.IsPixelUsed())
+                continue;
+
+            // If this pixel is to far away (in arrival time) don't count
+            if (TMath::Abs(npix.GetArrivalTime()-tm0)>lvl)
+                continue;
+
+            // Now count the pixel. If we did not found n pixels yet
+            // which fullfill the condition, go on searching
+            if (++cnt>=n)
                 break;
-            }
         }
 
-        // If the pixel has at least one core-neighbor
-        // go on with the next pixel
-        if (hasNeighbor)
-            continue;
-
-        // If the pixel has no neighbors and the single pixels
-        // should not be kept turn the used- into an unused-status
-        if (!fKeepSinglePixels)
-            pix.SetPixelUnused();
-
-        // count size and number of single core-pixels
-        size += pix.GetNumPhotons();
-        n++;
-    }
-
-    // Now turn the used-status into the core-status
-    // (FIXME: A more intelligent handling of used/core in clean step1/2
-    //         would make this loop obsolete!)
-    for (UInt_t idx=0; idx<npixevt; idx++)
-    {
-        MSignalPix &pix = (*fEvt)[idx];
-        pix.SetPixelCore(pix.IsPixelUsed());
-    }
-
-    return n;
-} 
-
-void MImgCleanStd::CleanStep3b(Int_t idx)
-{
-    MSignalPix &pix = (*fEvt)[idx];
-
-    //
-    // check if the pixel's next neighbor is a core pixel.
-    // if it is a core pixel set pixel state to: used.
-    //
-    MGeomPix   &gpix  = (*fCam)[idx];
-    const Int_t nnmax = gpix.GetNumNeighbors();
-
-    for (Int_t j=0; j<nnmax; j++)
-    {
-        const Int_t idx2 = gpix.GetNeighbor(j);
-
-        // Check if the neighbor pixel is a core pixel. (Rem: Unampped
-        // pixels are never assigned the core-pixel status)
-	if (!(*fEvt)[idx2].IsPixelCore())
-            continue;
-
-        pix.SetPixelUsed();
-       	break;
-    }
-}
-
-// --------------------------------------------------------------------------
-//
-//   NT: Add option "rings": default value = 1. 
-//   Look n (n>1) times for the boundary pixels around the used pixels.
-//   If a pixel has more than 2.5 (clean level 2.5) sigma,
-//   it is declared as used.
-//
-//   If a value<2 for fCleanRings is used, no CleanStep4 is done.
-//
-void MImgCleanStd::CleanStep4(UShort_t r, Int_t idx)
-{
-    MSignalPix &pix = (*fEvt)[idx];
-
-    //
-    // Skip events that have already a defined status;
-    //
-    if (pix.GetRing() != 0)
+        // If we found at least n neighbors which are
+        // with a time difference of lvl keep the pixel
+        if (cnt>=n)
+            continue;
+
+        indices.Set(indices.GetSize()+1);
+        indices[indices.GetSize()-1] = idx;
+    }
+
+    // Now remove the pixels which didn't fullfill the requirement
+    for (UInt_t i=0; i<indices.GetSize(); i++)
+    {
+        (*fEvt)[indices[i]].SetPixelUnused();
+        (*fEvt)[indices[i]].SetPixelCore(kFALSE);
+    }
+}
+
+void MImgCleanStd::CleanStepTime() const
+{
+    if (fPostCleanType<=0)
         return;
 
-    //
-    // check if the pixel's next neighbor is a used pixel.
-    // if it is a used pixel set pixel state to: used,
-    // and tell to which ring it belongs to.
-    //
-    MGeomPix  &gpix = (*fCam)[idx];
-
-    const Int_t nnmax = gpix.GetNumNeighbors();
-
-    for (Int_t j=0; j<nnmax; j++)
-    {
-        const Int_t idx2 = gpix.GetNeighbor(j);
-
-        const MSignalPix &npix = (*fEvt)[idx2];
-        if (!npix.IsPixelUsed() || npix.GetRing()>r-1 )
-            continue;
-
-        pix.SetRing(r);
-        break;
-    }
-}
-
-// --------------------------------------------------------------------------
-//
-//  Look for the boundary pixels around the core pixels
-//  if a pixel has more than 2.5 (clean level 2.5) sigma, and
-//  a core neighbor, it is declared as used.
-//
-void MImgCleanStd::CleanStep3()
-{
-    const TArrayD &data = fData->GetData();
-
-    for (UShort_t r=1; r<fCleanRings+1; r++)
-    {
-        // Loop over all pixels
-        const UInt_t npixevt = fEvt->GetNumPixels();
-        for (UInt_t idx=0; idx<npixevt; idx++)
-        {
-            MSignalPix &pix = (*fEvt)[idx];
-
-            //
-	    // if pixel is a core pixel or unmapped, go to the next pixel
-            //
-            if (pix.IsPixelCore() || pix.IsPixelUnmapped())
-                continue;
-
-            if (data[idx] <= fCleanLvl2)
-                continue;
-
-            if (r==1)
-                CleanStep3b(idx);
-            else
-                CleanStep4(r, idx);
-        }
-    }
+    if (fPostCleanType&2)
+        CleanTime(2, fTimeLvl2);
+
+    if (fPostCleanType&1)
+        CleanTime(1, fTimeLvl1);
 }
 
@@ -572,5 +741,4 @@
         return kFALSE;
     }
-
     fEvt = (MSignalCam*)pList->FindObject(AddSerialNumber(fNameSignalCam), "MSignalCam");
     if (!fEvt)
@@ -595,4 +763,33 @@
         return kFALSE;
 
+    if (fCleanLvl2>fCleanLvl1)
+    {
+        *fLog << warn << "WARNING - fCleanLvl2 (" << fCleanLvl2 << ") > fCleanLvl1 (" << fCleanLvl1 << ")... resetting fCleanLvl2." << endl;
+        fCleanLvl2 = fCleanLvl1;
+    }
+
+    if (fCleanLvl2==fCleanLvl1 && fCleanRings>0)
+    {
+        *fLog << warn << "WARNING - fCleanLvl2 == fCleanLvl1 (" << fCleanLvl1 << ") but fCleanRings>0... resetting fCleanRings to 0." << endl;
+        fCleanRings=0;
+    }
+
+    if (fKeepIsolatedPixels && fTimeLvl2<fCleanLvl1)
+    {
+        *fLog << warn << "WARNING - fKeepIsolatedPixels set but CleanLvl0 (" << fTimeLvl2 << ") < fCleanLvl1 (" << fCleanLvl1 << ")... resetting fTimeLvl2." << endl;
+        fTimeLvl2 = fCleanLvl1;
+    }
+    if (!fKeepIsolatedPixels && fTimeLvl2>fCleanLvl1)
+    {
+        *fLog << warn << "WARNING - fKeepIsolatedPixels not set but CleanLvl0 (" << fTimeLvl2 << ") > fCleanLvl1 (" << fCleanLvl1 << ")... setting fKeepIsolatedCorePixels." << endl;
+        fKeepIsolatedPixels=kTRUE;
+    }
+
+    if (fKeepIsolatedPixels && fTimeLvl2==fCleanLvl1 && fRecoverIsolatedPixels!=0)
+    {
+        *fLog << warn << "WARNING - fTimeLvl2 == fCleanLvl1 (" << fTimeLvl2 << ") and fKeepSinglePixels and fRecoverIsolatedPixels!=0... setting fRecoverIsolatedPixels=0." << endl;
+        fRecoverIsolatedPixels = 0;
+    }
+
     Print();
 
@@ -631,28 +828,36 @@
 
 #ifdef DEBUG
-    *fLog << all << "CleanStep 1" << endl;
+    *fLog << all << "ResetCleaning" << endl;
 #endif
-    CleanStep1();
-
+    ResetCleaning();
 
 #ifdef DEBUG
-    *fLog << all << "CleanStep 2" << endl;
+    *fLog << all << "DoCleaning" << endl;
 #endif
     Float_t size;
-    const Short_t n = CleanStep2(size);
+    Short_t n = DoCleaning(size);
+
+#ifdef DEBUG
+    *fLog << all << "RecoverIsolatedPixels" << endl;
+#endif
+    for (UInt_t i=0; i<(UInt_t)fRecoverIsolatedPixels; i++)
+    {
+        const Int_t rc=RecoverIsolatedPixels(size);
+        if (rc==0)
+            break;
+
+        n -= rc;
+    }
+
+#ifdef DEBUG
+    *fLog << all << "Time Cleaning" << endl;
+#endif
+    // FIXME: Remove removed core piselx?
+    CleanStepTime();
+
     fEvt->SetSinglePixels(n, size);
 
-    // For speed reasons skip the rest of the cleaning if no
-    // action will be taken!
-    if (fCleanLvl1>fCleanLvl2)
-    {
 #ifdef DEBUG
-        *fLog << all << "CleanStep 3" << endl;
-#endif
-        CleanStep3();
-    }
-
-#ifdef DEBUG
-    *fLog << all << "Calc Islands" << endl;
+    *fLog << all << "CalcIslands" << endl;
 #endif
     // Takes roughly 10% of the time
@@ -698,4 +903,26 @@
     *fLog << "initialized with level " << fCleanLvl1 << " and " << fCleanLvl2;
     *fLog << " (CleanRings=" << fCleanRings << ")" << endl;
+
+    if (fPostCleanType)
+    {
+        *fLog << "Time post cleaning is switched on with:" << endl;
+        if (fPostCleanType&2)
+            *fLog << " - Two pixel coincidence window: " << fTimeLvl2 << "ns" << endl;
+        if (fPostCleanType&1)
+            *fLog << " - One pixel coincidence window: " << fTimeLvl1 << "ns" << endl;
+    }
+
+    if (fKeepIsolatedPixels)
+        *fLog << "isolated core pixels will be kept above " << fCleanLvl0 << endl;
+
+    if (fRecoverIsolatedPixels)
+    {
+        if (fRecoverIsolatedPixels<0)
+            *fLog << "all ";
+        *fLog << "isolated core pixels with used pixels as neighbors will be recovered";
+        if (fRecoverIsolatedPixels>0)
+            *fLog << " " << fRecoverIsolatedPixels << " times";
+        *fLog << "." << endl;;
+    }
 
     if (fCleaningMethod!=kAbsolute && fCleaningMethod!=kTime)
@@ -848,6 +1075,8 @@
     if (gsNameSignalCam!=fNameSignalCam)
         out << "   " << GetUniqueName() << ".SetNameSignalCam(\"" << fNameSignalCam << "\");" << endl;
-    if (fKeepSinglePixels)
-        out << "   " << GetUniqueName() << ".SetKeepSinglePixels();" << endl;
+    if (fKeepIsolatedPixels)
+        out << "   " << GetUniqueName() << ".SetKeepIsolatedPixels();" << endl;
+    if (fRecoverIsolatedPixels)
+        out << "   " << GetUniqueName() << ".SetRecoverIsolatedPixels(" << fRecoverIsolatedPixels << ");" << endl;
 
 }
@@ -860,5 +1089,5 @@
 //   MImgCleanStd.CleanMethod: Standard, Scaled, Democratic, Probability, Absolute
 //   MImgCleanStd.CleanRings:  1
-//   MImgCleanStd.KeepSinglePixels: yes, no
+//   MImgCleanStd.KeepIsolatedPixels: yes, no
 //
 Int_t MImgCleanStd::ReadEnv(const TEnv &env, TString prefix, Bool_t print)
@@ -870,4 +1099,9 @@
         SetCleanRings(GetEnvValue(env, prefix, "CleanRings", fCleanRings));
     }
+    if (IsEnvDefined(env, prefix, "CleanLevel0", print))
+    {
+        rc = kTRUE;
+        fCleanLvl0 = GetEnvValue(env, prefix, "CleanLevel0", fCleanLvl0);
+    }
     if (IsEnvDefined(env, prefix, "CleanLevel1", print))
     {
@@ -880,8 +1114,28 @@
         fCleanLvl2 = GetEnvValue(env, prefix, "CleanLevel2", fCleanLvl2);
     }
-    if (IsEnvDefined(env, prefix, "KeepSinglePixels", print))
+    if (IsEnvDefined(env, prefix, "TimeLevel1", print))
     {
         rc = kTRUE;
-        fKeepSinglePixels = GetEnvValue(env, prefix, "KeepSinglePixels", fKeepSinglePixels);
+        fTimeLvl1 = GetEnvValue(env, prefix, "TimeLevel1", fTimeLvl1);
+    }
+    if (IsEnvDefined(env, prefix, "TimeLevel2", print))
+    {
+        rc = kTRUE;
+        fTimeLvl2 = GetEnvValue(env, prefix, "TimeLevel2", fTimeLvl2);
+    }
+    if (IsEnvDefined(env, prefix, "KeepIsolatedPixels", print))
+    {
+        rc = kTRUE;
+        fKeepIsolatedPixels = GetEnvValue(env, prefix, "KeepIsolatedPixels", fKeepIsolatedPixels);
+    }
+    if (IsEnvDefined(env, prefix, "RecoverIsolatedPixels", print))
+    {
+        rc = kTRUE;
+        fRecoverIsolatedPixels = GetEnvValue(env, prefix, "RecoverIsolatedPixels", fKeepIsolatedPixels);
+    }
+    if (IsEnvDefined(env, prefix, "PostCleanType", print))
+    {
+        rc = kTRUE;
+        fPostCleanType = GetEnvValue(env, prefix, "PostCleanType", fPostCleanType);
     }
 
Index: trunk/MagicSoft/Mars/mimage/MImgCleanStd.h
===================================================================
--- trunk/MagicSoft/Mars/mimage/MImgCleanStd.h	(revision 8619)
+++ trunk/MagicSoft/Mars/mimage/MImgCleanStd.h	(revision 8646)
@@ -7,9 +7,10 @@
 
 class MGeomCam;
-class MSigmabar;
+class MGeomPix;
 class MSignalCam;
 class MPedPhotCam;
 class MArrivalTime;
 class MCameraData;
+//class MRawRunHeader;
 
 class MGGroupFrame;
@@ -32,16 +33,23 @@
     static const TString gsNameSignalCam;  // default name of the 'MSignalCam' container
 
-    const MGeomCam     *fCam;  //!
-          MSignalCam   *fEvt;  //!
-          MPedPhotCam  *fPed;  //!
-          MCameraData  *fData; //!
+    const MGeomCam      *fCam;  //!
+          MSignalCam    *fEvt;  //!
+          MPedPhotCam   *fPed;  //!
+          MCameraData   *fData; //!
+//          MRawRunHeader *fHeader; //!
 
     CleaningMethod_t fCleaningMethod;
 
+    Float_t  fCleanLvl0;
     Float_t  fCleanLvl1;
     Float_t  fCleanLvl2;
 
+    Float_t  fTimeLvl1;
+    Float_t  fTimeLvl2;
+
     UShort_t fCleanRings;
-    Bool_t   fKeepSinglePixels;
+    Bool_t   fKeepIsolatedPixels;
+    Int_t    fRecoverIsolatedPixels;
+    Int_t    fPostCleanType;
 
     TString  fNamePedPhotCam; // name of the 'MPedPhotCam' container
@@ -50,9 +58,13 @@
 
     // MImgCleanStd
-    void    CleanStep1();
-    Short_t CleanStep2(Float_t &size);
-    void    CleanStep3();
-    void    CleanStep3b(Int_t idx);
-    void    CleanStep4(UShort_t r, Int_t idx);
+    Bool_t HasCoreNeighbors(const MGeomPix &gpix) const;
+    Bool_t HasUsedNeighbors(const MGeomPix &gpix) const;
+    void   SetUsedNeighbors(const MGeomPix &gpix, Int_t r=1) const;
+    Int_t  DoCleaning(Float_t &size) const;
+    void   ResetCleaning() const;
+    Int_t  RecoverIsolatedPixels(Float_t &size) const;
+    void   CleanTime(Int_t n, Double_t lvl) const;
+
+    void CleanStepTime() const;
 
     // MGTask, MTask, MParContainer
@@ -70,11 +82,24 @@
     void Print(Option_t *o="") const;
 
-    Float_t  GetCleanLvl1() const { return fCleanLvl1; }
-    Float_t  GetCleanLvl2() const { return fCleanLvl2; }
+    Float_t GetCleanLvl0() const { return fCleanLvl0; }
+    Float_t GetCleanLvl1() const { return fCleanLvl1; }
+    Float_t GetCleanLvl2() const { return fCleanLvl2; }
+
+    Float_t GetTimeLvl1() const { return fTimeLvl1; }
+    Float_t GetTimeLvl2() const { return fTimeLvl2; }
+
+    void SetCleanLvl0(Float_t lvl) { fCleanLvl0=lvl; }
+    void SetCleanLvl1(Float_t lvl) { fCleanLvl1=lvl; }
+    void SetCleanLvl2(Float_t lvl) { fCleanLvl2=lvl; }
+
+    void SetTimeLvl1(Float_t lvl) { fTimeLvl1=lvl; }
+    void SetTimeLvl2(Float_t lvl) { fTimeLvl2=lvl; }
+
+    void SetCleanRings(UShort_t r) { fCleanRings=r; }
     UShort_t GetCleanRings() const { return fCleanRings;}
 
-    void SetCleanRings(UShort_t r) { if(r==0) r=1; fCleanRings=r; }
     void SetMethod(CleaningMethod_t m) { fCleaningMethod = m; }
-    void SetKeepSinglePixels(Bool_t b=kTRUE) { fKeepSinglePixels=b; }
+    void SetKeepIsolatedPixels(Bool_t b=kTRUE) { fKeepIsolatedPixels=b; }
+    void SetRecoverIsolatedPixels(Int_t n=-1) { fRecoverIsolatedPixels=n; }
 
     Bool_t ProcessMessage(Int_t msg, Int_t submsg, Long_t param1, Long_t param2);
@@ -84,5 +109,5 @@
     void SetNameGeomCam(const char *name)     { fNameGeomCam = name; }
 
-    ClassDef(MImgCleanStd, 3)    // task doing the image cleaning
+    ClassDef(MImgCleanStd, 4)    // task doing the image cleaning
 }; 
 
