27dfe3b87b236ab878773c9cc0f7f2d6587fd924
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpVRowSegmentSpecial.cxx
1 // $Id$
2 // Category: sector
3 //
4 // Class AliMpVRowSegmentSpecial
5 // ----------------------------
6 // Class describing a special row segment composed of the 
7 // pad rows.
8 //
9 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
10
11 #include <TError.h>
12 #include <Riostream.h>
13
14 #include "AliMpVRowSegmentSpecial.h"
15 #include "AliMpRow.h"
16 #include "AliMpPadRow.h"
17 #include "AliMpVPadRowSegment.h"
18 #include "AliMpMotif.h"
19 #include "AliMpMotifType.h"
20 #include "AliMpMotifMap.h"
21 #include "AliMpMotifPosition.h"
22 #include "AliMpConstants.h"
23
24 ClassImp(AliMpVRowSegmentSpecial)
25
26 #ifdef WITH_ROOT
27 const Int_t  AliMpVRowSegmentSpecial::fgkMaxNofMotifPositionIds = 20;
28 #endif    
29
30 //______________________________________________________________________________
31 AliMpVRowSegmentSpecial::AliMpVRowSegmentSpecial(AliMpRow* row, Double_t offsetX)
32   : AliMpVRowSegment(),
33     fRow(row),
34     fOffsetX(offsetX),
35     fPadRows(),
36     fMotifs(),
37     fMotifPositionIds()
38 #ifdef WITH_ROOT
39     ,fNofMotifPositionIds(0)
40 #endif    
41 {
42 // 
43 }
44
45 //______________________________________________________________________________
46 AliMpVRowSegmentSpecial::AliMpVRowSegmentSpecial() 
47   : AliMpVRowSegment(),
48     fRow(0),
49     fOffsetX(0.),
50     fPadRows(),
51     fMotifs(),
52     fMotifPositionIds()
53 #ifdef WITH_ROOT
54     ,fNofMotifPositionIds(0)
55 #endif    
56 {
57 //
58 #ifdef WITH_ROOT
59    fMotifPositionIds.Set(fgkMaxNofMotifPositionIds);
60 #endif    
61 }
62
63 //______________________________________________________________________________
64 AliMpVRowSegmentSpecial::~AliMpVRowSegmentSpecial() 
65 {
66 //  
67   for (Int_t i=0; i<GetNofPadRows(); i++)
68     delete fPadRows[i];
69 }
70
71 //
72 // protected methods  
73 //
74
75 //______________________________________________________________________________
76 AliMpPadRow*  AliMpVRowSegmentSpecial::FindPadRow(Double_t y) const
77 {
78 // Finds the pad row in the given y coordinate.
79 // ---
80
81   Double_t lowBorder =  fRow->LowBorderY();
82   Double_t highBorder = fRow->LowBorderY();
83   
84   for (Int_t i=0; i<GetNofPadRows(); i++) {    
85
86     AliMpPadRow* padRow = GetPadRow(i);
87     highBorder += 2.*padRow->HalfSizeY();
88
89     if ( y >= lowBorder &&  y <= highBorder)
90       return padRow;
91
92     lowBorder = highBorder;
93   }
94   
95   return 0;     
96 }
97
98 //______________________________________________________________________________
99 AliMpVPadRowSegment*  
100 AliMpVRowSegmentSpecial::FindPadRowSegment(Int_t motifPositionId) const
101 {
102 // Find the most down pad row segment with this motifPositionId.
103 // ---
104
105   for (Int_t i=0; i<GetNofPadRows(); i++) {
106     AliMpPadRow* padRow = GetPadRow(i);    
107
108     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) { 
109       AliMpVPadRowSegment* padRowSegment = padRow->GetPadRowSegment(j);
110
111       if (padRowSegment->GetMotifPositionId() == motifPositionId) 
112         return padRowSegment;
113     }
114   }
115   return 0;     
116 }
117
118 //______________________________________________________________________________
119 AliMpIntPair 
120 AliMpVRowSegmentSpecial::FindRelativeLowIndicesOf(Int_t motifPositionId) const 
121
122 // Returns the lowest pad indices where the motif of the given position ID
123 // exists in this segment.
124 // ---
125
126   AliMpIntPair ans(0,1000);
127   AliMpIntPair ans0 = ans;
128   Int_t maxNofPadsX=0;
129   
130   for (Int_t i=0; i<GetNofPadRows(); i++) {
131     AliMpPadRow* padRow = GetPadRow(i);
132
133     Int_t nofPadsX=0;
134     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) {
135       AliMpVPadRowSegment* padRowSegment = padRow->GetPadRowSegment(j);
136       nofPadsX += padRowSegment->GetNofPads();
137       if (padRowSegment->GetMotifPositionId() == motifPositionId) {
138          if (ans.GetFirst() < nofPadsX) ans.SetFirst(nofPadsX);
139          if (ans.GetSecond()>i) ans.SetSecond(i);
140                   // ans.First = max (nof pads of this pos ID)
141                   // ans.Second = min of pad row number
142       }
143     }  
144     if (nofPadsX > maxNofPadsX) maxNofPadsX = nofPadsX;
145   }    
146   if (ans == ans0) return AliMpIntPair::Invalid();
147   
148   return AliMpIntPair(maxNofPadsX-ans.GetFirst(), ans.GetSecond());
149 }
150  
151 //______________________________________________________________________________
152 Int_t  AliMpVRowSegmentSpecial::MaxNofPadsInRow() const 
153
154 // Returns the maximum number of pads in this row segment along the X direction
155 // ---
156
157   Int_t maxNofPads = 0;    
158
159   for (Int_t i=0; i<GetNofPadRows(); i++){
160     Int_t nofPads = GetPadRow(i)->GetNofPads(); 
161
162     // Find maximum
163     if (nofPads > maxNofPads) maxNofPads = nofPads;
164   }
165     
166   return maxNofPads;
167 }
168
169 //______________________________________________________________________________
170 Bool_t AliMpVRowSegmentSpecial::HasMotif(const AliMpVMotif* motif) const
171 {
172 // Returns true if the specified motif is already in fMotifs vector,
173 // returns false otherwise.
174 // ---
175
176 #ifdef WITH_STL
177   for (UInt_t i=0; i<fMotifs.size(); i++)
178     if (fMotifs[i] == motif) return true;
179 #endif
180
181 #ifdef WITH_ROOT
182   for (Int_t i=0; i<fMotifs.GetEntriesFast(); i++)
183     if (fMotifs[i] == motif) return true;
184 #endif
185
186   return false;  
187 }
188
189 //______________________________________________________________________________
190 Int_t AliMpVRowSegmentSpecial::GetNofPadRows() const
191 {
192 // Returns number of pad rows.
193 // ---
194
195 #ifdef WITH_STL
196   return fPadRows.size();
197 #endif
198
199 #ifdef WITH_ROOT
200   return fPadRows.GetEntriesFast();
201 #endif
202 }  
203
204 //______________________________________________________________________________
205 AliMpPadRow* AliMpVRowSegmentSpecial::GetPadRow(Int_t i) const
206 {
207 // Returns number of pad rows.
208 // ---
209
210 #ifdef WITH_STL
211   return fPadRows[i];
212 #endif
213
214 #ifdef WITH_ROOT
215   return (AliMpPadRow*)fPadRows[i];
216 #endif
217 }  
218
219 //
220 // public methods  
221 //
222
223 //______________________________________________________________________________
224 void  AliMpVRowSegmentSpecial::AddPadRow(AliMpPadRow* padRow)
225 {
226 // Adds a pad row.
227 // ---
228
229   padRow->SetOffsetX(fOffsetX);
230   padRow->SetID(GetNofPadRows());
231
232 #ifdef WITH_STL
233   fPadRows.push_back(padRow);
234 #endif
235
236 #ifdef WITH_ROOT
237   fPadRows.Add(padRow);
238 #endif
239 }  
240
241 //______________________________________________________________________________
242 void AliMpVRowSegmentSpecial::UpdateMotifVector()
243 {
244 // Add motifs associated with the pad row segments in the specified
245 // pad row in the fMotifs vector.
246 // ---
247
248   for (Int_t i=0; i<GetNofPadRows(); i++) {
249     AliMpPadRow* padRow = GetPadRow(i);
250  
251     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) {
252       AliMpVMotif* motif = padRow->GetPadRowSegment(j)->GetMotif();            
253
254       if (!HasMotif(motif)) {
255 #ifdef WITH_STL
256         fMotifs.push_back(motif);        
257         fMotifPositionIds.push_back(
258           padRow->GetPadRowSegment(j)->GetMotifPositionId());
259 #endif
260 #ifdef WITH_ROOT
261         fMotifs.Add(motif);
262         
263         // resize array if needed
264         if (fNofMotifPositionIds<fgkMaxNofMotifPositionIds)
265           fMotifPositionIds.Set(fMotifPositionIds.GetSize()+
266                                 fgkMaxNofMotifPositionIds);      
267         fMotifPositionIds.AddAt(
268           padRow->GetPadRowSegment(j)->GetMotifPositionId(),
269           fNofMotifPositionIds++);
270 #endif
271       }
272     }  
273   }
274 }
275
276 //______________________________________________________________________________
277 Double_t  AliMpVRowSegmentSpecial::HalfSizeY() const
278 {
279 // Returns the size in y of this row segment.
280 // ---
281
282   Double_t halfSizeY = 0.;
283   for (Int_t i=0; i<GetNofPadRows(); i++) {
284     halfSizeY += GetPadRow(i)->HalfSizeY();
285   }  
286   
287   return halfSizeY;
288 }
289
290 //______________________________________________________________________________
291 AliMpVMotif*  AliMpVRowSegmentSpecial::FindMotif(const TVector2& position) const
292 {
293 // Returns the motif of this row; 
294 // ---
295
296   AliMpPadRow* padRow 
297     = FindPadRow(position.Y());
298   
299   if (!padRow) return 0;
300
301   AliMpVPadRowSegment* padRowSegment 
302     = padRow->FindPadRowSegment(position.X());
303     
304   if (!padRowSegment) return 0;
305
306   return padRowSegment->GetMotif();
307 }  
308
309 //______________________________________________________________________________
310 Int_t AliMpVRowSegmentSpecial::FindMotifPositionId(const TVector2& position) const
311 {
312 // Returns the motif position identified for the given
313 // geometric position.
314 // ---
315
316   AliMpPadRow* padRow 
317     = FindPadRow(position.Y());
318   
319   if (!padRow) return 0;
320
321   AliMpVPadRowSegment* padRowSegment 
322     = padRow->FindPadRowSegment(position.X());
323     
324   if (!padRowSegment) return 0;
325
326   return padRowSegment->GetMotifPositionId();
327 }
328
329 //______________________________________________________________________________
330 Bool_t AliMpVRowSegmentSpecial::HasMotifPosition(Int_t motifPositionId) const
331 {
332 // Returns true if the motif specified with the given position identifier
333 // is in this segment.
334 // ---
335
336   if (FindPadRowSegment(motifPositionId))
337     return true;
338   else  
339     return false;       
340 }
341
342 //______________________________________________________________________________
343 TVector2 AliMpVRowSegmentSpecial::MotifCenter(Int_t motifPositionId) const
344 {
345 // Returns the coordinates of the motif specified with
346 // the given position identifier.
347 // ---
348
349   // Try to get the motif position from the motif map first
350   AliMpMotifPosition* motifPosition
351     = GetRow()->GetMotifMap()->FindMotifPosition(motifPositionId);
352   if (motifPosition) return motifPosition->Position();
353
354   // Use slow method otherwise
355   return MotifCenterSlow(motifPositionId);
356 }
357
358 //______________________________________________________________________________
359 TVector2 AliMpVRowSegmentSpecial::Dimensions() const
360 {
361 // Returns the halflengths in x, y of the row segment rectangular envelope.
362 // ---
363
364   Double_t x = 0.;                  
365   Double_t y = 0.;  
366   for (Int_t i=0; i<GetNofPadRows(); i++) {    
367     AliMpPadRow* padRow = GetPadRow(i); 
368     
369     // Add all pad rows y halfsizes   
370     y += padRow->HalfSizeY();
371
372     // Find the biggest pad rows x halfsize
373     Double_t xx 
374       = (padRow->GetPadRowSegment(0)->RightBorderX() -
375          padRow->GetPadRowSegment(padRow->GetNofPadRowSegments()-1)->LeftBorderX())/2.;
376     if (xx > x) x = xx;            
377   }                  
378     
379   return TVector2(x, y);   
380 }
381
382 //______________________________________________________________________________
383 void AliMpVRowSegmentSpecial::SetGlobalIndices()
384 {
385 // Sets indices limits.
386 // ---
387
388   AliMpMotifPosition* firstPos = 0;
389   AliMpMotifPosition* lastPos = 0;
390         
391   for (Int_t i=0;i<GetNofMotifs();i++) {
392     AliMpMotifPosition* mPos
393       = GetRow()->GetMotifMap()
394         ->FindMotifPosition(GetMotifPositionId(i));
395         
396     if (!firstPos || 
397         mPos->GetLowIndicesLimit().GetFirst()
398         < firstPos->GetLowIndicesLimit().GetFirst())
399        firstPos = mPos;
400        
401     if (!lastPos || 
402         mPos->GetHighIndicesLimit().GetFirst()
403         >lastPos->GetHighIndicesLimit().GetFirst())
404        lastPos = mPos;
405   }
406
407   // Check if the motif positions has the limits set
408   if ( !firstPos->HasValidIndices() || !lastPos->HasValidIndices())
409     Fatal("SetGlobalIndices", "Indices of motif positions have to be set first.");
410
411   SetLowIndicesLimit(firstPos->GetLowIndicesLimit());
412   SetHighIndicesLimit(lastPos->GetHighIndicesLimit());
413 }  
414
415 //______________________________________________________________________________
416 AliMpRow*  AliMpVRowSegmentSpecial::GetRow() const
417 {
418 // Returns the row.which this row segment belongs to.
419 // ---
420
421   return fRow;
422 }  
423
424 //______________________________________________________________________________
425 Int_t  AliMpVRowSegmentSpecial::GetNofMotifs() const 
426
427 // Returns the number of different motifs present in this row segment.
428 // ---
429
430 #ifdef WITH_STL
431   return fMotifs.size();
432 #endif
433 #ifdef WITH_ROOT
434   return fMotifs.GetEntriesFast();
435 #endif
436 }  
437
438 //______________________________________________________________________________
439 AliMpVMotif* AliMpVRowSegmentSpecial::GetMotif(Int_t i) const  
440 {
441 // Returns the i-th motif present in this row segment.
442 // ---
443
444 #ifdef WITH_STL
445    return fMotifs[i]; 
446 #endif
447 #ifdef WITH_ROOT
448    return (AliMpVMotif*)fMotifs[i]; 
449 #endif
450 }
451
452 //______________________________________________________________________________
453 Int_t  AliMpVRowSegmentSpecial::GetMotifPositionId(Int_t i) const 
454
455 // Returns the i-th motif position Id present in this row segment.
456 // ---
457
458    return fMotifPositionIds[i]; 
459
460