Make the Scan method public
[u/mrichter/AliRoot.git] / MUON / AliMUONPreClusterFinder.cxx
index bd09884..cbbadf6 100644 (file)
@@ -17,6 +17,8 @@
 
 #include "AliMUONPreClusterFinder.h"
 
+#include "AliCodeTimer.h"
+
 #include "AliMUONCluster.h"
 #include "AliMUONPad.h"
 #include "AliMUONVDigit.h"
@@ -29,7 +31,7 @@
 #include "AliLog.h"
 
 #include <Riostream.h>
-#include <TClonesArray.h>
+#include <TObjArray.h>
 #include <TVector2.h>
 
 //-----------------------------------------------------------------------------
@@ -47,10 +49,11 @@ ClassImp(AliMUONPreClusterFinder)
 //_____________________________________________________________________________
 AliMUONPreClusterFinder::AliMUONPreClusterFinder()
 : AliMUONVClusterFinder(),
-  fClusters(0x0),
+  fClusters("AliMUONCluster"),
   fPads(0x0),
   fDetElemId(0),
-  fArea()
+  fArea(),
+  fShouldAbort(kFALSE)
 {
   /// ctor
 }
@@ -59,7 +62,6 @@ AliMUONPreClusterFinder::AliMUONPreClusterFinder()
 AliMUONPreClusterFinder::~AliMUONPreClusterFinder()
 {
   /// dtor : note we're owner of the clusters, but not of the pads
-  delete fClusters;
 }
 
 //_____________________________________________________________________________
@@ -74,7 +76,7 @@ AliMUONPreClusterFinder::UsePad(const AliMUONPad& pad)
     return kFALSE;
   }
   
-  new ((*fPads[pad.Cathode()])[fPads[pad.Cathode()]->GetLast()+1]) AliMUONPad(pad); 
+  fPads[pad.Cathode()]->Add(new AliMUONPad(pad)); 
   // FIXME: should set the ClusterId of that new pad to be -1
   return kTRUE;
 }
@@ -82,18 +84,19 @@ AliMUONPreClusterFinder::UsePad(const AliMUONPad& pad)
 //_____________________________________________________________________________
 Bool_t
 AliMUONPreClusterFinder::Prepare(Int_t detElemId,
-                                 TClonesArray* pads[2],
+                                 TObjArray* pads[2],
                                  const AliMpArea& area)
 {
   /// Prepare for clustering, by giving access to segmentations and digit lists
-  
-  delete fClusters;
-  fClusters = new TClonesArray("AliMUONCluster");
 
+  fClusters.Delete();
+  
   fPads = pads;
   fDetElemId = detElemId;
   fArea = area;
   
+  fShouldAbort = kFALSE;
+  
   return kTRUE;
 }
 
@@ -102,27 +105,39 @@ void
 AliMUONPreClusterFinder::AddPad(AliMUONCluster& cluster, AliMUONPad* pad)
 {
   /// Add a pad to a cluster
-  cluster.AddPad(*pad);
+  
+  if ( cluster.IsMonoCathode() && cluster.Multiplicity() > 199 ) 
+  {
+    /// FIXME : we should at that point really find a better way to remove "bad" preclusters,
+    /// like e.g. computing the charge dispersion (the lower, the most probably we have noise cluster)
+    /// and/or mean charge per pad (if too close to LowestPadCharge, again that's a noise cluster...
+    /// *BUT* this needs carefull testing !
+    fShouldAbort = kTRUE;
+    return;
+  }
+  
+  AliMUONPad* addedPad = cluster.AddPad(*pad);
   
   Int_t cathode = pad->Cathode();
-  TClonesArray& padArray = *fPads[cathode];
+  TObjArray& padArray = *fPads[cathode];
   // WARNING: this Remove method uses the AliMUONPad::IsEqual if that method is
   // present (otherwise just compares pointers) : so that one must be correct
   // if implemented !
-  padArray.Remove(pad);
- // TObject* o = padArray.Remove(pad); 
+  TObject* o = padArray.Remove(pad);
 //  if (!o)
 //  {
 //    AliFatal("Oups. Could not remove pad from pads to consider. Aborting as anyway "
 //             " we'll get an infinite loop. Please check the AliMUONPad::IsEqual method"
 //             " as the first suspect for failed remove");
 //  }  
+  delete o;
+  
   TIter next(&padArray);
   AliMUONPad* testPad;
 
   while ( ( testPad = static_cast<AliMUONPad*>(next())))
   {
-    if ( AliMUONPad::AreNeighbours(*testPad,*pad) )
+    if ( AliMUONPad::AreNeighbours(*testPad,*addedPad) )
     {
       AddPad(cluster,testPad);
     }
@@ -170,7 +185,7 @@ AliMUONPreClusterFinder::GetNextPad(Int_t cathode) const
     AliMUONPad* pad;
     while ( ( pad = static_cast<AliMUONPad*>(next())) )
     {
-      AliMpArea padArea(pad->Position(),pad->Dimensions());
+      AliMpArea padArea(pad->X(), pad->Y(), pad->DX(), pad->DY());
       
       if (fArea.Overlap(padArea)) return pad;
 
@@ -181,49 +196,83 @@ AliMUONPreClusterFinder::GetNextPad(Int_t cathode) const
 
 //_____________________________________________________________________________
 AliMUONCluster* 
+AliMUONPreClusterFinder::NewCluster()
+{
+  /// Create a new (empty) cluster
+  Int_t id = fClusters.GetLast()+1;
+  AliMUONCluster* cluster = new (fClusters[id]) AliMUONCluster;
+  cluster->SetUniqueID(id);
+  return cluster;
+}
+
+//_____________________________________________________________________________
+void 
+AliMUONPreClusterFinder::RemoveCluster(AliMUONCluster* cluster)
+{
+  /// Remove a cluster
+  /// Note that we are *not* releasing the pads, so they won't be used further on
+  fClusters.Remove(cluster);
+  fClusters.Compress();
+}
+
+//_____________________________________________________________________________
+AliMUONCluster* 
 AliMUONPreClusterFinder::NextCluster()
 {
   /// Builds the next cluster, and returns it.
-//  AliCodeTimerAuto("pre-clustering")
   
   // Start a new cluster
-  Int_t id = fClusters->GetLast()+1;
-  AliMUONCluster* cluster = new ((*fClusters)[id]) AliMUONCluster;
-  cluster->SetUniqueID(id);
   
   AliMUONPad* pad = GetNextPad(0);
   
+  AliMUONCluster* cluster(0x0);
+  
   if (!pad) // protection against no pad in first cathode, which might happen
   {
     // try other cathode
     pad = GetNextPad(1);
     if (!pad) 
     {
-      // we are done.
       return 0x0;
     }
-    // Builds (recursively) a cluster on second cathode only
-    AddPad(*cluster,pad);
+    else
+    {
+      cluster = NewCluster();
+      // Builds (recursively) a cluster on second cathode only
+      AddPad(*cluster,pad);
+    }
   }
   else
   {
     // Builds (recursively) a cluster on first cathode only
+    
+    cluster = NewCluster();
     AddPad(*cluster,pad);
     
-    // On the 2nd cathode, only add pads overlapping with the current cluster
-    TClonesArray& padArray = *fPads[1];
-    TIter next(&padArray);
-    AliMUONPad* testPad;
-  
-    while ( ( testPad = static_cast<AliMUONPad*>(next())))
+    if ( !ShouldAbort() ) 
     {
-      if (AreOverlapping(*testPad,*cluster) )
+      // On the 2nd cathode, only add pads overlapping with the current cluster
+      TObjArray& padArray = *fPads[1];
+      TIter next(&padArray);
+      AliMUONPad* testPad;
+      
+      while ( ( testPad = static_cast<AliMUONPad*>(next())) && !ShouldAbort() )
       {
-        AddPad(*cluster,testPad);
+        if (AreOverlapping(*testPad,*cluster) )
+        {
+          AddPad(*cluster,testPad);
+        }
       }
     }
   }
   
+  if ( ShouldAbort() ) 
+  {
+    AliCodeTimerAuto(Form("Skipping a precluster in DE %d because it got too many pads",fDetElemId),0);
+    RemoveCluster(cluster);
+    return NextCluster();
+  }
+  
   if ( cluster->Multiplicity() <= 1 )
   {
     if ( cluster->Multiplicity() == 0 ) 
@@ -233,8 +282,7 @@ AliMUONPreClusterFinder::NextCluster()
     }
     // else only 1 pad (not suspicious, but kind of useless, probably noise)
     // so we remove it from our list
-    fClusters->Remove(cluster);
-    fClusters->Compress();
+    RemoveCluster(cluster);
     // then proceed further
     return NextCluster();
   }