New macro to keep track of timing performances of the segmentation methods (Laurent)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpRow.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 // $MpId: AliMpRow.cxx,v 1.9 2006/05/24 13:58:46 ivana Exp $
18 // Category: sector
19
20 //-----------------------------------------------------------------------------
21 // Class AliMpRow
22 // --------------
23 // Class describing a row composed of the row segments.
24 // Included in AliRoot: 2003/05/02
25 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
26 //-----------------------------------------------------------------------------
27
28 #include "AliMpRow.h"
29 #include "AliMpVRowSegment.h"
30 #include "AliMpVRowSegmentSpecial.h"
31 #include "AliMpRowSegmentRSpecial.h"
32 #include "AliMpVMotif.h"
33 #include "AliMpMotifType.h"
34 #include "AliMpMotifPosition.h"
35 #include "AliMpMotifMap.h"
36 #include "AliMpConstants.h"
37
38 #include "AliLog.h"
39
40 #include <TMath.h>
41 #include <Riostream.h>
42
43 /// \cond CLASSIMP
44 ClassImp(AliMpRow)
45 /// \endcond
46
47 //_____________________________________________________________________________
48 AliMpRow::AliMpRow(Int_t id, AliMpMotifMap* motifMap) 
49   : AliMpVIndexed(),
50     fID(id),
51     fOffsetY(0.),
52     fSegments(),
53     fMotifMap(motifMap)
54 {
55 /// Standard constructor
56 }
57
58 //_____________________________________________________________________________
59 AliMpRow::AliMpRow() 
60   : AliMpVIndexed(),
61     fID(0),
62     fOffsetY(0.),
63     fSegments(),
64     fMotifMap(0)
65 {
66 /// Default constructor
67 }
68
69 //_____________________________________________________________________________
70 AliMpRow::~AliMpRow() 
71 {
72 /// Destructor 
73
74 #ifdef WITH_STL
75   for (Int_t i=0; i<GetNofRowSegments(); i++)
76     delete fSegments[i]; 
77 #endif
78
79 #ifdef WITH_ROOT
80   fSegments.Delete();
81 #endif
82 }
83
84 //
85 // private methods
86 //
87
88 //_____________________________________________________________________________
89 AliMpVRowSegment*  AliMpRow::FindRowSegment(Int_t ix) const
90 {    
91 /// Find first normal row segment with low indices limit >= ix.
92
93   for (Int_t i=0; i<GetNofRowSegments(); i++) {
94     AliMpVRowSegment* segment = GetRowSegment(i);
95
96     if (!dynamic_cast<AliMpVRowSegmentSpecial*>(segment) &&
97          segment->GetHighIndicesLimit().GetFirst() >= ix)
98          
99      return segment;     
100   }   
101
102   return 0;      
103 }
104
105 //_____________________________________________________________________________
106 AliMpMotifPosition*  
107 AliMpRow::FindMotifPosition(AliMpVRowSegment* segment, Int_t ix) const
108 {
109 /// Find first motif position in the specified row segment 
110 /// with high indices limit >= ix.
111
112   if (!segment) return 0;
113
114   for (Int_t i=0; i<segment->GetNofMotifs(); i++){
115      AliMpMotifPosition* motifPosition 
116        = GetMotifMap()->FindMotifPosition(segment->GetMotifPositionId(i));
117        
118      if(!motifPosition) {
119        Fatal("FindMotifPosition", "Not found.");
120        return 0;
121      }  
122      
123      if (motifPosition->GetHighIndicesLimit().GetFirst()>=ix) 
124        return motifPosition;
125   }
126   
127   return 0;     
128 }
129
130
131 //_____________________________________________________________________________
132 void AliMpRow::SetHighIndicesLimits(Int_t iy)
133 {
134 /// Set the global indices high limit to its row segments,
135 /// motif positions with a given value.
136 /// Keep ix unmodified.
137
138   for (Int_t j=0; j<GetNofRowSegments(); j++) {
139      AliMpVRowSegment* rowSegment = GetRowSegment(j);       
140      rowSegment
141        ->SetHighIndicesLimit(
142             AliMpIntPair(rowSegment->GetHighIndicesLimit().GetFirst(),iy));
143
144     for (Int_t k=0; k<rowSegment->GetNofMotifs(); k++) {
145
146       Int_t motifPositionId = rowSegment->GetMotifPositionId(k);
147       AliMpMotifPosition* motifPosition 
148         = GetMotifMap()->FindMotifPosition(motifPositionId);
149
150       motifPosition
151         ->SetHighIndicesLimit(
152              AliMpIntPair(motifPosition->GetHighIndicesLimit().GetFirst(), iy));
153      
154     }
155   }  
156 }
157
158 //_____________________________________________________________________________
159 void  AliMpRow::CheckEmpty() const
160 {
161 /// Give a fatal if the row is empty.
162
163   if (GetNofRowSegments() == 0) 
164     Fatal("CheckEmpty", "Empty row");
165 }
166
167 //
168 // public methods
169 //
170
171 //_____________________________________________________________________________
172 void AliMpRow::AddRowSegment(AliMpVRowSegment* rowSegment)
173 {
174 /// Add row segment at the end.
175
176 #ifdef WITH_STL
177   fSegments.push_back(rowSegment);
178 #endif
179
180 #ifdef WITH_ROOT
181   fSegments.Add(rowSegment);
182 #endif
183 }  
184   
185 //_____________________________________________________________________________
186 void AliMpRow::AddRowSegmentInFront(AliMpVRowSegment* rowSegment)
187 {
188 /// Insert row segment in the first vector position.
189
190 #ifdef WITH_STL
191   fSegments.insert(fSegments.begin(), rowSegment);
192 #endif
193
194 #ifdef WITH_ROOT
195   fSegments.AddFirst(rowSegment);
196 #endif
197 }  
198   
199 //_____________________________________________________________________________
200 AliMpVRowSegment* AliMpRow::FindRowSegment(Double_t x) const
201 {
202 /// Find the row segment for the specified x position;
203 /// return 0 if no row segment is found.
204
205   for (Int_t i=0; i<GetNofRowSegments(); i++) {
206
207 #ifdef WITH_STL
208     AliMpVRowSegment* rs = fSegments[i];
209 #endif
210 #ifdef WITH_ROOT
211     AliMpVRowSegment* rs = (AliMpVRowSegment*)fSegments.At(i);
212 #endif
213
214     if (x >= rs->LeftBorderX() && x <= rs->RightBorderX())
215       return rs;
216   }
217   
218   return 0;    
219 }    
220
221 //_____________________________________________________________________________
222 Double_t AliMpRow::LowBorderY() const
223 {
224 /// Return the lowest row offset (the Y coordinate of the position of the
225 /// low border of motif).
226
227   CheckEmpty();
228
229   return fOffsetY - GetRowSegment(0)->HalfSizeY();
230 }  
231
232 //_____________________________________________________________________________
233 Double_t AliMpRow::UpperBorderY() const
234 {
235 /// Return the uppermost row offset (the Y coordinate of the position of the
236 /// upper border of motif).
237 \
238   CheckEmpty();
239
240   return fOffsetY + GetRowSegment(0)->HalfSizeY();
241 }  
242
243 //_____________________________________________________________________________
244 AliMpVPadIterator* AliMpRow::CreateIterator() const
245 {
246 /// Iterator is not implemented.
247
248   Fatal("CreateIterator", "Iterator is not implemented.");
249   
250   return 0;
251 }  
252
253 //_____________________________________________________________________________
254 void AliMpRow::SetMotifPositions()
255 {
256 /// Create motif positions objects and fills them in the motif map.
257
258   CheckEmpty();
259
260   for (Int_t j=0; j<GetNofRowSegments(); j++) {
261      AliMpVRowSegment* rowSegment = GetRowSegment(j);
262
263      for (Int_t k=0; k<rowSegment->GetNofMotifs(); k++) {
264         // Get values 
265         Int_t motifPositionId = rowSegment->GetMotifPositionId(k);
266         AliMpVMotif* motif = rowSegment->GetMotif(k);
267         TVector2 position = rowSegment->MotifCenter(motifPositionId);
268        
269         AliMpMotifPosition* motifPosition 
270           = new AliMpMotifPosition(motifPositionId, motif, position);
271         // set the initial value to of HighIndicesLimit() Invalid()
272         // (this is used for calculation of indices in case of
273         // special row segments)
274         motifPosition->SetHighIndicesLimit(AliMpIntPair::Invalid());
275
276         //Bool_t warn = (rowSegment->GetNofMotifs()==1); 
277         Bool_t warn = true;
278         if (dynamic_cast<AliMpVRowSegmentSpecial*>(rowSegment)) warn = false; 
279                // supress warnings for special row segments
280                // which motifs can overlap the row borders
281                
282         Bool_t added = GetMotifMap()->AddMotifPosition(motifPosition, warn);
283         
284         if (!added) delete motifPosition;       
285      }  
286   }
287 }    
288
289 //_____________________________________________________________________________
290 void AliMpRow::SetGlobalIndices(AliMp::Direction constPadSizeDirection, 
291                                 AliMpRow* rowBefore)
292 {
293 /// Set the global indices limits to its row segments, motif positions
294 /// and itself.
295
296   Int_t ix = AliMpConstants::StartPadIndex();
297   Int_t iy = AliMpConstants::StartPadIndex();
298
299   for (Int_t j=0; j<GetNofRowSegments(); j++) {
300      AliMpVRowSegment* rowSegment = GetRowSegment(j);
301      
302      ix += rowSegment->GetLowIndicesLimit().GetFirst();
303
304      for (Int_t k=0; k<rowSegment->GetNofMotifs(); k++) {
305      
306        // Find the y index value of the low edge
307        if (rowBefore) {
308          if (constPadSizeDirection == AliMp::kY) {
309            iy = rowBefore->GetHighIndicesLimit().GetSecond()+1;
310          } 
311          else {
312            AliMpVRowSegment* seg = rowBefore->FindRowSegment(ix);       
313            AliMpMotifPosition* motPos =  FindMotifPosition(seg, ix);
314            if (!dynamic_cast<AliMpRowSegmentRSpecial*>(rowSegment)) {
315              if (!motPos) 
316                Fatal("SetGlobalIndices", "Motif position in rowBefore not found.");
317            
318              iy = motPos->GetHighIndicesLimit().GetSecond()+1;
319            }  
320          }
321        } 
322
323        // Set (ix, iy) to k-th motif position and update ix
324        ix = rowSegment->SetIndicesToMotifPosition(k, AliMpIntPair(ix, iy));
325     }
326     rowSegment->SetGlobalIndices(rowBefore);    
327   }
328
329   // The low/high indices limits has to be taken as the highest/lowest from all 
330   // row segments
331   Int_t ixl = 9999;
332   Int_t iyl = 9999;
333   Int_t ixh = AliMpConstants::StartPadIndex();
334   Int_t iyh = AliMpConstants::StartPadIndex();
335
336   for (Int_t i=0; i<GetNofRowSegments(); i++) {
337     
338     AliMpVRowSegment* rowSegment = GetRowSegment(i);
339     
340     if ( rowSegment->GetLowIndicesLimit().GetFirst() < ixl ) 
341        ixl = rowSegment->GetLowIndicesLimit().GetFirst();
342        
343     if ( rowSegment->GetLowIndicesLimit().GetSecond() < iyl ) 
344        iyl = rowSegment->GetLowIndicesLimit().GetSecond();
345
346     if ( rowSegment->GetHighIndicesLimit().GetFirst() > ixh ) 
347        ixh = rowSegment->GetHighIndicesLimit().GetFirst();
348        
349     if ( rowSegment->GetHighIndicesLimit().GetSecond() > iyh ) 
350        iyh = rowSegment->GetHighIndicesLimit().GetSecond();
351   }     
352
353   SetLowIndicesLimit(AliMpIntPair(ixl, iyl));
354   SetHighIndicesLimit(AliMpIntPair(ixh, iyh));
355 }
356
357 //_____________________________________________________________________________
358 TVector2  AliMpRow::Position() const
359 {
360 /// Return the position of the row centre.
361
362   Double_t x = (GetRowSegment(0)->LeftBorderX() +
363                 GetRowSegment(GetNofRowSegments()-1)->RightBorderX())/2.;
364                     
365   Double_t y = fOffsetY;  
366     
367   return TVector2(x, y);   
368 }
369
370 //_____________________________________________________________________________
371 TVector2  AliMpRow::Dimensions() const
372 {
373 /// Return the maximum halflengths of the row in x, y.
374
375   Double_t x = (GetRowSegment(GetNofRowSegments()-1)->RightBorderX() -
376                 GetRowSegment(0)->LeftBorderX())/2.;
377                   
378   Double_t y = GetRowSegment(0)->HalfSizeY();  
379     
380   return TVector2(x, y);   
381 }
382
383 //_____________________________________________________________________________
384 void AliMpRow::SetRowSegmentOffsets(const TVector2& offset)
385 {
386 /// Set the row segments offsets in X .
387
388   CheckEmpty();
389   
390   AliMpVRowSegment* previous = 0;
391
392   for (Int_t j=0; j<GetNofRowSegments(); j++) {
393      AliMpVRowSegment* rowSegment = GetRowSegment(j);
394
395      Double_t offsetX;
396      if (previous) 
397       offsetX = previous->RightBorderX();
398     else
399       offsetX = offset.X();  
400   
401     rowSegment->SetOffset(TVector2(offsetX, 0.));
402     previous = rowSegment;  
403   }
404 }
405
406
407 //_____________________________________________________________________________
408 Double_t AliMpRow::SetOffsetY(Double_t offsetY)
409 {
410 /// Set the row offset (the Y coordinate of the position of the
411 /// center of motif) and returns the offset of the top border.
412
413   CheckEmpty();
414
415   AliMpVRowSegment* first = GetRowSegment(0);
416   Double_t rowSizeY = first->HalfSizeY();
417   
418   // Check if all next row segments have motif of
419   // the same size in y
420   for (Int_t i=1; i<GetNofRowSegments(); i++) {
421      Double_t sizeY = GetRowSegment(i)->HalfSizeY();
422      
423      if (TMath::Abs(sizeY - rowSizeY) >= AliMpConstants::LengthTolerance()) {
424        Fatal("SetOffsetY", "Motif with different Y size in one row");
425        return 0.;
426      }  
427   }
428
429   offsetY += rowSizeY ;
430     
431   fOffsetY = offsetY;
432     
433   return offsetY += rowSizeY;
434 }  
435
436 //_____________________________________________________________________________
437 Int_t AliMpRow::GetNofRowSegments() const 
438 {
439 /// Return number of row segments.
440
441 #ifdef WITH_STL
442   return fSegments.size();
443 #endif
444
445 #ifdef WITH_ROOT
446   return fSegments.GetSize();
447 #endif
448 }  
449
450 //_____________________________________________________________________________
451 AliMpVRowSegment* AliMpRow::GetRowSegment(Int_t i) const 
452 {
453 /// Return i-th row segment.
454
455   if (i<0 || i>=GetNofRowSegments()) {
456     AliWarningStream() << "Index outside range" << endl;
457     return 0;
458   }
459   
460 #ifdef WITH_STL
461   return fSegments[i];  
462 #endif
463
464 #ifdef WITH_ROOT
465   return (AliMpVRowSegment*)fSegments.At(i);  
466 #endif
467 }
468