4a489e2d5e8152ec3bd97823c2703cd9d2f737b7
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpPlaneSegmentation.cxx
1 // $Id$
2 // Category: plane
3 //
4 // Class AliMpPlaneSegmentation
5 // ----------------------------
6 // Class describing the segmentation of the plane.
7 //
8 // Transformation of pad characteristics according to sectors:
9 //
10 //   I.  ( posId,  Guassi ), ( i, j), ( x, y)         II. |  I.
11 //  II.  ( posId', Guassi'), (-i, j), (-x, y)       _____ | ____
12 // III.  (-posId,  Guassi),  (-i,-j), (-x,-y)             |
13 //  IV.  (-posId', Guassi'), ( i,-j), ( x,-y)        III. |  IV.
14 //   
15 // Where (posId', Guassi') is the location of the pad
16 // in the clipped sector.
17 //
18 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
19
20 #include <Riostream.h>
21 #include <TMath.h>
22
23 #include "AliMpPlaneSegmentation.h"
24 #include "AliMpPlaneAreaPadIterator.h"
25 #include "AliMpPlane.h"
26 #include "AliMpSectorPosition.h"
27 #include "AliMpSectorSegmentation.h"
28
29 ClassImp(AliMpPlaneSegmentation)
30
31 //_____________________________________________________________________________
32 AliMpPlaneSegmentation::AliMpPlaneSegmentation(const AliMpPlane* plane) 
33   : AliMpVSegmentation(),
34     fkPlane(plane),
35     fFrontSectorSegmentation(0),
36     fBackSectorSegmentation(0)
37 {
38 //
39   fFrontSectorSegmentation = new AliMpSectorSegmentation(plane->GetFrontSector());
40   fBackSectorSegmentation = new AliMpSectorSegmentation(plane->GetBackSector());
41   
42   for (Int_t i=0; i<fkPlane->GetNofSectorPositions(); i++) {
43
44 #ifdef WITH_STL
45     fTransformers.push_back(
46       new AliMpTransformer(fkPlane->GetSectorPosition(i)->GetOffset(),
47                            fkPlane->GetSectorPosition(i)->GetScale()));
48 #endif
49
50 #ifdef WITH_ROOT
51     fTransformers.Add(
52       new AliMpTransformer(fkPlane->GetSectorPosition(i)->GetOffset(),
53                            fkPlane->GetSectorPosition(i)->GetScale()));
54 #endif
55  }                     
56 }
57
58 ///_____________________________________________________________________________
59 AliMpPlaneSegmentation::AliMpPlaneSegmentation() 
60   : AliMpVSegmentation(),
61     fkPlane(0),
62     fFrontSectorSegmentation(0),
63     fBackSectorSegmentation(0)
64 {
65 //
66 }
67
68 //_____________________________________________________________________________
69 AliMpPlaneSegmentation::~AliMpPlaneSegmentation() {
70 // 
71   delete fFrontSectorSegmentation;
72   delete fBackSectorSegmentation;
73
74   for (Int_t i=0; i<GetNofTransformers(); i++) 
75     delete GetTransformer(i);
76 }
77
78 //
79 // private methods
80 //
81
82 //_____________________________________________________________________________
83 const AliMpTransformer* 
84 AliMpPlaneSegmentation::GetTransformer(const AliMpIntPair& scale) const
85 {
86 // Returns the sector position specified by scale.
87 // ---
88
89   for (Int_t i=0; i<GetNofTransformers(); i++) 
90     if (GetTransformer(i)->GetScale() == scale) return GetTransformer(i);
91
92   Fatal("GetTransformer", "Wrong scale");
93   return 0; 
94 }
95
96 //_____________________________________________________________________________
97 AliMpIntPair AliMpPlaneSegmentation::GetScale(const AliMpIntPair& pair) const
98 {
99 // Returns pair of the signs of the values of the given pair.
100 // ---
101
102   AliMpIntPair scale(1, 1);
103   
104   if (pair.GetFirst() < 0)  scale.SetFirst(-1);
105   if (pair.GetSecond() < 0) scale.SetSecond(-1);
106   
107   return scale;
108 }
109
110 //_____________________________________________________________________________
111 AliMpIntPair AliMpPlaneSegmentation::GetScale(const TVector2& vector) const
112 {
113 // Returns pair of the signs of the values of the given vector.
114 // ---
115
116   AliMpIntPair scale(1, 1);
117   
118   if (vector.X() < 0) scale.SetFirst(-1);
119   if (vector.Y() < 0) scale.SetSecond(-1);
120   
121   return scale;
122 }
123
124 //_____________________________________________________________________________
125 AliMpIntPair 
126 AliMpPlaneSegmentation::GetLocationScale(const AliMpIntPair& location) const
127 {
128 // Returns the scale transformation of the specified location. 
129 // ---
130
131   // Find the sector
132   Bool_t inFront;
133   if (fFrontSectorSegmentation
134         ->HasMotifPosition(TMath::Abs(location.GetFirst())))
135     inFront = true;
136   else if (fBackSectorSegmentation
137              ->HasMotifPosition(TMath::Abs(location.GetFirst())))  
138     inFront = false;
139   else {
140     Fatal("GetLocationScale", "Motif position not found.");
141     return AliMpIntPair();
142   }  
143     
144   if      (inFront  && location.GetFirst() > 0) return  AliMpIntPair(1, 1); 
145   else if (inFront  && location.GetFirst() < 0) return  AliMpIntPair(-1, -1);
146   else if (!inFront && location.GetFirst() > 0) return  AliMpIntPair(-1, 1);
147   else if (!inFront && location.GetFirst() < 0) return  AliMpIntPair( 1,-1);  
148
149   // cannot get there
150   Fatal("GetLocationScale", "Condition failed.");
151   return AliMpIntPair();
152 }
153
154
155 //_____________________________________________________________________________
156 AliMpSectorSegmentation* 
157 AliMpPlaneSegmentation::GetSectorSegmentation(const AliMpIntPair& scale) const
158 {    
159 // Returns front sector or back sector segmentation
160 // according to quadrant specified by scale.
161 // ---
162
163   if (scale.GetFirst()*scale.GetSecond() > 0) {
164     // quadrant I or III
165     return fFrontSectorSegmentation;
166   }  
167   else  {
168     // quadrant II or IV
169     return fBackSectorSegmentation;
170   }  
171 }
172
173 //_____________________________________________________________________________
174 AliMpSectorSegmentation* 
175 AliMpPlaneSegmentation::GetSectorSegmentation(Int_t motifPositionId) const
176 {    
177 // Returns front sector or back sector segmentation
178 // according to specified motifPositionId
179 // ---
180
181   if (fFrontSectorSegmentation->HasMotifPosition(motifPositionId))
182     return fFrontSectorSegmentation;
183   else if (fBackSectorSegmentation->HasMotifPosition(motifPositionId)) 
184     return fBackSectorSegmentation;
185   else {
186     Fatal("GetSectorSegmentation", "Motif position not found.");
187     return 0;
188   }
189 }
190
191 //
192 // public methods
193 //
194
195 //_____________________________________________________________________________
196 AliMpVPadIterator* 
197 AliMpPlaneSegmentation::CreateIterator(const AliMpArea& area) const
198 {
199 // Creates the are iterator. 
200 // (The inherited method cannot be used)
201 // ---
202
203   return new AliMpPlaneAreaPadIterator(this, area);  
204 }   
205   
206 //______________________________________________________________________________
207 AliMpPad AliMpPlaneSegmentation::PadByLocation(const AliMpIntPair& location, 
208                                        Bool_t warning) const
209 {
210 // Find the pad which corresponds to the given location
211 // ---
212
213   // Get segmentation
214   AliMpSectorSegmentation* segmentation 
215     = GetSectorSegmentation(TMath::Abs(location.GetFirst()));
216
217   // Get pad in the segmentation
218   AliMpPad pad
219      = segmentation
220        ->PadByLocation(
221            AliMpIntPair(TMath::Abs(location.GetFirst()),location.GetSecond()), 
222                         warning);
223
224   // Get transformation
225   AliMpIntPair scale  = GetLocationScale(location);
226   const AliMpTransformer* kTransformer = GetTransformer(scale);
227   
228   // Transform pad characteristics
229   return kTransformer->Transform(pad);        
230 }
231
232 //______________________________________________________________________________
233 AliMpPad AliMpPlaneSegmentation::PadByIndices (const AliMpIntPair& indices,
234                                                Bool_t warning ) const
235 {
236 // Find the pad which corresponds to the given indices  
237 //
238
239   AliMpIntPair scale = GetScale(indices);
240   const AliMpTransformer* kTransformer = GetTransformer(scale);
241
242   AliMpIntPair scaledIndices = kTransformer->Scale(indices);
243   AliMpPad pad 
244     = GetSectorSegmentation(scale)->PadByIndices(scaledIndices, warning);
245     
246   return kTransformer->Transform(pad);        
247 }
248
249 //_____________________________________________________________________________
250 AliMpPad AliMpPlaneSegmentation::PadByPosition(const TVector2& position,
251                                                Bool_t warning) const
252 {
253 // Find the pad which corresponds to the given position
254 // ---
255
256   AliMpIntPair scale = GetScale(position);
257   const AliMpTransformer* kTransformer = GetTransformer(scale);
258
259   TVector2 scaledPosition = kTransformer->ITransform(position);  
260   AliMpPad pad 
261     = GetSectorSegmentation(scale)->PadByPosition(scaledPosition, warning);
262   
263   return kTransformer->Transform(pad);        
264 }
265
266 //_____________________________________________________________________________
267 Bool_t AliMpPlaneSegmentation::HasPad(const AliMpIntPair& indices) const
268 {
269 // Does the pad located by <indices> exists ?
270 // ---
271
272   AliMpIntPair scale = GetScale(indices);
273   const AliMpTransformer* kTransformer = GetTransformer(scale);
274
275   AliMpIntPair scaledIndices = kTransformer->Scale(indices);
276
277   return GetSectorSegmentation(scale)->HasPad(scaledIndices);
278 }
279
280 //_____________________________________________________________________________
281 Int_t AliMpPlaneSegmentation::Zone(const AliMpPad& pad, Bool_t warning) const
282 {
283 // Returns the zone index of the zone containing the specified pad.
284 // This zone index is different from the zone ID,
285 // as it is unique for each pad dimensions.
286 // It is composed in this way:
287 //   sectorID*100 + zoneID*10 + specific index 
288 // Where sectorID = 0,1 for front/back sector.
289 // Specific index is present only for zones containing special motifs.
290 // ---
291
292   if (!pad.IsValid()) {
293     if (warning) Warning("Zone(AliMpPad)", "Invalid pad");
294     return 0;
295   }  
296
297   AliMpIntPair scale = GetScale(pad.GetIndices());  
298   const AliMpTransformer* kTransformer = GetTransformer(scale);
299
300   AliMpPad scaledPad = kTransformer->ITransform(pad);
301   
302   AliMpSectorSegmentation* segmentation = GetSectorSegmentation(scale);
303   Int_t zoneID = segmentation->Zone(scaledPad, warning);
304   
305   // Distinguish zones from front/back sector
306   // For back sector - add 10
307   if (segmentation == fBackSectorSegmentation) zoneID += 100;
308
309   return zoneID;
310 }  
311
312 //_____________________________________________________________________________
313 TVector2 
314 AliMpPlaneSegmentation::PadDimensions(Int_t zone, Bool_t warning) const
315 {
316 // Returns the pad dimensions for the zone with the specified zone index.
317 // ---
318
319   if (zone < 100)
320     return fFrontSectorSegmentation->PadDimensions(zone, warning);
321   else  
322     return fBackSectorSegmentation->PadDimensions(zone - 100, warning);
323 }  
324
325 //_____________________________________________________________________________
326 Bool_t AliMpPlaneSegmentation::CircleTest(const AliMpIntPair& indices) const
327 {
328 // Verifies that all methods for retrieving pads are consistents between them.
329 // Returns true if the pad with specified indices was found and verified,
330 // false otherwise.
331 // ---
332
333   if (!HasPad(indices)) return false;
334
335   // Verify the indice->location->position->indice way
336   AliMpIntPair location = PadByIndices(indices).GetLocation();
337   TVector2 position = PadByLocation(location).Position();
338   AliMpIntPair retIndices = PadByPosition(position).GetIndices();
339     
340   if (retIndices != indices) {
341     cout << "Pad " << indices << " lead to inconsistency" << endl;
342     cout << "in indice->location->position->indice way..." << endl;
343     cout << "starting from " << indices << "-->" << location << "-->" 
344          << '(' << position.X() << ',' << position.Y() << ')'
345          << " and retIndices: " << retIndices << endl;
346   }
347     
348     
349   // Verify the indice->position->location->indice way    
350   position = PadByIndices(indices).Position();
351   location = PadByPosition(position).GetLocation();
352   retIndices = PadByLocation(location).GetIndices();
353
354   if (retIndices != indices) {
355     cout << "Pad " << indices << " lead to inconsistency" << endl;
356     cout << "in indice->position->location->indice way..." <<endl;
357     cout << "starting from " << indices 
358          << " and retIndices: " << retIndices << endl;
359   }
360   
361   return true;
362
363 }
364
365 //_____________________________________________________________________________
366 Int_t AliMpPlaneSegmentation::GetNofTransformers() const
367 {
368 // Returns number of transformers.
369 // ---
370
371 #ifdef WITH_STL
372   return fTransformers.size();
373 #endif
374
375 #ifdef WITH_ROOT
376   return fTransformers.GetEntriesFast();
377 #endif
378 }  
379
380
381 //_____________________________________________________________________________
382 AliMpTransformer* AliMpPlaneSegmentation::GetTransformer(Int_t i) const
383 {
384 // Returns i-th transformer.
385 // ---
386  
387 #ifdef WITH_STL
388   return  fTransformers[i];
389 #endif
390
391 #ifdef WITH_ROOT
392   return  (AliMpTransformer*)fTransformers[i];
393 #endif
394 }     
395
396