]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONSimpleClusterServer.cxx
Changes needed by the following commit: coding convention for type (_t) and access...
[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             
233             // skip virtual pads
234             if (!pad->IsReal()) continue;
235             
236             rawCluster->AddDigitId(pad->GetUniqueID());
237           }
238           
239           // fill charge and other cluster informations
240           rawCluster->SetCharge(cluster->Charge());
241           rawCluster->SetChi2(cluster->Chi2());
242           
243           Double_t xg, yg, zg;
244           fTransformer.Local2Global(detElemId, 
245                                     cluster->Position().X(), cluster->Position().Y(), 
246                                     0, xg, yg, zg);
247           rawCluster->SetXYZ(xg, yg, zg);
248           
249           AliDebug(1,Form("Adding RawCluster detElemId %4d mult %2d charge %e (xl,yl,zl)=(%e,%e,%e) (xg,yg,zg)=(%e,%e,%e)",
250                           detElemId,rawCluster->GetNDigits(),rawCluster->GetCharge(),
251                           cluster->Position().X(),cluster->Position().Y(),0.0,
252                           xg,yg,zg));
253         }
254       }
255     }
256     it.Next();
257   }
258   
259   AliDebug(1,Form("chamberId = %2d NofClusters after = %d",chamberId,fNCluster));
260
261   return nofAddedClusters;
262 }
263
264 //_____________________________________________________________________________
265 void
266 AliMUONSimpleClusterServer::Global2Local(Int_t detElemId, const AliMpArea& globalArea,
267                                          AliMpArea& localArea) const
268 {
269   /// Convert a global area in local area for a given DE
270   
271   Double_t xl,yl,zl;
272   
273   Double_t zg = AliMUONConstants::DefaultChamberZ(AliMpDEManager::GetChamberId(detElemId));
274   
275   fTransformer.Global2Local(detElemId,
276                              globalArea.Position().X(),globalArea.Position().Y(),zg,
277                              xl,yl,zl);
278   
279   localArea = AliMpArea(TVector2(xl,yl), globalArea.Dimensions());
280 }
281
282 //_____________________________________________________________________________
283 Bool_t
284 AliMUONSimpleClusterServer::Overlap(Int_t detElemId,
285                                     const AliMpArea& area,
286                                     AliMpArea& deArea) const
287 {
288   /// Check whether (global) area overlaps with the given DE.
289   /// If it is, set deArea to the overlap region and convert it
290   /// in the local coordinate system of that DE.
291   
292   Bool_t overlap(kFALSE);
293   
294   AliMpArea* globalDEArea = static_cast<AliMpArea*>(fDEAreas->GetValue(detElemId));
295   
296   AliMpArea overlapArea;
297   
298   if ( area.Overlap(*globalDEArea) )
299   {
300     overlapArea = area.Intersect(*globalDEArea);
301     Global2Local(detElemId,overlapArea,deArea);
302     overlap = kTRUE;
303   }
304   else
305   {
306     deArea = AliMpArea();
307   }
308   
309   AliDebug(1,Form("DE %04d area %s globalDEArea %s overlapArea %s deArea %s overlap=%d",
310                   detElemId,
311                   AsString(area).Data(),
312                   AsString(*globalDEArea).Data(),
313                   AsString(overlapArea).Data(),
314                   AsString(deArea).Data(),
315                   overlap));
316                   
317   return overlap;
318 }
319
320 //_____________________________________________________________________________
321 TClonesArray* 
322 AliMUONSimpleClusterServer::PadArray(Int_t detElemId, Int_t cathode) const
323 {
324   /// Return array for given cathode of given DE
325   
326   return static_cast<TClonesArray*>(fPads[cathode]->GetValue(detElemId));
327 }
328
329 //_____________________________________________________________________________
330 void 
331 AliMUONSimpleClusterServer::UseDigitStore(const AliMUONVDigitStore& digitStore)
332 {
333   /// Convert digitStore into two arrays of AliMUONPads
334
335   delete fPads[0];
336   delete fPads[1];
337   
338   fPads[0] = new AliMpExMap(true);
339   fPads[1] = new AliMpExMap(true);
340   
341   TIter next(digitStore.CreateIterator());
342   AliMUONVDigit* d;
343   
344   while ( ( d = static_cast<AliMUONVDigit*>(next()) ) )
345   {
346     if ( ! d->Charge() > 0 ) continue; // skip void digits.
347     Int_t ix = d->PadX();
348     Int_t iy = d->PadY();
349     Int_t cathode = d->Cathode();
350     Int_t detElemId = d->DetElemId();
351     const AliMpVSegmentation* seg = AliMpSegmentation::Instance()->
352       GetMpSegmentation(detElemId,AliMp::GetCathodType(cathode));
353     AliMpPad pad = seg->PadByIndices(AliMpIntPair(ix,iy));
354     
355     TClonesArray* padArray = PadArray(detElemId,cathode);
356     if (!padArray)
357     {
358       padArray = new TClonesArray("AliMUONPad",100);
359       fPads[cathode]->Add(detElemId,padArray);
360     }
361     
362     AliMUONPad mpad(detElemId,cathode,
363                     ix,iy,pad.Position().X(),pad.Position().Y(),
364                     pad.Dimensions().X(),pad.Dimensions().Y(),
365                     d->Charge());
366     if ( d->IsSaturated() ) mpad.SetSaturated(kTRUE);
367     mpad.SetUniqueID(d->GetUniqueID());
368     new ((*padArray)[padArray->GetLast()+1]) AliMUONPad(mpad);      
369   }
370 }
371
372 //_____________________________________________________________________________
373 void 
374 AliMUONSimpleClusterServer::Print(Option_t*) const
375 {
376   /// Printout for debug only
377   
378   AliMpDEIterator it;
379   
380   it.First();
381   
382   while ( !it.IsDone() )
383   {
384     Int_t detElemId = it.CurrentDEId();
385     
386     // printout the number of pads / de, and number of used pads / de
387     
388     if ( ( PadArray(detElemId,0) && PadArray(detElemId,0)->GetLast() >= 0 ) || 
389          ( PadArray(detElemId,1) && PadArray(detElemId,1)->GetLast() >= 0 ) )
390     {
391       cout << Form("---- DE %04d",detElemId) << endl;
392       
393       for ( Int_t cathode = 0; cathode < 2; ++cathode ) 
394       {
395         cout << Form("  -- Cathode %1d",cathode) << endl;
396         
397         TClonesArray* padArray = PadArray(detElemId,cathode);
398         
399         if (!padArray)
400         {
401           cout << "no pad array" << endl;
402         }
403         else if ( padArray->GetLast() < 0 ) 
404         {
405           cout << "no pads" << endl;
406         }
407         else
408         {
409           TIter next(padArray);
410           AliMUONPad* pad;
411           while ( ( pad = static_cast<AliMUONPad*>(next()) ) )
412           {
413             pad->Print("full");
414           }
415         }
416       }
417     }
418     it.Next();
419   }
420 }  
421
422