]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSimpleClusterServer.cxx
542661be70ea50ed888569b3d244d0028fda1004
[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 "AliMpVPadIterator.h"
34 #include "AliMpVSegmentation.h"
35 #include "AliLog.h"
36 #include <float.h>
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       {
97         Double_t xmin(FLT_MAX);
98         Double_t xmax(-FLT_MAX);
99         Double_t ymin(FLT_MAX);
100         Double_t ymax(-FLT_MAX);
101         
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;
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       }
136       
137       fDEAreas->Add(detElemId,new AliMpArea(TVector2(xg,yg),TVector2(dx,dy)));
138      
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