#include "AliMUONPreClusterFinder.h"
+#include "AliCodeTimer.h"
+
#include "AliMUONCluster.h"
#include "AliMUONPad.h"
#include "AliMUONVDigit.h"
#include "AliLog.h"
#include <Riostream.h>
-#include <TClonesArray.h>
+#include <TObjArray.h>
#include <TVector2.h>
//-----------------------------------------------------------------------------
//_____________________________________________________________________________
AliMUONPreClusterFinder::AliMUONPreClusterFinder()
: AliMUONVClusterFinder(),
- fClusters(0x0),
+ fClusters("AliMUONCluster"),
fPads(0x0),
fDetElemId(0),
- fArea()
+ fArea(),
+ fShouldAbort(kFALSE)
{
/// ctor
}
AliMUONPreClusterFinder::~AliMUONPreClusterFinder()
{
/// dtor : note we're owner of the clusters, but not of the pads
- delete fClusters;
}
//_____________________________________________________________________________
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;
}
//_____________________________________________________________________________
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;
}
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);
}
AliMUONPad*
AliMUONPreClusterFinder::GetNextPad(Int_t cathode) const
{
+/// Return the next unused pad of given cathode, which is within fArea
+
TIter next(fPads[cathode]);
if ( !fArea.IsValid() )
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;
}
}
+//_____________________________________________________________________________
+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 )
}
// 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();
}