]> git.uio.no Git - u/mrichter/AliRoot.git/blame - MUON/AliMUONSimpleClusterServer.cxx
In MUONTriggerChamberEfficiency.C:
[u/mrichter/AliRoot.git] / MUON / AliMUONSimpleClusterServer.cxx
CommitLineData
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
9bf6860b 20#include "AliCodeTimer.h"
21#include "AliLog.h"
d08b5461 22#include "AliMUONCluster.h"
9bf6860b 23#include "AliMUONConstants.h"
d08b5461 24#include "AliMUONGeometryTransformer.h"
25#include "AliMUONPad.h"
9bf6860b 26#include "AliMUONTriggerTrackToTrackerClusters.h"
d08b5461 27#include "AliMUONVCluster.h"
28#include "AliMUONVClusterFinder.h"
29#include "AliMUONVClusterStore.h"
30#include "AliMUONVDigitStore.h"
35be7ed7 31#include "AliMUONRecoParam.h"
d08b5461 32#include "AliMpArea.h"
33#include "AliMpDEIterator.h"
34#include "AliMpDEManager.h"
35#include "AliMpExMap.h"
e5b8601d 36#include "AliMpExMapIterator.h"
9bf6860b 37#include "AliMpPad.h"
d08b5461 38#include "AliMpSegmentation.h"
39#include "AliMpVSegmentation.h"
d08b5461 40#include <Riostream.h>
41#include <TClonesArray.h>
42#include <TString.h>
9bf6860b 43#include <float.h>
7deb8eb0 44
d08b5461 45/// \class AliMUONSimpleClusterServer
46///
47/// Implementation of AliMUONVClusterServer interface
48///
49///
50/// \author Laurent Aphecetche, Subatech
51
52/// \cond CLASSIMP
53ClassImp(AliMUONSimpleClusterServer)
54/// \endcond
55
56namespace
57{
58 TString AsString(const AliMpArea& area)
59 {
60 return Form("(X,Y)=(%7.3f,%7.3f) (DX,DY)=(%7.3f,%7.3f)",
6e97fbb8 61 area.GetPositionX(),
62 area.GetPositionY(),
63 area.GetDimensionX(), /// TBCL was Y !!!
64 area.GetDimensionY());
d08b5461 65 }
66}
67
68//_____________________________________________________________________________
9bf6860b 69AliMUONSimpleClusterServer::AliMUONSimpleClusterServer(AliMUONVClusterFinder* clusterFinder,
d08b5461 70 const AliMUONGeometryTransformer& transformer)
2e2d0c44 71: AliMUONVClusterServer(),
72 fDigitStore(0x0),
d08b5461 73 fClusterFinder(clusterFinder),
72dae9ff 74 fkTransformer(transformer),
d08b5461 75 fPads(),
9bf6860b 76 fTriggerTrackStore(0x0),
77 fBypass(0x0)
d08b5461 78{
79 /// Ctor
9bf6860b 80 /// Note that we take ownership of the clusterFinder
d08b5461 81
630711ed 82 fPads[0] = new AliMpExMap;
83 fPads[1] = new AliMpExMap;
7deb8eb0 84
e5b8601d 85 fPadsIterator[0] = fPads[0]->CreateIterator();
86 fPadsIterator[1] = fPads[1]->CreateIterator();
d08b5461 87}
88
89//_____________________________________________________________________________
90AliMUONSimpleClusterServer::~AliMUONSimpleClusterServer()
91{
92 /// Dtor
9bf6860b 93 delete fClusterFinder;
d08b5461 94 delete fPads[0];
95 delete fPads[1];
e5b8601d 96 delete fPadsIterator[0];
97 delete fPadsIterator[1];
9bf6860b 98 delete fBypass;
d08b5461 99}
100
101//_____________________________________________________________________________
102Int_t
103AliMUONSimpleClusterServer::Clusterize(Int_t chamberId,
104 AliMUONVClusterStore& clusterStore,
35be7ed7 105 const AliMpArea& area,
106 const AliMUONRecoParam* recoParam)
d08b5461 107{
108 /// Area is in absolute coordinate. If not valid, means clusterize all
109 /// the chamber.
110 ///
111 /// We first find out the list of DE that have a non-zero overlap with area,
112 /// and then use the clusterfinder to find clusters in those areas (and DE).
113
99c136e1 114 AliCodeTimerAuto(Form("Chamber %d",chamberId),0);
9bf6860b 115
116 if ( fTriggerTrackStore && chamberId >= 6 )
117 {
118 return fBypass->GenerateClusters(chamberId,clusterStore);
119 }
120
35be7ed7 121 if (!recoParam) {
122 AliError("Reconstruction parameters are missing: unable to clusterize");
123 return 0;
124 }
125
d08b5461 126 AliMpDEIterator it;
127
128 it.First(chamberId);
129
130 Int_t nofAddedClusters(0);
131 Int_t fNCluster = clusterStore.GetSize();
132
133 AliDebug(1,Form("chamberId = %2d NofClusters before = %d searchArea=%s",
134 chamberId,fNCluster,AsString(area).Data()));
135
136 while ( !it.IsDone() )
137 {
138 Int_t detElemId = it.CurrentDEId();
139
140 TClonesArray* pads[2] =
141 {
142 static_cast<TClonesArray*>(fPads[0]->GetValue(detElemId)),
143 static_cast<TClonesArray*>(fPads[1]->GetValue(detElemId))
144 };
145
146 if ( ( pads[0] && pads[0]->GetLast()>=0 ) ||
147 ( pads[1] && pads[1]->GetLast()>=0 ) )
148 {
149 AliMpArea deArea; // area in DE-local-coordinates
150 Bool_t ok(kTRUE);
151
152 if ( area.IsValid() )
153 {
154 ok = Overlap(detElemId,area,deArea);
155 }
156
157 if ( ok )
158 {
2e2d0c44 159 const AliMpVSegmentation* seg[2] =
d08b5461 160 { AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath0),
161 AliMpSegmentation::Instance()->GetMpSegmentation(detElemId,AliMp::kCath1)
162 };
110edb51 163
164 fClusterFinder->SetChargeHints(recoParam->LowestPadCharge(),
165 recoParam->LowestClusterCharge());
166
2e2d0c44 167 if ( fClusterFinder->NeedSegmentation() )
168 {
9bf6860b 169 fClusterFinder->Prepare(detElemId,pads,deArea,seg);
d08b5461 170 }
171 else
172 {
9bf6860b 173 fClusterFinder->Prepare(detElemId,pads,deArea);
d08b5461 174 }
175
176 AliDebug(1,Form("Clusterizing DE %04d with %3d pads (cath0) and %3d pads (cath1)",
177 detElemId,
178 (pads[0] ? pads[0]->GetLast()+1 : 0),
179 (pads[1] ? pads[1]->GetLast()+1 : 0)));
180
181 AliMUONCluster* cluster;
182
9bf6860b 183 while ( ( cluster = fClusterFinder->NextCluster() ) )
d08b5461 184 {
185 // add new cluster to the store with information to build its ID
186 // increment the number of clusters into the store
35be7ed7 187 AliMUONVCluster* rawCluster = clusterStore.Add(chamberId, detElemId, fNCluster++);
d08b5461 188
189 ++nofAddedClusters;
190
191 // fill array of Id of digits attached to this cluster
192 Int_t nPad = cluster->Multiplicity();
193 if (nPad < 1) AliWarning("no pad attached to the cluster");
194
195 for (Int_t iPad=0; iPad<nPad; iPad++)
196 {
197 AliMUONPad *pad = cluster->Pad(iPad);
89b4e052 198
199 // skip virtual pads
200 if (!pad->IsReal()) continue;
201
202 rawCluster->AddDigitId(pad->GetUniqueID());
d08b5461 203 }
204
205 // fill charge and other cluster informations
206 rawCluster->SetCharge(cluster->Charge());
89b4e052 207 rawCluster->SetChi2(cluster->Chi2());
d08b5461 208
209 Double_t xg, yg, zg;
72dae9ff 210 fkTransformer.Local2Global(detElemId,
d08b5461 211 cluster->Position().X(), cluster->Position().Y(),
212 0, xg, yg, zg);
213 rawCluster->SetXYZ(xg, yg, zg);
35be7ed7 214 rawCluster->SetErrXY(recoParam->GetDefaultNonBendingReso(chamberId),recoParam->GetDefaultBendingReso(chamberId));
d08b5461 215
91b67b6f 216 // Set MC label
217 if (fDigitStore && fDigitStore->HasMCInformation())
218 {
219 rawCluster->SetMCLabel(FindMCLabel(*cluster, detElemId, seg));
220 }
221
2e2d0c44 222 AliDebug(1,Form("Adding RawCluster detElemId %4d mult %2d charge %e (xl,yl,zl)=(%e,%e,%e) (xg,yg,zg)=(%e,%e,%e) label %d",
89b4e052 223 detElemId,rawCluster->GetNDigits(),rawCluster->GetCharge(),
d08b5461 224 cluster->Position().X(),cluster->Position().Y(),0.0,
2e2d0c44 225 xg,yg,zg,rawCluster->GetMCLabel()));
d08b5461 226 }
227 }
228 }
229 it.Next();
230 }
231
232 AliDebug(1,Form("chamberId = %2d NofClusters after = %d",chamberId,fNCluster));
91b67b6f 233
d08b5461 234 return nofAddedClusters;
235}
236
9bf6860b 237
d08b5461 238//_____________________________________________________________________________
239void
240AliMUONSimpleClusterServer::Global2Local(Int_t detElemId, const AliMpArea& globalArea,
241 AliMpArea& localArea) const
242{
243 /// Convert a global area in local area for a given DE
244
245 Double_t xl,yl,zl;
246
247 Double_t zg = AliMUONConstants::DefaultChamberZ(AliMpDEManager::GetChamberId(detElemId));
248
72dae9ff 249 fkTransformer.Global2Local(detElemId,
6e97fbb8 250 globalArea.GetPositionX(),globalArea.GetPositionY(),zg,
d08b5461 251 xl,yl,zl);
252
6e97fbb8 253 localArea = AliMpArea(xl,yl, globalArea.GetDimensionX(), globalArea.GetDimensionY());
d08b5461 254}
255
256//_____________________________________________________________________________
257Bool_t
258AliMUONSimpleClusterServer::Overlap(Int_t detElemId,
259 const AliMpArea& area,
260 AliMpArea& deArea) const
261{
262 /// Check whether (global) area overlaps with the given DE.
263 /// If it is, set deArea to the overlap region and convert it
264 /// in the local coordinate system of that DE.
265
266 Bool_t overlap(kFALSE);
267
72dae9ff 268 AliMpArea* globalDEArea = fkTransformer.GetDEArea(detElemId);
9bf6860b 269
270 if (!globalDEArea) return kFALSE;
d08b5461 271
272 AliMpArea overlapArea;
273
274 if ( area.Overlap(*globalDEArea) )
275 {
276 overlapArea = area.Intersect(*globalDEArea);
277 Global2Local(detElemId,overlapArea,deArea);
278 overlap = kTRUE;
279 }
280 else
281 {
282 deArea = AliMpArea();
283 }
284
285 AliDebug(1,Form("DE %04d area %s globalDEArea %s overlapArea %s deArea %s overlap=%d",
286 detElemId,
287 AsString(area).Data(),
288 AsString(*globalDEArea).Data(),
289 AsString(overlapArea).Data(),
290 AsString(deArea).Data(),
291 overlap));
292
293 return overlap;
294}
295
296//_____________________________________________________________________________
297TClonesArray*
298AliMUONSimpleClusterServer::PadArray(Int_t detElemId, Int_t cathode) const
299{
300 /// Return array for given cathode of given DE
301
302 return static_cast<TClonesArray*>(fPads[cathode]->GetValue(detElemId));
303}
304
9bf6860b 305//_____________________________________________________________________________
306Bool_t
307AliMUONSimpleClusterServer::UseTriggerTrackStore(AliMUONVTriggerTrackStore* trackStore)
308{
309 /// Tells us to use trigger track store, and thus to bypass St45 clusters
310 fTriggerTrackStore = trackStore; // not owner
311 delete fBypass;
72dae9ff 312 fBypass = new AliMUONTriggerTrackToTrackerClusters(fkTransformer,fTriggerTrackStore);
9bf6860b 313 return kTRUE;
314}
315
d08b5461 316//_____________________________________________________________________________
317void
2e2d0c44 318AliMUONSimpleClusterServer::UseDigits(TIter& next, AliMUONVDigitStore* digitStore)
d08b5461 319{
320 /// Convert digitStore into two arrays of AliMUONPads
2e2d0c44 321
322 fDigitStore = digitStore;
323
e5b8601d 324 // Clear pads arrays in the maps
325 for ( Int_t i=0; i<2; i++ ) {
326 fPadsIterator[i]->Reset();
327 Int_t key; TObject* obj;
328 while ( ( obj = fPadsIterator[i]->Next(key) ) ) {
329 //cout << "clearing array for detElemId " << key << " ";
330 obj->Clear();
331 }
332 }
333
d08b5461 334 AliMUONVDigit* d;
d08b5461 335 while ( ( d = static_cast<AliMUONVDigit*>(next()) ) )
336 {
337 if ( ! d->Charge() > 0 ) continue; // skip void digits.
338 Int_t ix = d->PadX();
339 Int_t iy = d->PadY();
340 Int_t cathode = d->Cathode();
341 Int_t detElemId = d->DetElemId();
342 const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->
343 GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
168e9c4d 344 AliMpPad pad = seg->PadByIndices(ix,iy);
d08b5461 345
346 TClonesArray* padArray = PadArray(detElemId,cathode);
347 if (!padArray)
348 {
349 padArray = new TClonesArray("AliMUONPad",100);
350 fPads[cathode]->Add(detElemId,padArray);
351 }
352
353 AliMUONPad mpad(detElemId,cathode,
6e97fbb8 354 ix,iy,pad.GetPositionX(),pad.GetPositionY(),
355 pad.GetDimensionX(),pad.GetDimensionY(),
d08b5461 356 d->Charge());
357 if ( d->IsSaturated() ) mpad.SetSaturated(kTRUE);
358 mpad.SetUniqueID(d->GetUniqueID());
359 new ((*padArray)[padArray->GetLast()+1]) AliMUONPad(mpad);
360 }
361}
362
2e2d0c44 363//_____________________________________________________________________________
364Int_t
365AliMUONSimpleClusterServer::FindMCLabel(const AliMUONCluster& cluster, Int_t detElemId, const AliMpVSegmentation* seg[2]) const
366{
367 /// Find the label of the most contributing MC track (-1 in case of failure)
368 /// The data member fDigitStore must be set
369
370 // --- get the digit (if any) located at the cluster position on both cathods ---
371 Int_t nTracks[2] = {0, 0};
372 AliMUONVDigit* digit[2] = {0x0, 0x0};
373 for (Int_t iCath = 0; iCath < 2; iCath++) {
6e97fbb8 374 AliMpPad pad
375 = seg[AliMp::GetCathodType(iCath)]->PadByPosition(cluster.Position().X(), cluster.Position().Y(),kFALSE);
2e2d0c44 376 if (pad.IsValid()) {
168e9c4d 377 digit[iCath] = fDigitStore->FindObject(detElemId, pad.GetManuId(), pad.GetManuChannel(), iCath);
2e2d0c44 378 if (digit[iCath]) nTracks[iCath] = digit[iCath]->Ntracks();
379 }
380 }
381
382 if (nTracks[0] + nTracks[1] == 0) return -1;
383
384 // --- build the list of contributing tracks and of the associated charge ---
385 Int_t* trackId = new Int_t[nTracks[0] + nTracks[1]];
386 Float_t* trackCharge = new Float_t[nTracks[0] + nTracks[1]];
387 Int_t nTracksTot = 0;
388
389 // fill with contributing tracks on first cathod
390 for (Int_t iTrack1 = 0; iTrack1 < nTracks[0]; iTrack1++) {
391 trackId[iTrack1] = digit[0]->Track(iTrack1);
392 trackCharge[iTrack1] = digit[0]->TrackCharge(iTrack1);
393 }
394 nTracksTot = nTracks[0];
395
396 // complement with contributing tracks on second cathod
397 for (Int_t iTrack2 = 0; iTrack2 < nTracks[1]; iTrack2++) {
398 Int_t trackId2 = digit[1]->Track(iTrack2);
399 // check if track exist
400 Bool_t trackExist = kFALSE;
401 for (Int_t iTrack1 = 0; iTrack1 < nTracks[0]; iTrack1++) {
402 if (trackId2 == trackId[iTrack1]) {
403 // complement existing track
404 trackCharge[iTrack1] += digit[1]->TrackCharge(iTrack2);
405 trackExist = kTRUE;
406 break;
407 }
408 }
409 // add the new track
410 if (!trackExist) {
411 trackId[nTracksTot] = trackId2;
412 trackCharge[nTracksTot] = digit[1]->TrackCharge(iTrack2);
413 nTracksTot++;
414 }
415 }
416
417 // --- Find the most contributing track ---
418 Int_t mainTrackId = -1;
419 Float_t maxCharge = 0.;
420 for (Int_t iTrack = 0; iTrack < nTracksTot; iTrack++) {
421 if (trackCharge[iTrack] > maxCharge) {
422 mainTrackId = trackId[iTrack];
423 maxCharge = trackCharge[iTrack];
424 }
425 }
426
427 delete[] trackId;
428 delete[] trackCharge;
429
430 return mainTrackId;
431}
432
d08b5461 433//_____________________________________________________________________________
434void
435AliMUONSimpleClusterServer::Print(Option_t*) const
436{
437 /// Printout for debug only
438
439 AliMpDEIterator it;
440
441 it.First();
442
443 while ( !it.IsDone() )
444 {
445 Int_t detElemId = it.CurrentDEId();
446
447 // printout the number of pads / de, and number of used pads / de
448
449 if ( ( PadArray(detElemId,0) && PadArray(detElemId,0)->GetLast() >= 0 ) ||
450 ( PadArray(detElemId,1) && PadArray(detElemId,1)->GetLast() >= 0 ) )
451 {
452 cout << Form("---- DE %04d",detElemId) << endl;
453
454 for ( Int_t cathode = 0; cathode < 2; ++cathode )
455 {
456 cout << Form(" -- Cathode %1d",cathode) << endl;
457
458 TClonesArray* padArray = PadArray(detElemId,cathode);
459
460 if (!padArray)
461 {
462 cout << "no pad array" << endl;
463 }
464 else if ( padArray->GetLast() < 0 )
465 {
466 cout << "no pads" << endl;
467 }
468 else
469 {
470 TIter next(padArray);
471 AliMUONPad* pad;
472 while ( ( pad = static_cast<AliMUONPad*>(next()) ) )
473 {
474 pad->Print("full");
475 }
476 }
477 }
478 }
479 it.Next();
480 }
481}
482
483