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