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