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