remoe duplicate QA initialisation and do ESD QA for same detectors as RecPoint QA
[u/mrichter/AliRoot.git] / MUON / AliMUONPreClusterFinderV2.cxx
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 "AliMUONPreClusterFinderV2.h"
19
20 #include "AliLog.h"
21 #include "AliMUONCluster.h"
22 #include "AliMpVSegmentation.h"
23 #include "TClonesArray.h"
24 #include "TVector2.h"
25 #include "AliMUONPad.h"
26 #include "AliMUONVDigit.h"
27 #include "AliMUONVDigitStore.h"
28
29 //-----------------------------------------------------------------------------
30 /// \class AliMUONPreClusterFinderV2
31 ///
32 /// Implementation of AliMUONVClusterFinder
33 ///
34 /// This one ressembles the preclustering stage in the original ClusterFinderAZ
35 ///
36 /// \author Laurent Aphecetche
37 //-----------------------------------------------------------------------------
38
39 ClassImp(AliMUONPreClusterFinderV2)
40
41 //_____________________________________________________________________________
42 AliMUONPreClusterFinderV2::AliMUONPreClusterFinderV2()
43 : AliMUONVClusterFinder(),
44   fClusters(0x0),
45   fSegmentations(0x0),
46   fPads(0x0),
47   fDetElemId(0)
48 {
49     /// ctor
50 }
51
52 //_____________________________________________________________________________
53 AliMUONPreClusterFinderV2::~AliMUONPreClusterFinderV2()
54 {
55   /// dtor : note we're owner of the clusters, but not of the pads
56   delete fClusters;
57 }
58
59 //_____________________________________________________________________________
60 Bool_t
61 AliMUONPreClusterFinderV2::UsePad(const AliMUONPad& pad)
62 {
63   /// Add a pad to the list of pads to be considered
64   if ( pad.DetElemId() != fDetElemId )
65   {
66     AliError(Form("Cannot add pad from DE %d to this cluster finder which is "
67                   "currently dealing with DE %d",pad.DetElemId(),fDetElemId));
68     return kFALSE;
69   }
70   
71   new ((*fPads[pad.Cathode()])[fPads[pad.Cathode()]->GetLast()+1]) AliMUONPad(pad); 
72   // FIXME: should set the ClusterId of that new pad to be -1
73   return kTRUE;
74 }
75
76 //_____________________________________________________________________________
77 Bool_t
78 AliMUONPreClusterFinderV2::Prepare(Int_t detElemId,
79                                    TClonesArray* pads[2],
80                                    const AliMpArea& area,
81                                    const AliMpVSegmentation* seg[2])
82 {
83   /// Prepare for clustering, by giving access to segmentations and digit lists
84   
85   if ( area.IsValid() ) 
86   {
87     AliError("Handling of area not yet implemented for this class. Please check");
88   }
89   
90   delete fClusters;
91   fClusters = new TClonesArray("AliMUONCluster");
92
93   fPads = pads;
94   fSegmentations = seg;
95   
96   fDetElemId = detElemId;
97   
98   if ( fPads[0]->GetLast() < 0 && fPads[1]->GetLast() < 0 )
99   {
100     // no pad at all, nothing to do...
101     return kFALSE;
102   }
103
104   return kTRUE;
105 }
106
107 //_____________________________________________________________________________
108 void
109 AliMUONPreClusterFinderV2::AddPad(AliMUONCluster& cluster, AliMUONPad* pad)
110 {
111   /// Add a pad to a cluster
112   
113   cluster.AddPad(*pad);
114   pad->SetClusterId(cluster.GetUniqueID());
115   
116   Int_t cathode = pad->Cathode();
117   TClonesArray& padArray = *fPads[cathode];
118   padArray.Remove(pad);
119   TIter next(&padArray);
120   
121   // Check neighbours
122   TObjArray neighbours;
123   AliMpPad p = fSegmentations[pad->Cathode()]->PadByIndices(AliMpIntPair(pad->Ix(),pad->Iy()),kTRUE);
124   Int_t nn = fSegmentations[pad->Cathode()]->GetNeighbours(p,neighbours);
125   for (Int_t in = 0; in < nn; ++in) 
126   {
127     AliMpPad* p = static_cast<AliMpPad*>(neighbours.At(in));
128     
129     TIter next(&padArray);
130     AliMUONPad* p2;
131     
132     while ( ( p2 = static_cast<AliMUONPad*>(next()) ) )
133     {
134         if ( !p2->IsUsed() && p2->Ix()==p->GetIndices().GetFirst() 
135              && p2->Iy() == p->GetIndices().GetSecond() &&
136              p2->Cathode() == pad->Cathode() )
137         {
138           AddPad(cluster,p2);
139         }
140     }
141   } // for (Int_t in = 0;
142 }
143
144 namespace
145 {
146 //_____________________________________________________________________________
147 Bool_t
148 AreOverlapping(const AliMUONPad& pad, const AliMUONCluster& cluster)
149 {
150   /// Whether the pad overlaps with the cluster
151   
152   static Double_t precision = 1E-4; // cm
153   static TVector2 precisionAdjustment(precision,precision);//-precision,-precision);
154   for ( Int_t i = 0; i < cluster.Multiplicity(); ++i )
155   {
156     AliMUONPad* testPad = cluster.Pad(i);
157     // Note: we use negative precision numbers, meaning
158     // the area of the pads will be *increased* by these small numbers
159     // prior to check the overlap by the AreOverlapping method,
160     // so pads touching only by the corners will be considered as
161     // overlapping.    
162     if ( AliMUONPad::AreOverlapping(*testPad,pad,precisionAdjustment) )
163     {
164       return kTRUE;
165     }
166   }
167   return kFALSE;
168 }
169 }
170
171 //_____________________________________________________________________________
172 AliMUONCluster* 
173 AliMUONPreClusterFinderV2::NextCluster()
174 {
175   /// Builds the next cluster, and returns it.
176   
177   // Start a new cluster
178   Int_t id = fClusters->GetLast()+1;
179   AliMUONCluster* cluster = new ((*fClusters)[id]) AliMUONCluster;
180   cluster->SetUniqueID(id);
181   
182   AliMUONPad* pad;
183   TIter next(fPads[0]);
184   while (  ( pad = static_cast<AliMUONPad*>(next())) && pad->IsUsed() );
185
186   if (!pad) // protection against no pad in first cathode, which might happen
187   {
188     // try other cathode
189     TIter next(fPads[1]);
190     while (  ( pad = static_cast<AliMUONPad*>(next())) && pad->IsUsed() );
191     if (!pad) 
192     {
193       // we are done.
194       return 0x0;
195     }
196     // Builds (recursively) a cluster on second cathode only
197     AddPad(*cluster,pad);
198   }
199   else
200   {
201     // Builds (recursively) a cluster on first cathode only
202       
203     AddPad(*cluster,pad);
204
205     // On the 2nd cathode, only add pads overlapping with the current cluster
206     TIter next1(fPads[1]);
207     AliMUONPad* testPad;
208   
209     while ( ( testPad = static_cast<AliMUONPad*>(next1())))
210     {
211       if ( !testPad->IsUsed() && AreOverlapping(*testPad,*cluster) )
212       {
213         AddPad(*cluster,testPad);
214       }
215     }
216   }
217   
218   if ( cluster->Multiplicity() <= 1 )
219   {
220     if ( cluster->Multiplicity() == 0 ) 
221     {
222       // no pad is suspicious
223       AliWarning("Got an empty cluster...");
224     }
225     // else only 1 pad (not suspicious, but kind of useless, probably noise)
226     // so we remove it from our list
227     fClusters->Remove(cluster);
228     fClusters->Compress();
229     // then proceed further
230     return NextCluster();
231   }
232   
233   return cluster;
234 }