AliRoot Core  edcc906 (edcc906)
AliMUONPreClusterFinder.cxx
Go to the documentation of this file.
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 
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 //-----------------------------------------------------------------------------
45 //-----------------------------------------------------------------------------
46 
48 
49 //_____________________________________________________________________________
52  fClusters("AliMUONCluster"),
53  fPads(0x0),
54  fDetElemId(0),
55  fArea(),
56  fShouldAbort(kFALSE)
57 {
59 }
60 
61 //_____________________________________________________________________________
63 {
65 }
66 
67 //_____________________________________________________________________________
68 Bool_t
70 {
72  if ( pad.DetElemId() != fDetElemId )
73  {
74  AliError(Form("Cannot add pad from DE %d to this cluster finder which is "
75  "currently dealing with DE %d",pad.DetElemId(),fDetElemId));
76  return kFALSE;
77  }
78 
79  fPads[pad.Cathode()]->Add(new AliMUONPad(pad));
80  // FIXME: should set the ClusterId of that new pad to be -1
81  return kTRUE;
82 }
83 
84 //_____________________________________________________________________________
85 Bool_t
87  TObjArray* pads[2],
88  const AliMpArea& area)
89 {
91 
92  fClusters.Delete();
93 
94  fPads = pads;
95  fDetElemId = detElemId;
96  fArea = area;
97 
98  fShouldAbort = kFALSE;
99 
100  return kTRUE;
101 }
102 
103 //_____________________________________________________________________________
104 void
106 {
108 
109  if ( cluster.IsMonoCathode() && cluster.Multiplicity() > 199 )
110  {
115  fShouldAbort = kTRUE;
116  return;
117  }
118 
119  AliMUONPad* addedPad = cluster.AddPad(*pad);
120 
121  Int_t cathode = pad->Cathode();
122  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  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  delete o;
134 
135  TIter next(&padArray);
136  AliMUONPad* testPad;
137 
138  while ( ( testPad = static_cast<AliMUONPad*>(next())))
139  {
140  if ( AliMUONPad::AreNeighbours(*testPad,*addedPad) )
141  {
142  AddPad(cluster,testPad);
143  }
144  }
145 }
146 
147 //_____________________________________________________________________________
148 Bool_t
149 AreOverlapping(const AliMUONPad& pad, const AliMUONCluster& cluster)
150 {
152 
153  static Double_t precision = 1E-4; // cm
154  static TVector2 precisionAdjustment(precision,precision);//-precision,-precision);
155  for ( Int_t i = 0; i < cluster.Multiplicity(); ++i )
156  {
157  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  if ( AliMUONPad::AreOverlapping(*testPad,pad,precisionAdjustment) )
164  {
165  return kTRUE;
166  }
167  }
168  return kFALSE;
169 }
170 
171 //_____________________________________________________________________________
172 AliMUONPad*
174 {
176 
177  TIter next(fPads[cathode]);
178 
179  if ( !fArea.IsValid() )
180  {
181  return static_cast<AliMUONPad*>(next());
182  }
183  else
184  {
185  AliMUONPad* pad;
186  while ( ( pad = static_cast<AliMUONPad*>(next())) )
187  {
188  AliMpArea padArea(pad->X(), pad->Y(), pad->DX(), pad->DY());
189 
190  if (fArea.Overlap(padArea)) return pad;
191 
192  }
193  return 0x0;
194  }
195 }
196 
197 //_____________________________________________________________________________
200 {
202  Int_t id = fClusters.GetLast()+1;
203  AliMUONCluster* cluster = new (fClusters[id]) AliMUONCluster;
204  cluster->SetUniqueID(id);
205  return cluster;
206 }
207 
208 //_____________________________________________________________________________
209 void
211 {
214  fClusters.Remove(cluster);
215  fClusters.Compress();
216 }
217 
218 //_____________________________________________________________________________
221 {
223 
224  // Start a new cluster
225 
226  AliMUONPad* pad = GetNextPad(0);
227 
228  AliMUONCluster* cluster(0x0);
229 
230  if (!pad) // protection against no pad in first cathode, which might happen
231  {
232  // try other cathode
233  pad = GetNextPad(1);
234  if (!pad)
235  {
236  return 0x0;
237  }
238  else
239  {
240  cluster = NewCluster();
241  // Builds (recursively) a cluster on second cathode only
242  AddPad(*cluster,pad);
243  }
244  }
245  else
246  {
247  // Builds (recursively) a cluster on first cathode only
248 
249  cluster = NewCluster();
250  AddPad(*cluster,pad);
251 
252  if ( !ShouldAbort() )
253  {
254  // On the 2nd cathode, only add pads overlapping with the current cluster
255  TObjArray& padArray = *fPads[1];
256  TIter next(&padArray);
257  AliMUONPad* testPad;
258 
259  while ( ( testPad = static_cast<AliMUONPad*>(next())) && !ShouldAbort() )
260  {
261  if (AreOverlapping(*testPad,*cluster) )
262  {
263  AddPad(*cluster,testPad);
264  }
265  }
266  }
267  }
268 
269  if ( ShouldAbort() )
270  {
271  AliCodeTimerAuto(Form("Skipping a precluster in DE %d because it got too many pads",fDetElemId),0);
272  RemoveCluster(cluster);
273  return NextCluster();
274  }
275 
276  if ( cluster->Multiplicity() <= 1 )
277  {
278  if ( cluster->Multiplicity() == 0 )
279  {
280  // no pad is suspicious
281  AliWarning("Got an empty cluster...");
282  }
283  // else only 1 pad (not suspicious, but kind of useless, probably noise)
284  // so we remove it from our list
285  RemoveCluster(cluster);
286  // then proceed further
287  return NextCluster();
288  }
289 
290  return cluster;
291 }
static Bool_t AreOverlapping(const AliMUONPad &d1, const AliMUONPad &d2, const TVector2 &precision, AliMpArea &overlapArea)
Definition: AliMUONPad.cxx:221
Int_t fDetElemId
! which DE we&#39;re considering
Bool_t fShouldAbort
! to indicate clustering should stop right now
Interface of a cluster finder.
Bool_t AreOverlapping(const AliMUONPad &pad, const AliMUONCluster &cluster)
AliMUONPad * GetNextPad(Int_t cathode) const
#define TObjArray
A group of adjacent pads.
TClonesArray fClusters
! the clusters we&#39;ve found (owner)
void AddPad(AliMUONCluster &cluster, AliMUONPad *pad)
A rectangle area positioned in plane..
Definition: AliMpArea.h:20
virtual Bool_t ShouldAbort() const
Whether we should stop working...
AliMpArea fArea
! area into which to consider pads to start a cluster
Double_t DY() const
Return half dimensions in y (cm)
Definition: AliMUONPad.h:61
Int_t Multiplicity() const
static Bool_t AreNeighbours(const AliMUONPad &d1, const AliMUONPad &d2)
Definition: AliMUONPad.cxx:167
#define AliWarning(message)
Definition: AliLog.h:541
Double_t Y() const
Return position in y (cm)
Definition: AliMUONPad.h:128
Bool_t IsMonoCathode() const
Double_t X() const
Return position in x (cm)
Definition: AliMUONPad.h:126
virtual Bool_t UsePad(const AliMUONPad &pad)
#define AliCodeTimerAuto(message, counter)
Definition: AliCodeTimer.h:137
Int_t Cathode() const
Return cathode number.
Definition: AliMUONPad.h:43
AliMUONPad * AddPad(const AliMUONPad &pad)
Bool_t IsValid() const
Return validity.
Definition: AliMpArea.h:83
Bool_t Overlap(const AliMpArea &area) const
Definition: AliMpArea.cxx:231
Int_t DetElemId() const
Return detection element id.
Definition: AliMUONPad.h:53
#define AliError(message)
Definition: AliLog.h:591
A basic pre-cluster finder.
virtual AliMUONCluster * NextCluster()
AliMUONPad * Pad(Int_t index) const
void RemoveCluster(AliMUONCluster *cluster)
virtual Bool_t Prepare(Int_t detElemId, TObjArray *pads[2], const AliMpArea &area)
TObjArray ** fPads
! the pads corresponding to the digits (not owner)
Combination of digit and mppad informations.
Definition: AliMUONPad.h:25
Double_t DX() const
Return half dimensions in x (cm)
Definition: AliMUONPad.h:59