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 "AliMUONPreClusterFinderV3.h"
19 :
20 : #include "AliLog.h"
21 : #include "AliMUONCluster.h"
22 : #include "AliMpVSegmentation.h"
23 : #include "TObjArray.h"
24 : #include "AliMpArea.h"
25 : #include "TVector2.h"
26 : #include "AliMUONPad.h"
27 : #include "AliMUONVDigit.h"
28 : #include "AliMUONVDigitStore.h"
29 : #include <Riostream.h>
30 : //#include "AliCodeTimer.h"
31 :
32 : //-----------------------------------------------------------------------------
33 : /// \class AliMUONPreClusterFinderV3
34 : ///
35 : /// Implementation of AliMUONVClusterFinder
36 : ///
37 : /// This version uses a 2 steps approach :
38 : ///
39 : /// we first clusterize each cathode independently to form proto-preclusters,
40 : /// and then we try to "merge" proto-preclusters from the two cathodes
41 : /// when thoses proto-preclusters overlap, thus ending up with preclusters
42 : /// spanning the two cathodes.
43 : ///
44 : /// This implementation, on the contrary to PreClusterFinder or PreClusterFinderV2
45 : /// should not depend on the order of the input digits.
46 : ///
47 : /// \author Laurent Aphecetche
48 : //-----------------------------------------------------------------------------
49 :
50 : using std::endl;
51 : using std::cout;
52 18 : ClassImp(AliMUONPreClusterFinderV3)
53 :
54 : //_____________________________________________________________________________
55 : AliMUONPreClusterFinderV3::AliMUONPreClusterFinderV3()
56 0 : : AliMUONVClusterFinder(),
57 0 : fClusters(new TClonesArray("AliMUONCluster",10)),
58 0 : fkSegmentations(0x0),
59 0 : fPads(0x0),
60 0 : fDetElemId(0),
61 0 : fIterator(0x0)
62 0 : {
63 : /// ctor
64 0 : AliInfo("");
65 0 : for ( Int_t i = 0; i < 2; ++i )
66 : {
67 0 : fPreClusters[i] = new TClonesArray("AliMUONCluster",10);
68 : }
69 0 : }
70 :
71 : //_____________________________________________________________________________
72 : AliMUONPreClusterFinderV3::~AliMUONPreClusterFinderV3()
73 0 : {
74 : /// dtor
75 0 : delete fClusters;
76 0 : for ( Int_t i = 0; i < 2; ++i )
77 : {
78 0 : delete fPreClusters[i];
79 : }
80 0 : }
81 :
82 : //_____________________________________________________________________________
83 : Bool_t
84 : AliMUONPreClusterFinderV3::UsePad(const AliMUONPad& pad)
85 : {
86 : /// Add a pad to the list of pads to be considered
87 0 : if ( pad.DetElemId() != fDetElemId )
88 : {
89 0 : AliError(Form("Cannot add pad from DE %d to this cluster finder which is "
90 : "currently dealing with DE %d",pad.DetElemId(),fDetElemId));
91 0 : return kFALSE;
92 : }
93 :
94 0 : AliMUONPad* p = new AliMUONPad(pad);
95 0 : p->SetClusterId(-1);
96 0 : fPads[pad.Cathode()]->Add(p);
97 : return kTRUE;
98 0 : }
99 :
100 : //_____________________________________________________________________________
101 : Bool_t
102 : AliMUONPreClusterFinderV3::Prepare(Int_t detElemId,
103 : TObjArray* pads[2],
104 : const AliMpArea& area,
105 : const AliMpVSegmentation* seg[2])
106 : {
107 : /// Prepare for clustering, by giving access to segmentations and digit lists
108 :
109 0 : if ( area.IsValid() )
110 : {
111 0 : AliError("Handling of area not yet implemented for this class. Please check.");
112 0 : }
113 :
114 0 : fkSegmentations = seg;
115 0 : fPads = pads;
116 :
117 0 : fClusters->Clear("C");
118 0 : for ( Int_t i = 0; i < 2; ++i )
119 : {
120 0 : fPreClusters[i]->Clear("C");
121 : }
122 :
123 0 : fDetElemId = detElemId;
124 :
125 0 : if ( fPads[0]->GetLast() < 0 && fPads[1]->GetLast() < 0 )
126 : {
127 : // no pad at all, nothing to do...
128 0 : return kFALSE;
129 : }
130 :
131 0 : MakeCathodePreClusters(0);
132 0 : MakeCathodePreClusters(1);
133 0 : MakeClusters();
134 :
135 0 : delete fIterator;
136 0 : fIterator = fClusters->MakeIterator();
137 :
138 0 : return kTRUE;
139 0 : }
140 :
141 : //_____________________________________________________________________________
142 : void
143 : AliMUONPreClusterFinderV3::DumpPreClusters() const
144 : {
145 : /// Dump preclusters
146 : AliMUONCluster *c;
147 0 : TIter next0(fPreClusters[0]);
148 0 : TIter next1(fPreClusters[1]);
149 0 : cout << "Cath0" << endl;
150 0 : while ( ( c = static_cast<AliMUONCluster*>(next0())) )
151 : {
152 0 : cout << c->AsString().Data() << endl;
153 : }
154 0 : cout << "Cath1" << endl;
155 0 : while ( ( c = static_cast<AliMUONCluster*>(next1())) )
156 : {
157 0 : cout << c->AsString().Data() << endl;
158 : }
159 0 : }
160 :
161 : //_____________________________________________________________________________
162 : void
163 : AliMUONPreClusterFinderV3::AddPreCluster(AliMUONCluster& cluster, AliMUONCluster* preCluster)
164 : {
165 : /// Add a pad to a cluster
166 :
167 0 : AliMUONCluster a(*preCluster);
168 :
169 0 : Int_t cathode = preCluster->Cathode();
170 0 : if ( cathode < 0 ) {
171 0 : AliError(Form("Cathod undefined: %d",cathode));
172 0 : AliFatal("");
173 0 : return;
174 : }
175 :
176 0 : if ( cathode <=1 && !fPreClusters[cathode]->Remove(preCluster) )
177 : {
178 0 : AliError(Form("Could not remove %s from preclusters[%d]",
179 : preCluster->AsString().Data(),cathode));
180 0 : StdoutToAliDebug(1,DumpPreClusters());
181 0 : AliFatal("");
182 0 : return;
183 : }
184 :
185 0 : cluster.AddCluster(a);
186 :
187 : // loop on the *other* cathode
188 0 : TIter next(fPreClusters[1-cathode]);
189 : AliMUONCluster* testCluster;
190 :
191 0 : while ( ( testCluster = static_cast<AliMUONCluster*>(next())))
192 : {
193 0 : if ( AliMUONCluster::AreOverlapping(a,*testCluster) )
194 : {
195 0 : AddPreCluster(cluster,testCluster);
196 : }
197 : }
198 0 : }
199 :
200 :
201 : //_____________________________________________________________________________
202 : void
203 : AliMUONPreClusterFinderV3::AddPad(AliMUONCluster& cluster, AliMUONPad* pad)
204 : {
205 : /// Add a pad to a cluster
206 0 : AliMUONPad* addedPad = cluster.AddPad(*pad);
207 :
208 0 : Int_t cathode = pad->Cathode();
209 0 : TObjArray& padArray = *fPads[cathode];
210 0 : delete padArray.Remove(pad);
211 :
212 0 : TIter next(&padArray);
213 : AliMUONPad* testPad;
214 :
215 0 : while ( ( testPad = static_cast<AliMUONPad*>(next())))
216 : {
217 0 : if ( AliMUONPad::AreNeighbours(*testPad,*addedPad) )
218 : {
219 0 : AddPad(cluster,testPad);
220 : }
221 : }
222 0 : }
223 :
224 : //_____________________________________________________________________________
225 : AliMUONCluster*
226 : AliMUONPreClusterFinderV3::NextCluster()
227 : {
228 : /// Returns the next cluster
229 :
230 0 : return static_cast<AliMUONCluster*>(fIterator->Next());
231 : }
232 :
233 : //_____________________________________________________________________________
234 : void
235 : AliMUONPreClusterFinderV3::MakeClusters()
236 : {
237 : /// Associate (proto)preclusters to form (pre)clusters
238 :
239 : // AliCodeTimerAuto("",0)
240 :
241 0 : for ( Int_t cathode = 0; cathode < 2; ++cathode )
242 : {
243 0 : TClonesArray& preclusters = *(fPreClusters[cathode]);
244 :
245 0 : TIter next(&preclusters);
246 : AliMUONCluster* preCluster(0x0);
247 :
248 0 : while ( ( preCluster = static_cast<AliMUONCluster*>(next()) ) )
249 : {
250 0 : Int_t id(fClusters->GetLast()+1);
251 0 : AliMUONCluster* cluster = new((*fClusters)[id]) AliMUONCluster;
252 0 : cluster->SetUniqueID(id);
253 0 : AddPreCluster(*cluster,preCluster);
254 : }
255 0 : }
256 0 : }
257 :
258 : //_____________________________________________________________________________
259 : void
260 : AliMUONPreClusterFinderV3::MakeCathodePreClusters(Int_t cathode)
261 : {
262 : /// Build (proto)preclusters from digits on a given cathode
263 :
264 : // AliCodeTimerAuto(Form("Cathode %d",cathode),0)
265 :
266 0 : while ( fPads[cathode]->GetLast() > 0 )
267 : {
268 0 : TIter next(fPads[cathode]);
269 0 : AliMUONPad* pad = static_cast<AliMUONPad*>(next());
270 :
271 0 : if (!pad) AliFatal("");
272 :
273 0 : Int_t id = fPreClusters[cathode]->GetLast()+1;
274 0 : AliMUONCluster* cluster = new ((*fPreClusters[cathode])[id]) AliMUONCluster;
275 0 : cluster->SetUniqueID(id);
276 :
277 : // Builds (recursively) a cluster on first cathode only
278 0 : AddPad(*cluster,pad);
279 :
280 0 : if ( cluster->Multiplicity() <= 1 )
281 : {
282 0 : if ( cluster->Multiplicity() == 0 )
283 : {
284 : // no pad is suspicious
285 0 : AliWarning("Got an empty cluster...");
286 : }
287 : // else only 1 pad (not suspicious, but kind of useless, probably noise)
288 : // so we remove it from our list
289 0 : fPreClusters[cathode]->Remove(cluster);
290 : // then proceed further
291 : }
292 0 : }
293 :
294 0 : }
|