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