]>
Commit | Line | Data |
---|---|---|
d08b5461 | 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 "AliMUONSimpleClusterServer.h" | |
19 | ||
20 | #include "AliMUONConstants.h" | |
21 | #include "AliMUONCluster.h" | |
22 | #include "AliMUONGeometryTransformer.h" | |
23 | #include "AliMUONPad.h" | |
24 | #include "AliMUONVCluster.h" | |
25 | #include "AliMUONVClusterFinder.h" | |
26 | #include "AliMUONVClusterStore.h" | |
27 | #include "AliMUONVDigitStore.h" | |
28 | #include "AliMpArea.h" | |
29 | #include "AliMpDEIterator.h" | |
30 | #include "AliMpDEManager.h" | |
31 | #include "AliMpExMap.h" | |
32 | #include "AliMpSegmentation.h" | |
2e749af3 | 33 | #include "AliMpVPadIterator.h" |
d08b5461 | 34 | #include "AliMpVSegmentation.h" |
35 | #include "AliLog.h" | |
2e749af3 | 36 | #include <float.h> |
d08b5461 | 37 | #include <Riostream.h> |
38 | #include <TClonesArray.h> | |
39 | #include <TString.h> | |
40 | ||
41 | /// \class AliMUONSimpleClusterServer | |
42 | /// | |
43 | /// Implementation of AliMUONVClusterServer interface | |
44 | /// | |
45 | /// | |
46 | /// \author Laurent Aphecetche, Subatech | |
47 | ||
48 | /// \cond CLASSIMP | |
49 | ClassImp(AliMUONSimpleClusterServer) | |
50 | /// \endcond | |
51 | ||
52 | namespace | |
53 | { | |
54 | TString AsString(const AliMpArea& area) | |
55 | { | |
56 | return Form("(X,Y)=(%7.3f,%7.3f) (DX,DY)=(%7.3f,%7.3f)", | |
57 | area.Position().X(), | |
58 | area.Position().Y(), | |
59 | area.Dimensions().Y(), | |
60 | area.Dimensions().Y()); | |
61 | } | |
62 | } | |
63 | ||
64 | //_____________________________________________________________________________ | |
65 | AliMUONSimpleClusterServer::AliMUONSimpleClusterServer(AliMUONVClusterFinder& clusterFinder, | |
66 | const AliMUONGeometryTransformer& transformer) | |
67 | : AliMUONVClusterServer(), | |
68 | fClusterFinder(clusterFinder), | |
69 | fTransformer(transformer), | |
70 | fPads(), | |
71 | fDEAreas(new AliMpExMap(true)) | |
72 | { | |
73 | /// Ctor | |
74 | ||
75 | AliMpDEIterator it; | |
76 | ||
77 | it.First(); | |
78 | ||
79 | /// Generate the DE areas in global coordinates | |
80 | ||
81 | while ( !it.IsDone() ) | |
82 | { | |
83 | Int_t detElemId = it.CurrentDEId(); | |
84 | ||
85 | const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0); | |
86 | ||
87 | Double_t xg,yg,zg; | |
88 | ||
89 | AliMp::StationType stationType = AliMpDEManager::GetStationType(detElemId); | |
90 | ||
91 | Double_t xl(0.0), yl(0.0), zl(0.0); | |
92 | Double_t dx(seg->Dimensions().X()); | |
93 | Double_t dy(seg->Dimensions().Y()); | |
94 | ||
95 | if ( stationType == AliMp::kStation1 || stationType == AliMp::kStation2 ) | |
96 | { | |
2e749af3 | 97 | Double_t xmin(FLT_MAX); |
98 | Double_t xmax(-FLT_MAX); | |
99 | Double_t ymin(FLT_MAX); | |
100 | Double_t ymax(-FLT_MAX); | |
d08b5461 | 101 | |
2e749af3 | 102 | for ( Int_t icathode = 0; icathode < 2; ++icathode ) |
103 | { | |
104 | const AliMpVSegmentation* cathode | |
105 | = AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::GetCathodType(icathode)); | |
106 | ||
107 | AliMpVPadIterator* it = cathode->CreateIterator(); | |
108 | ||
109 | it->First(); | |
110 | ||
111 | while ( !it->IsDone() ) | |
112 | { | |
113 | AliMpPad pad = it->CurrentItem(); | |
114 | AliMpArea a(pad.Position(),pad.Dimensions()); | |
115 | xmin = TMath::Min(xmin,a.LeftBorder()); | |
116 | xmax = TMath::Max(xmax,a.RightBorder()); | |
117 | ymin = TMath::Min(ymin,a.DownBorder()); | |
118 | ymax = TMath::Max(ymax,a.UpBorder()); | |
119 | it->Next(); | |
120 | } | |
121 | ||
122 | delete it; | |
123 | } | |
124 | ||
125 | xl = (xmin+xmax)/2.0; | |
126 | yl = (ymin+ymax)/2.0; | |
127 | dx = (xmax-xmin)/2.0; | |
128 | dy = (ymax-ymin)/2.0; | |
d08b5461 | 129 | |
130 | fTransformer.Local2Global(detElemId,xl,yl,zl,xg,yg,zg); | |
131 | } | |
132 | else | |
133 | { | |
134 | fTransformer.Local2Global(detElemId,xl,yl,zl,xg,yg,zg); | |
135 | } | |
2e749af3 | 136 | |
d08b5461 | 137 | fDEAreas->Add(detElemId,new AliMpArea(TVector2(xg,yg),TVector2(dx,dy))); |
2e749af3 | 138 | |
d08b5461 | 139 | it.Next(); |
140 | } | |
141 | } | |
142 | ||
143 | //_____________________________________________________________________________ | |
144 | AliMUONSimpleClusterServer::~AliMUONSimpleClusterServer() | |
145 | { | |
146 | /// Dtor | |
147 | delete fPads[0]; | |
148 | delete fPads[1]; | |
149 | delete fDEAreas; | |
150 | } | |
151 | ||
152 | //_____________________________________________________________________________ | |
153 | Int_t | |
154 | AliMUONSimpleClusterServer::Clusterize(Int_t chamberId, | |
155 | AliMUONVClusterStore& clusterStore, | |
156 | const AliMpArea& area) | |
157 | { | |
158 | /// Area is in absolute coordinate. If not valid, means clusterize all | |
159 | /// the chamber. | |
160 | /// | |
161 | /// We first find out the list of DE that have a non-zero overlap with area, | |
162 | /// and then use the clusterfinder to find clusters in those areas (and DE). | |
163 | ||
164 | AliMpDEIterator it; | |
165 | ||
166 | it.First(chamberId); | |
167 | ||
168 | Int_t nofAddedClusters(0); | |
169 | Int_t fNCluster = clusterStore.GetSize(); | |
170 | ||
171 | AliDebug(1,Form("chamberId = %2d NofClusters before = %d searchArea=%s", | |
172 | chamberId,fNCluster,AsString(area).Data())); | |
173 | ||
174 | while ( !it.IsDone() ) | |
175 | { | |
176 | Int_t detElemId = it.CurrentDEId(); | |
177 | ||
178 | TClonesArray* pads[2] = | |
179 | { | |
180 | static_cast<TClonesArray*>(fPads[0]->GetValue(detElemId)), | |
181 | static_cast<TClonesArray*>(fPads[1]->GetValue(detElemId)) | |
182 | }; | |
183 | ||
184 | if ( ( pads[0] && pads[0]->GetLast()>=0 ) || | |
185 | ( pads[1] && pads[1]->GetLast()>=0 ) ) | |
186 | { | |
187 | AliMpArea deArea; // area in DE-local-coordinates | |
188 | Bool_t ok(kTRUE); | |
189 | ||
190 | if ( area.IsValid() ) | |
191 | { | |
192 | ok = Overlap(detElemId,area,deArea); | |
193 | } | |
194 | ||
195 | if ( ok ) | |
196 | { | |
197 | if ( fClusterFinder.NeedSegmentation() ) | |
198 | { | |
199 | const AliMpVSegmentation* seg[2] = | |
200 | { AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0), | |
201 | AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath1) | |
202 | }; | |
203 | fClusterFinder.Prepare(detElemId,pads,deArea,seg); | |
204 | } | |
205 | else | |
206 | { | |
207 | fClusterFinder.Prepare(detElemId,pads,deArea); | |
208 | } | |
209 | ||
210 | AliDebug(1,Form("Clusterizing DE %04d with %3d pads (cath0) and %3d pads (cath1)", | |
211 | detElemId, | |
212 | (pads[0] ? pads[0]->GetLast()+1 : 0), | |
213 | (pads[1] ? pads[1]->GetLast()+1 : 0))); | |
214 | ||
215 | AliMUONCluster* cluster; | |
216 | ||
217 | while ( ( cluster = fClusterFinder.NextCluster() ) ) | |
218 | { | |
219 | // add new cluster to the store with information to build its ID | |
220 | // increment the number of clusters into the store | |
221 | AliMUONVCluster* rawCluster = clusterStore.Add(AliMpDEManager::GetChamberId(detElemId), detElemId, fNCluster++); | |
222 | ||
223 | ++nofAddedClusters; | |
224 | ||
225 | // fill array of Id of digits attached to this cluster | |
226 | Int_t nPad = cluster->Multiplicity(); | |
227 | if (nPad < 1) AliWarning("no pad attached to the cluster"); | |
228 | ||
229 | for (Int_t iPad=0; iPad<nPad; iPad++) | |
230 | { | |
231 | AliMUONPad *pad = cluster->Pad(iPad); | |
232 | rawCluster->AddDigitId(pad->GetUniqueID()); | |
233 | } | |
234 | ||
235 | // fill charge and other cluster informations | |
236 | rawCluster->SetCharge(cluster->Charge()); | |
237 | ||
238 | Double_t xg, yg, zg; | |
239 | fTransformer.Local2Global(detElemId, | |
240 | cluster->Position().X(), cluster->Position().Y(), | |
241 | 0, xg, yg, zg); | |
242 | rawCluster->SetXYZ(xg, yg, zg); | |
243 | ||
244 | AliDebug(1,Form("Adding RawCluster detElemId %4d mult %2d charge %e (xl,yl,zl)=(%e,%e,%e) (xg,yg,zg)=(%e,%e,%e)", | |
245 | detElemId,nPad,cluster->Charge(), | |
246 | cluster->Position().X(),cluster->Position().Y(),0.0, | |
247 | xg,yg,zg)); | |
248 | } | |
249 | } | |
250 | } | |
251 | it.Next(); | |
252 | } | |
253 | ||
254 | AliDebug(1,Form("chamberId = %2d NofClusters after = %d",chamberId,fNCluster)); | |
255 | ||
256 | return nofAddedClusters; | |
257 | } | |
258 | ||
259 | //_____________________________________________________________________________ | |
260 | void | |
261 | AliMUONSimpleClusterServer::Global2Local(Int_t detElemId, const AliMpArea& globalArea, | |
262 | AliMpArea& localArea) const | |
263 | { | |
264 | /// Convert a global area in local area for a given DE | |
265 | ||
266 | Double_t xl,yl,zl; | |
267 | ||
268 | Double_t zg = AliMUONConstants::DefaultChamberZ(AliMpDEManager::GetChamberId(detElemId)); | |
269 | ||
270 | fTransformer.Global2Local(detElemId, | |
271 | globalArea.Position().X(),globalArea.Position().Y(),zg, | |
272 | xl,yl,zl); | |
273 | ||
274 | localArea = AliMpArea(TVector2(xl,yl), globalArea.Dimensions()); | |
275 | } | |
276 | ||
277 | //_____________________________________________________________________________ | |
278 | Bool_t | |
279 | AliMUONSimpleClusterServer::Overlap(Int_t detElemId, | |
280 | const AliMpArea& area, | |
281 | AliMpArea& deArea) const | |
282 | { | |
283 | /// Check whether (global) area overlaps with the given DE. | |
284 | /// If it is, set deArea to the overlap region and convert it | |
285 | /// in the local coordinate system of that DE. | |
286 | ||
287 | Bool_t overlap(kFALSE); | |
288 | ||
289 | AliMpArea* globalDEArea = static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId)); | |
290 | ||
291 | AliMpArea overlapArea; | |
292 | ||
293 | if ( area.Overlap(*globalDEArea) ) | |
294 | { | |
295 | overlapArea = area.Intersect(*globalDEArea); | |
296 | Global2Local(detElemId,overlapArea,deArea); | |
297 | overlap = kTRUE; | |
298 | } | |
299 | else | |
300 | { | |
301 | deArea = AliMpArea(); | |
302 | } | |
303 | ||
304 | AliDebug(1,Form("DE %04d area %s globalDEArea %s overlapArea %s deArea %s overlap=%d", | |
305 | detElemId, | |
306 | AsString(area).Data(), | |
307 | AsString(*globalDEArea).Data(), | |
308 | AsString(overlapArea).Data(), | |
309 | AsString(deArea).Data(), | |
310 | overlap)); | |
311 | ||
312 | return overlap; | |
313 | } | |
314 | ||
315 | //_____________________________________________________________________________ | |
316 | TClonesArray* | |
317 | AliMUONSimpleClusterServer::PadArray(Int_t detElemId, Int_t cathode) const | |
318 | { | |
319 | /// Return array for given cathode of given DE | |
320 | ||
321 | return static_cast<TClonesArray*>(fPads[cathode]->GetValue(detElemId)); | |
322 | } | |
323 | ||
324 | //_____________________________________________________________________________ | |
325 | void | |
326 | AliMUONSimpleClusterServer::UseDigitStore(const AliMUONVDigitStore& digitStore) | |
327 | { | |
328 | /// Convert digitStore into two arrays of AliMUONPads | |
329 | ||
330 | delete fPads[0]; | |
331 | delete fPads[1]; | |
332 | ||
333 | fPads[0] = new AliMpExMap(true); | |
334 | fPads[1] = new AliMpExMap(true); | |
335 | ||
336 | TIter next(digitStore.CreateIterator()); | |
337 | AliMUONVDigit* d; | |
338 | ||
339 | while ( ( d = static_cast<AliMUONVDigit*>(next()) ) ) | |
340 | { | |
341 | if ( ! d->Charge() > 0 ) continue; // skip void digits. | |
342 | Int_t ix = d->PadX(); | |
343 | Int_t iy = d->PadY(); | |
344 | Int_t cathode = d->Cathode(); | |
345 | Int_t detElemId = d->DetElemId(); | |
346 | const AliMpVSegmentation* seg = AliMpSegmentation::Instance()-> | |
347 | GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode)); | |
348 | AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy)); | |
349 | ||
350 | TClonesArray* padArray = PadArray(detElemId,cathode); | |
351 | if (!padArray) | |
352 | { | |
353 | padArray = new TClonesArray("AliMUONPad",100); | |
354 | fPads[cathode]->Add(detElemId,padArray); | |
355 | } | |
356 | ||
357 | AliMUONPad mpad(detElemId,cathode, | |
358 | ix,iy,pad.Position().X(),pad.Position().Y(), | |
359 | pad.Dimensions().X(),pad.Dimensions().Y(), | |
360 | d->Charge()); | |
361 | if ( d->IsSaturated() ) mpad.SetSaturated(kTRUE); | |
362 | mpad.SetUniqueID(d->GetUniqueID()); | |
363 | new ((*padArray)[padArray->GetLast()+1]) AliMUONPad(mpad); | |
364 | } | |
365 | } | |
366 | ||
367 | //_____________________________________________________________________________ | |
368 | void | |
369 | AliMUONSimpleClusterServer::Print(Option_t*) const | |
370 | { | |
371 | /// Printout for debug only | |
372 | ||
373 | AliMpDEIterator it; | |
374 | ||
375 | it.First(); | |
376 | ||
377 | while ( !it.IsDone() ) | |
378 | { | |
379 | Int_t detElemId = it.CurrentDEId(); | |
380 | ||
381 | // printout the number of pads / de, and number of used pads / de | |
382 | ||
383 | if ( ( PadArray(detElemId,0) && PadArray(detElemId,0)->GetLast() >= 0 ) || | |
384 | ( PadArray(detElemId,1) && PadArray(detElemId,1)->GetLast() >= 0 ) ) | |
385 | { | |
386 | cout << Form("---- DE %04d",detElemId) << endl; | |
387 | ||
388 | for ( Int_t cathode = 0; cathode < 2; ++cathode ) | |
389 | { | |
390 | cout << Form(" -- Cathode %1d",cathode) << endl; | |
391 | ||
392 | TClonesArray* padArray = PadArray(detElemId,cathode); | |
393 | ||
394 | if (!padArray) | |
395 | { | |
396 | cout << "no pad array" << endl; | |
397 | } | |
398 | else if ( padArray->GetLast() < 0 ) | |
399 | { | |
400 | cout << "no pads" << endl; | |
401 | } | |
402 | else | |
403 | { | |
404 | TIter next(padArray); | |
405 | AliMUONPad* pad; | |
406 | while ( ( pad = static_cast<AliMUONPad*>(next()) ) ) | |
407 | { | |
408 | pad->Print("full"); | |
409 | } | |
410 | } | |
411 | } | |
412 | } | |
413 | it.Next(); | |
414 | } | |
415 | } | |
416 | ||
417 |