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