]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/AliMUONPreClusterFinder.cxx
Decalibration should use the same CDB as calibration in AliPHOSClusterizerv1
[u/mrichter/AliRoot.git] / MUON / AliMUONPreClusterFinder.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 "AliMUONPreClusterFinder.h"
19
20 #include "AliLog.h"
21 #include "AliMUONCluster.h"
22 #include "AliMpVSegmentation.h"
23 #include "TClonesArray.h"
24 #include "AliMpArea.h"
25 #include "TVector2.h"
26 #include "AliMUONPad.h"
27 #include "AliMUONDigit.h"
28
29 /// \class AliMUONPreClusterFinder
30 ///
31 /// Implementation of AliMUONVClusterFinder
32 ///
33 /// This class simply find adjacent pads to form clusters
34 ///
35 /// \author Laurent Aphecetche
36
37 ClassImp(AliMUONPreClusterFinder)
38
39 //_____________________________________________________________________________
40 AliMUONPreClusterFinder::AliMUONPreClusterFinder()
41 : AliMUONVClusterFinder(),
42   fClusters(0x0),
43   fSegmentations(0x0),
44   fDigits(0x0),
45   fDetElemId(0)
46 {
47     /// ctor
48   for ( Int_t i = 0; i < 2; ++i )
49   {
50     fPads[i] = 0x0;
51   } 
52 }
53
54 //_____________________________________________________________________________
55 AliMUONPreClusterFinder::~AliMUONPreClusterFinder()
56 {
57   /// dtor : note we're owner of the pads and the clusters, but not of
58   /// the remaining objects (digits, segmentations)
59   delete fClusters;
60   for ( Int_t i = 0; i < 2; ++i )
61   {
62     delete fPads[i];
63   }  
64 }
65
66 //_____________________________________________________________________________
67 Bool_t
68 AliMUONPreClusterFinder::UsePad(const AliMUONPad& pad)
69 {
70   /// Add a pad to the list of pads to be considered
71   if ( pad.DetElemId() != fDetElemId )
72   {
73     AliError(Form("Cannot add pad from DE %d to this cluster finder which is "
74                   "currently dealing with DE %d",pad.DetElemId(),fDetElemId));
75     return kFALSE;
76   }
77   
78   new ((*fPads[pad.Cathode()])[fPads[pad.Cathode()]->GetLast()+1]) AliMUONPad(pad); 
79   // FIXME: should set the ClusterId of that new pad to be -1
80   return kTRUE;
81 }
82
83 //_____________________________________________________________________________
84 Bool_t
85 AliMUONPreClusterFinder::Prepare(const AliMpVSegmentation* segmentations[2],
86                                  TClonesArray* digits[2]) 
87 // FIXME : add area on which to look for clusters here.
88 {
89   /// Prepare for clustering, by giving access to segmentations and digit lists
90   
91   fSegmentations = segmentations;
92   fDigits = digits;
93   
94   delete fClusters;
95   fClusters = new TClonesArray("AliMUONCluster");
96   for ( Int_t i = 0; i < 2; ++i )
97   {
98     delete fPads[i];
99     fPads[i] = new TClonesArray("AliMUONPad");
100   }
101   
102   fDetElemId = -1;
103   
104   // Converts digits into pads
105   for ( Int_t cathode = 0; cathode < 2; ++cathode )
106   {
107     if ( !digits[cathode] ) continue;
108
109     AliMUONDigit* d;
110     TIter next(digits[cathode]);
111     while ( ( d = static_cast<AliMUONDigit*>(next())))
112     {
113       Int_t ix = d->PadX();
114       Int_t iy = d->PadY();
115       AliMpPad pad = fSegmentations[cathode]->PadByIndices(AliMpIntPair(ix,iy));
116       TClonesArray& padArray = *(fPads[cathode]);
117       if ( fDetElemId == -1 ) 
118       {
119         fDetElemId = d->DetElemId();
120       }
121       else
122       {
123         if ( d->DetElemId() != fDetElemId ) 
124         {
125           AliError("Something is seriously wrong with DE. Aborting clustering");
126           return kFALSE;
127         }
128       }
129       
130       AliMUONPad mpad(fDetElemId,cathode,
131                       ix,iy,pad.Position().X(),pad.Position().Y(),
132                       pad.Dimensions().X(),pad.Dimensions().Y(),
133                       d->Signal());
134       if ( d->IsSaturated() ) mpad.SetSaturated(kTRUE); 
135       new (padArray[padArray.GetLast()+1]) AliMUONPad(mpad);      
136     }
137   }
138   if ( fPads[0]->GetLast() < 0 && fPads[1]->GetLast() < 0 )
139   {
140     // no pad at all, nothing to do...
141     return kFALSE;
142   }
143
144   return kTRUE;
145 }
146
147 //_____________________________________________________________________________
148 void
149 AliMUONPreClusterFinder::AddPad(AliMUONCluster& cluster, AliMUONPad* pad)
150 {
151   /// Add a pad to a cluster
152   cluster.AddPad(*pad);
153   
154   Int_t cathode = pad->Cathode();
155   TClonesArray& padArray = *fPads[cathode];
156   padArray.Remove(pad);
157   padArray.Compress();
158   TIter next(&padArray);
159   AliMUONPad* testPad;
160   
161   while ( ( testPad = static_cast<AliMUONPad*>(next())))
162   {
163     if ( AliMUONPad::AreNeighbours(*testPad,*pad) )
164     {
165       AddPad(cluster,testPad);
166     }
167   }
168 }
169
170 //_____________________________________________________________________________
171 Bool_t
172 AreOverlapping(const AliMUONPad& pad, const AliMUONCluster& cluster)
173 {
174   /// Whether the pad overlaps with the cluster
175   
176   static Double_t precision = 1E-4; // cm
177   static TVector2 precisionAdjustment(precision,precision);//-precision,-precision);
178   for ( Int_t i = 0; i < cluster.Multiplicity(); ++i )
179   {
180     AliMUONPad* testPad = cluster.Pad(i);
181     // Note: we use negative precision numbers, meaning
182     // the area of the pads will be *increased* by these small numbers
183     // prior to check the overlap by the AreOverlapping method,
184     // so pads touching only by the corners will be considered as
185     // overlapping.    
186     if ( AliMUONPad::AreOverlapping(*testPad,pad,precisionAdjustment) )
187     {
188       return kTRUE;
189     }
190   }
191   return kFALSE;
192 }
193
194 //_____________________________________________________________________________
195 AliMUONCluster* 
196 AliMUONPreClusterFinder::NextCluster()
197 {
198   /// Builds the next cluster, and returns it.
199   
200   // Start a new cluster
201   Int_t id = fClusters->GetLast()+1;
202   AliMUONCluster* cluster = new ((*fClusters)[id]) AliMUONCluster;
203   cluster->SetUniqueID(id);
204   
205   AliMUONPad* pad = static_cast<AliMUONPad*>(fPads[0]->First());
206   
207   if (!pad) // protection against no pad in first cathode, which might happen
208   {
209     // try other cathode
210     pad = static_cast<AliMUONPad*>(fPads[1]->First());
211     if (!pad) 
212     {
213       // we are done.
214       return 0x0;
215     }
216     // Builds (recursively) a cluster on second cathode only
217     AddPad(*cluster,pad);
218   }
219   else
220   {
221     // Builds (recursively) a cluster on first cathode only
222     AddPad(*cluster,pad);
223     
224     // On the 2nd cathode, only add pads overlapping with the current cluster
225     TClonesArray& padArray = *fPads[1];
226     TIter next(&padArray);
227     AliMUONPad* testPad;
228   
229     while ( ( testPad = static_cast<AliMUONPad*>(next())))
230     {
231       if ( AreOverlapping(*testPad,*cluster) )
232       {
233         AddPad(*cluster,testPad);
234       }
235     }
236   }
237   
238   if ( cluster->Multiplicity() <= 1 )
239   {
240     if ( cluster->Multiplicity() == 0 ) 
241     {
242       // no pad is suspicious
243       AliWarning("Got an empty cluster...");
244     }
245     // else only 1 pad (not suspicious, but kind of useless, probably noise)
246     // so we remove it from our list
247     fClusters->Remove(cluster);
248     fClusters->Compress();
249     // then proceed further
250     return NextCluster();
251   }
252   
253   return cluster;
254 }