LCOV - code coverage report
Current view: top level - MUON/MUONrec - AliMUONPreClusterFinder.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 62 91 68.1 %
Date: 2016-06-14 17:26:59 Functions: 12 14 85.7 %

          Line data    Source code
       1             : /**************************************************************************
       2             : * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
       3             : *                                                                        *
       4             : * Author: The ALICE Off-line Project.                                    *
       5             : * Contributors are mentioned in the code where appropriate.              *
       6             : *                                                                        *
       7             : * Permission to use, copy, modify and distribute this software and its   *
       8             : * documentation strictly for non-commercial purposes is hereby granted   *
       9             : * without fee, provided that the above copyright notice appears in all   *
      10             : * copies and that both the copyright notice and this permission notice   *
      11             : * appear in the supporting documentation. The authors make no claims     *
      12             : * about the suitability of this software for any purpose. It is          *
      13             : * provided "as is" without express or implied warranty.                  *
      14             : **************************************************************************/
      15             : 
      16             : // $Id$
      17             : 
      18             : #include "AliMUONPreClusterFinder.h"
      19             : 
      20             : #include "AliCodeTimer.h"
      21             : 
      22             : #include "AliMUONCluster.h"
      23             : #include "AliMUONPad.h"
      24             : #include "AliMUONVDigit.h"
      25             : #include "AliMUONVDigitStore.h"
      26             : 
      27             : #include "AliMpArea.h"
      28             : #include "AliMpConstants.h"
      29             : #include "AliMpVSegmentation.h"
      30             : 
      31             : #include "AliLog.h"
      32             : 
      33             : #include <Riostream.h>
      34             : #include <TObjArray.h>
      35             : #include <TVector2.h>
      36             : 
      37             : //-----------------------------------------------------------------------------
      38             : /// \class AliMUONPreClusterFinder
      39             : ///
      40             : /// Implementation of AliMUONVClusterFinder
      41             : ///
      42             : /// This class simply find adjacent pads to form clusters
      43             : ///
      44             : /// \author Laurent Aphecetche
      45             : //-----------------------------------------------------------------------------
      46             : 
      47          18 : ClassImp(AliMUONPreClusterFinder)
      48             : 
      49             : //_____________________________________________________________________________
      50             : AliMUONPreClusterFinder::AliMUONPreClusterFinder()
      51           2 : : AliMUONVClusterFinder(),
      52           2 :   fClusters("AliMUONCluster"),
      53           2 :   fPads(0x0),
      54           2 :   fDetElemId(0),
      55           2 :   fArea(),
      56           2 :   fShouldAbort(kFALSE)
      57          10 : {
      58             :   /// ctor
      59           4 : }
      60             : 
      61             : //_____________________________________________________________________________
      62             : AliMUONPreClusterFinder::~AliMUONPreClusterFinder()
      63          12 : {
      64             :   /// dtor : note we're owner of the clusters, but not of the pads
      65           6 : }
      66             : 
      67             : //_____________________________________________________________________________
      68             : Bool_t
      69             : AliMUONPreClusterFinder::UsePad(const AliMUONPad& pad)
      70             : {
      71             :   /// Add a pad to the list of pads to be considered
      72           0 :   if ( pad.DetElemId() != fDetElemId )
      73             :   {
      74           0 :     AliError(Form("Cannot add pad from DE %d to this cluster finder which is "
      75             :                   "currently dealing with DE %d",pad.DetElemId(),fDetElemId));
      76           0 :     return kFALSE;
      77             :   }
      78             :   
      79           0 :   fPads[pad.Cathode()]->Add(new AliMUONPad(pad)); 
      80             :   // FIXME: should set the ClusterId of that new pad to be -1
      81           0 :   return kTRUE;
      82           0 : }
      83             : 
      84             : //_____________________________________________________________________________
      85             : Bool_t
      86             : AliMUONPreClusterFinder::Prepare(Int_t detElemId,
      87             :                                  TObjArray* pads[2],
      88             :                                  const AliMpArea& area)
      89             : {
      90             :   /// Prepare for clustering, by giving access to segmentations and digit lists
      91             : 
      92         288 :   fClusters.Delete();
      93             :   
      94         144 :   fPads = pads;
      95         144 :   fDetElemId = detElemId;
      96         144 :   fArea = area;
      97             :   
      98         144 :   fShouldAbort = kFALSE;
      99             :   
     100         144 :   return kTRUE;
     101             : }
     102             : 
     103             : //_____________________________________________________________________________
     104             : void
     105             : AliMUONPreClusterFinder::AddPad(AliMUONCluster& cluster, AliMUONPad* pad)
     106             : {
     107             :   /// Add a pad to a cluster
     108             :   
     109        3460 :   if ( cluster.IsMonoCathode() && cluster.Multiplicity() > 199 ) 
     110             :   {
     111             :     /// FIXME : we should at that point really find a better way to remove "bad" preclusters,
     112             :     /// like e.g. computing the charge dispersion (the lower, the most probably we have noise cluster)
     113             :     /// and/or mean charge per pad (if too close to LowestPadCharge, again that's a noise cluster...
     114             :     /// *BUT* this needs carefull testing !
     115           0 :     fShouldAbort = kTRUE;
     116           0 :     return;
     117             :   }
     118             :   
     119        1324 :   AliMUONPad* addedPad = cluster.AddPad(*pad);
     120             :   
     121        1324 :   Int_t cathode = pad->Cathode();
     122        1324 :   TObjArray& padArray = *fPads[cathode];
     123             :   // WARNING: this Remove method uses the AliMUONPad::IsEqual if that method is
     124             :   // present (otherwise just compares pointers) : so that one must be correct
     125             :   // if implemented !
     126        1324 :   TObject* o = padArray.Remove(pad);
     127             : //  if (!o)
     128             : //  {
     129             : //    AliFatal("Oups. Could not remove pad from pads to consider. Aborting as anyway "
     130             : //             " we'll get an infinite loop. Please check the AliMUONPad::IsEqual method"
     131             : //             " as the first suspect for failed remove");
     132             : //  }  
     133        2648 :   delete o;
     134             :   
     135        1324 :   TIter next(&padArray);
     136             :   AliMUONPad* testPad;
     137             : 
     138        7512 :   while ( ( testPad = static_cast<AliMUONPad*>(next())))
     139             :   {
     140        3540 :     if ( AliMUONPad::AreNeighbours(*testPad,*addedPad) )
     141             :     {
     142         996 :       AddPad(cluster,testPad);
     143             :     }
     144             :   }
     145        2648 : }
     146             : 
     147             : //_____________________________________________________________________________
     148             : Bool_t
     149             : AreOverlapping(const AliMUONPad& pad, const AliMUONCluster& cluster)
     150             : {
     151             :   /// Whether the pad overlaps with the cluster
     152             :   
     153             :   static Double_t precision = 1E-4; // cm
     154         516 :   static TVector2 precisionAdjustment(precision,precision);//-precision,-precision);
     155        2133 :   for ( Int_t i = 0; i < cluster.Multiplicity(); ++i )
     156             :   {
     157         930 :     AliMUONPad* testPad = cluster.Pad(i);
     158             :     // Note: we use negative precision numbers, meaning
     159             :     // the area of the pads will be *increased* by these small numbers
     160             :     // prior to check the overlap by the AreOverlapping method,
     161             :     // so pads touching only by the corners will be considered as
     162             :     // overlapping.    
     163         930 :     if ( AliMUONPad::AreOverlapping(*testPad,pad,precisionAdjustment) )
     164             :     {
     165         164 :       return kTRUE;
     166             :     }
     167         766 :   }
     168          91 :   return kFALSE;
     169         255 : }
     170             : 
     171             : //_____________________________________________________________________________
     172             : AliMUONPad*
     173             : AliMUONPreClusterFinder::GetNextPad(Int_t cathode) const
     174             : {
     175             : /// Return the next unused pad of given cathode, which is within fArea
     176             : 
     177         904 :   TIter next(fPads[cathode]);
     178             :   
     179         452 :   if ( !fArea.IsValid() )
     180             :   {
     181         904 :     return static_cast<AliMUONPad*>(next());
     182             :   }
     183             :   else
     184             :   {
     185             :     AliMUONPad* pad;
     186           0 :     while ( ( pad = static_cast<AliMUONPad*>(next())) )
     187             :     {
     188           0 :       AliMpArea padArea(pad->X(), pad->Y(), pad->DX(), pad->DY());
     189             :       
     190           0 :       if (fArea.Overlap(padArea)) return pad;
     191             : 
     192           0 :     }
     193           0 :     return 0x0;
     194             :   }
     195         452 : }
     196             : 
     197             : //_____________________________________________________________________________
     198             : AliMUONCluster* 
     199             : AliMUONPreClusterFinder::NewCluster()
     200             : {
     201             :   /// Create a new (empty) cluster
     202         328 :   Int_t id = fClusters.GetLast()+1;
     203         164 :   AliMUONCluster* cluster = new (fClusters[id]) AliMUONCluster;
     204         164 :   cluster->SetUniqueID(id);
     205         164 :   return cluster;
     206           0 : }
     207             : 
     208             : //_____________________________________________________________________________
     209             : void 
     210             : AliMUONPreClusterFinder::RemoveCluster(AliMUONCluster* cluster)
     211             : {
     212             :   /// Remove a cluster
     213             :   /// Note that we are *not* releasing the pads, so they won't be used further on
     214           0 :   fClusters.Remove(cluster);
     215           0 :   fClusters.Compress();
     216           0 : }
     217             : 
     218             : //_____________________________________________________________________________
     219             : AliMUONCluster* 
     220             : AliMUONPreClusterFinder::NextCluster()
     221             : {
     222             :   /// Builds the next cluster, and returns it.
     223             :   
     224             :   // Start a new cluster
     225             :   
     226         616 :   AliMUONPad* pad = GetNextPad(0);
     227             :   
     228             :   AliMUONCluster* cluster(0x0);
     229             :   
     230         308 :   if (!pad) // protection against no pad in first cathode, which might happen
     231             :   {
     232             :     // try other cathode
     233         144 :     pad = GetNextPad(1);
     234         144 :     if (!pad) 
     235             :     {
     236         144 :       return 0x0;
     237             :     }
     238             :     else
     239             :     {
     240           0 :       cluster = NewCluster();
     241             :       // Builds (recursively) a cluster on second cathode only
     242           0 :       AddPad(*cluster,pad);
     243             :     }
     244           0 :   }
     245             :   else
     246             :   {
     247             :     // Builds (recursively) a cluster on first cathode only
     248             :     
     249         164 :     cluster = NewCluster();
     250         164 :     AddPad(*cluster,pad);
     251             :     
     252         164 :     if ( !ShouldAbort() ) 
     253             :     {
     254             :       // On the 2nd cathode, only add pads overlapping with the current cluster
     255         164 :       TObjArray& padArray = *fPads[1];
     256         164 :       TIter next(&padArray);
     257             :       AliMUONPad* testPad;
     258             :       
     259        1512 :       while ( ( testPad = static_cast<AliMUONPad*>(next())) && !ShouldAbort() )
     260             :       {
     261         510 :         if (AreOverlapping(*testPad,*cluster) )
     262             :         {
     263         164 :           AddPad(*cluster,testPad);
     264             :         }
     265             :       }
     266         164 :     }
     267             :   }
     268             :   
     269         164 :   if ( ShouldAbort() ) 
     270             :   {
     271           0 :     AliCodeTimerAuto(Form("Skipping a precluster in DE %d because it got too many pads",fDetElemId),0);
     272           0 :     RemoveCluster(cluster);
     273           0 :     return NextCluster();
     274           0 :   }
     275             :   
     276         164 :   if ( cluster->Multiplicity() <= 1 )
     277             :   {
     278           0 :     if ( cluster->Multiplicity() == 0 ) 
     279             :     {
     280             :       // no pad is suspicious
     281           0 :       AliWarning("Got an empty cluster...");
     282           0 :     }
     283             :     // else only 1 pad (not suspicious, but kind of useless, probably noise)
     284             :     // so we remove it from our list
     285           0 :     RemoveCluster(cluster);
     286             :     // then proceed further
     287           0 :     return NextCluster();
     288             :   }
     289             :   
     290         164 :   return cluster;
     291         308 : }

Generated by: LCOV version 1.11