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