]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpRowSegmentSpecial.cxx
new class AliMUONLoader
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpRowSegmentSpecial.cxx
1 // $Id$
2 // Category: sector
3 //
4 // Class AliMpRowSegmentSpecial
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
13 #include "AliMpRowSegmentSpecial.h"
14 #include "AliMpRow.h"
15 #include "AliMpPadRow.h"
16 #include "AliMpPadRowSegment.h"
17 #include "AliMpMotif.h"
18 #include "AliMpMotifType.h"
19 #include "AliMpMotifMap.h"
20 #include "AliMpMotifPosition.h"
21 #include "AliMpConstants.h"
22
23 ClassImp(AliMpRowSegmentSpecial)
24
25 //______________________________________________________________________________
26 AliMpRowSegmentSpecial::AliMpRowSegmentSpecial(AliMpRow* row, Double_t offsetX)
27   : AliMpVRowSegment(),
28     fOffsetX(offsetX),
29     fRow(row),
30     fPadRows(),
31     fMotifs(),
32     fMotifPositionIds()
33 {
34 // 
35 }
36
37 //______________________________________________________________________________
38 AliMpRowSegmentSpecial::AliMpRowSegmentSpecial() 
39   : AliMpVRowSegment(),
40     fOffsetX(0.),
41     fRow(0),
42     fPadRows(),
43     fMotifs(),
44     fMotifPositionIds()
45 {
46 //
47 }
48
49 //______________________________________________________________________________
50 AliMpRowSegmentSpecial::~AliMpRowSegmentSpecial() 
51 {
52 //  
53   for (Int_t i=0; i<GetNofPadRows(); i++)
54     delete fPadRows[i];
55 }
56
57 //
58 // private methods  
59 //
60
61 //______________________________________________________________________________
62 Int_t AliMpRowSegmentSpecial::GetNofPadRows() const
63 {
64 // Returns number of pad rows.
65 // ---
66
67   return fPadRows.size();
68 }  
69
70 //______________________________________________________________________________
71 AliMpPadRow* AliMpRowSegmentSpecial::GetPadRow(Int_t i) const
72 {
73 // Returns number of pad rows.
74 // ---
75
76   return fPadRows[i];
77 }  
78
79 //______________________________________________________________________________
80 Int_t  AliMpRowSegmentSpecial::MaxNofPadsInRow() const 
81
82 // Returns the maximum number of pads in this row segment along the X direction
83 // ---
84
85   Int_t maxNofPads = 0;    
86
87   for (Int_t i=0; i<GetNofPadRows(); i++){
88     Int_t nofPads = GetPadRow(i)->GetNofPads(); 
89
90     // Find maximum
91     if (nofPads > maxNofPads) maxNofPads = nofPads;
92   }
93     
94   return maxNofPads;
95 }
96
97 //______________________________________________________________________________
98 AliMpPadRow*  AliMpRowSegmentSpecial::FindPadRow(Double_t y) const
99 {
100 // Finds the pad row in the given y coordinate.
101 // ---
102
103   Double_t lowBorder =  fRow->LowBorderY();
104   Double_t highBorder = fRow->LowBorderY();
105   
106   for (Int_t i=0; i<GetNofPadRows(); i++) {    
107
108     AliMpPadRow* padRow = GetPadRow(i);
109     highBorder += 2.*padRow->HalfSizeY();
110
111     if ( y >= lowBorder &&  y <= highBorder)
112       return padRow;
113
114     lowBorder = highBorder;
115   }
116   
117   return 0;     
118 }
119
120 //______________________________________________________________________________
121 AliMpPadRowSegment*  
122 AliMpRowSegmentSpecial::FindPadRowSegment(Int_t motifPositionId) const
123 {
124 // Find the most down pad row segment with this motifPositionId.
125 // ---
126
127   for (Int_t i=0; i<GetNofPadRows(); i++) {
128     AliMpPadRow* padRow = GetPadRow(i);    
129
130     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) { 
131       AliMpPadRowSegment* padRowSegment = padRow->GetPadRowSegment(j);
132
133       if (padRowSegment->GetMotifPositionId() == motifPositionId) 
134         return padRowSegment;
135     }
136   }
137   return 0;     
138 }
139
140 //______________________________________________________________________________
141 AliMpPadRowSegment*  
142 AliMpRowSegmentSpecial::FindMostRightPadRowSegment(Int_t motifPositionId) const
143 {
144 // Find the most left pad row segment with this motifPositionId.
145 // ---
146
147   AliMpPadRowSegment* found = 0;
148
149   for (Int_t i=0; i<GetNofPadRows(); i++) {
150     AliMpPadRow* padRow = GetPadRow(i);    
151
152     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) { 
153       AliMpPadRowSegment* padRowSegment = padRow->GetPadRowSegment(j);
154
155       if ( padRowSegment->GetMotifPositionId() == motifPositionId &&
156            (!found || padRowSegment->RightBorderX() > found->RightBorderX()))
157            
158         found = padRowSegment;  
159     }
160   }
161
162   return found;         
163 }
164
165 //______________________________________________________________________________
166 AliMpIntPair 
167 AliMpRowSegmentSpecial::FindRelativeLowIndicesOf(Int_t motifPositionId) const 
168
169 // Returns the lowest pad indices where the motif of the given position ID
170 // exists in this segment.
171 // ---
172
173   AliMpIntPair ans(0,1000);
174   AliMpIntPair ans0 = ans;
175   Int_t maxNofPadsX=0;
176   
177   for (Int_t i=0; i<GetNofPadRows(); i++) {
178     AliMpPadRow* padRow = GetPadRow(i);
179
180     Int_t nofPadsX=0;
181     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) {
182       AliMpPadRowSegment* padRowSegment = padRow->GetPadRowSegment(j);
183       nofPadsX += padRowSegment->GetNofPads();
184       if (padRowSegment->GetMotifPositionId() == motifPositionId) {
185          if (ans.GetFirst() < nofPadsX) ans.SetFirst(nofPadsX);
186          if (ans.GetSecond()>i) ans.SetSecond(i);
187                   // ans.First = max (nof pads of this pos ID)
188                   // ans.Second = min of pad row number
189       }
190     }  
191     if (nofPadsX > maxNofPadsX) maxNofPadsX = nofPadsX;
192   }    
193   if (ans == ans0) return AliMpIntPair::Invalid();
194   
195   return AliMpIntPair(maxNofPadsX-ans.GetFirst(), ans.GetSecond());
196 }
197  
198 //______________________________________________________________________________
199 TVector2 AliMpRowSegmentSpecial::MotifCenterSlow(Int_t motifPositionId) const
200 {
201 // Returns the coordinates of the motif specified with
202 // the given position identifier.
203 // !! Applicable only for motifs that have their most down pad in
204 // this row segment.
205 // ---
206
207   // Find the first (left, down) pad row segment with this motifPositionId.
208   AliMpPadRowSegment* downPadRowSegment 
209     = FindPadRowSegment(motifPositionId);
210   AliMpPadRowSegment* rightPadRowSegment 
211     = FindMostRightPadRowSegment(motifPositionId);
212   
213   // Check if the motifPositionId is present 
214   if (!downPadRowSegment || !rightPadRowSegment) {
215     Error("MotifCenter", "Outside row segment region");
216     return 0;
217   }
218
219   // Check if both pad row segments have the same motif 
220   if (downPadRowSegment->GetMotif() != rightPadRowSegment->GetMotif()) {
221     Fatal("MotifCenter", "Outside row segment region");
222     return 0;
223   }
224
225   // Get position of found row segment
226   Double_t x = rightPadRowSegment->RightBorderX();       
227   Double_t y = fRow->LowBorderY()  ;   
228   
229   for (Int_t i=0; i<downPadRowSegment->GetPadRow()->GetID(); i++)
230     y += GetPadRow(i)->HalfSizeY()*2.;
231     
232   // Add motifs dimensions
233   x -= downPadRowSegment->GetMotif()->Dimensions().X();
234   y += downPadRowSegment->GetMotif()->Dimensions().Y();
235   
236   return TVector2(x, y);
237 }
238
239 //______________________________________________________________________________
240 Bool_t AliMpRowSegmentSpecial::HasMotif(const AliMpVMotif* motif) const
241 {
242 // Returns true if the specified motif is already in fMotifs vector,
243 // returns false otherwise.
244 // ---
245
246   for (UInt_t i=0; i<fMotifs.size(); i++)
247     if (fMotifs[i] == motif) return true;
248
249   return false;  
250 }
251
252 //
253 // public methods  
254 //
255
256 //______________________________________________________________________________
257 void  AliMpRowSegmentSpecial::AddPadRow(AliMpPadRow* padRow)
258 {
259 // Adds a pad row.
260 // ---
261
262   padRow->SetID(GetNofPadRows());
263   padRow->SetOffsetX(fOffsetX);
264
265   fPadRows.push_back(padRow);
266 }  
267
268 //______________________________________________________________________________
269 void AliMpRowSegmentSpecial::UpdateMotifVector()
270 {
271 // Add motifs associated with the pad row segments in the specified
272 // pad row in the fMotifs vector.
273 // ---
274
275   for (Int_t i=0; i<GetNofPadRows(); i++) {
276     AliMpPadRow* padRow = GetPadRow(i);
277  
278     for (Int_t j=0; j<padRow->GetNofPadRowSegments(); j++) {
279       AliMpVMotif* motif = padRow->GetPadRowSegment(j)->GetMotif();            
280
281       if (!HasMotif(motif)) {
282         fMotifs.push_back(motif);        
283         fMotifPositionIds.push_back(
284           padRow->GetPadRowSegment(j)->GetMotifPositionId());
285       }
286     }  
287   }
288 }
289
290 //______________________________________________________________________________
291 void AliMpRowSegmentSpecial::UpdatePadsOffset()
292 {
293 // Sets low indices limit to the pad offset calculated
294 // from the neighbour normal segment.
295 // ---
296
297   // Get the neighbour row segment
298   // (the first normal segment)
299   AliMpVRowSegment* neighbour = fRow->GetRowSegment(1);
300
301   // Get the the pads offset of the neighbour row segment
302   // (the first normal segment)
303   AliMpIntPair offset = neighbour->GetLowIndicesLimit();
304   
305   // Find max nof pads in a row
306   Int_t maxNofPads = MaxNofPadsInRow();
307
308   // Set limits
309   SetLowIndicesLimit(offset - AliMpIntPair(maxNofPads, 0));
310
311   // Reset limits in the neighbour row segment
312   // (pad offset is now included in the special segment)  
313   neighbour->SetLowIndicesLimit(
314     AliMpIntPair(0, neighbour->GetLowIndicesLimit().GetSecond()));
315 }
316
317 //______________________________________________________________________________
318 Double_t  AliMpRowSegmentSpecial::LeftBorderX() const
319 {
320 // Returns the x coordinate of the left row segment border
321 // in global coordinate system.
322 // ---
323
324   Double_t leftBorder = DBL_MAX;
325   for (Int_t i=0; i<GetNofPadRows(); i++) {
326     AliMpPadRow* padRow = GetPadRow(i);
327     Double_t border 
328       = padRow->GetPadRowSegment(padRow->GetNofPadRowSegments()-1)->LeftBorderX();
329       
330     if (border < leftBorder) leftBorder =  border;
331   }  
332   
333   return leftBorder;
334 }
335
336 //______________________________________________________________________________
337 Double_t  AliMpRowSegmentSpecial::RightBorderX() const
338 {
339 // Returns the x coordinate of the right row segment border
340 // in global coordinate system.
341 // ---
342
343   Double_t sameBorder = fOffsetX;
344
345   // Consistence check  
346   Double_t rightBorder = -DBL_MAX;
347   for (Int_t i=0; i<GetNofPadRows(); i++) {
348     AliMpPadRow* padRow = GetPadRow(i);
349     Double_t border = padRow->GetPadRowSegment(0)->RightBorderX();
350     if (border > rightBorder) rightBorder =  border;
351   }  
352
353   if (TMath::Abs(fOffsetX - rightBorder) > 1.e-04)  {
354     Error("RightBorderX", "WrongBorder");
355     return sameBorder;
356   }  
357   
358   return rightBorder;
359 }
360
361 //______________________________________________________________________________
362 Double_t  AliMpRowSegmentSpecial::HalfSizeY() const
363 {
364 // Returns the size in y of this row segment.
365 // ---
366
367   Double_t halfSizeY = 0.;
368   for (Int_t i=0; i<GetNofPadRows(); i++) {
369     halfSizeY += GetPadRow(i)->HalfSizeY();
370   }  
371   
372   return halfSizeY;
373 }
374
375 //______________________________________________________________________________
376 AliMpVMotif*  AliMpRowSegmentSpecial::FindMotif(const TVector2& position) const
377 {
378 // Returns the motif of this row; 
379 // ---
380
381   AliMpPadRow* padRow 
382     = FindPadRow(position.Y());
383   
384   if (!padRow) return 0;
385
386   AliMpPadRowSegment* padRowSegment 
387     = padRow->FindPadRowSegment(position.X());
388     
389   if (!padRowSegment) return 0;
390
391   return padRowSegment->GetMotif();
392 }  
393
394 //______________________________________________________________________________
395 Int_t AliMpRowSegmentSpecial::FindMotifPositionId(const TVector2& position) const
396 {
397 // Returns the motif position identified for the given
398 // geometric position.
399 // ---
400
401   AliMpPadRow* padRow 
402     = FindPadRow(position.Y());
403   
404   if (!padRow) return 0;
405
406   AliMpPadRowSegment* padRowSegment 
407     = padRow->FindPadRowSegment(position.X());
408     
409   if (!padRowSegment) return 0;
410
411   return padRowSegment->GetMotifPositionId();
412 }
413
414 //______________________________________________________________________________
415 Bool_t AliMpRowSegmentSpecial::HasMotifPosition(Int_t motifPositionId) const
416 {
417 // Returns true if the motif specified with the given position identifier
418 // is in this segment.
419 // ---
420
421   if (FindPadRowSegment(motifPositionId))
422     return true;
423   else  
424     return false;       
425 }
426
427 //______________________________________________________________________________
428 TVector2 AliMpRowSegmentSpecial::MotifCenter(Int_t motifPositionId) const
429 {
430 // Returns the coordinates of the motif specified with
431 // the given position identifier.
432 // ---
433
434   // Try to get the motif position from the motif map first
435   AliMpMotifPosition* motifPosition
436     = GetRow()->GetMotifMap()->FindMotifPosition(motifPositionId);
437   if (motifPosition) return motifPosition->Position();
438
439   // Use slow method otherwise
440   return MotifCenterSlow(motifPositionId);
441 }
442
443 //______________________________________________________________________________
444 TVector2 AliMpRowSegmentSpecial::Position() const
445 {
446 // Returns the position of the row segment centre.
447 // The centre is defined as the centre of the rectangular
448 // row segment envelope.
449 // ---
450
451   Double_t x = fOffsetX - Dimensions().X();                 
452   Double_t y = fRow->Position().Y();  
453     
454   return TVector2(x, y);   
455 }
456
457
458 //______________________________________________________________________________
459 TVector2 AliMpRowSegmentSpecial::Dimensions() const
460 {
461 // Returns the halflengths in x, y of the row segment rectangular envelope.
462 // ---
463
464   Double_t x = 0.;                  
465   Double_t y = 0.;  
466   for (Int_t i=0; i<GetNofPadRows(); i++) {    
467     AliMpPadRow* padRow = GetPadRow(i); 
468     
469     // Add all pad rows y halfsizes   
470     y += padRow->HalfSizeY();
471
472     // Find the biggest pad rows x halfsize
473     Double_t xx 
474       = (padRow->GetPadRowSegment(0)->RightBorderX() -
475          padRow->GetPadRowSegment(padRow->GetNofPadRowSegments()-1)->LeftBorderX())/2.;
476     if (xx > x) x = xx;            
477   }                  
478     
479   return TVector2(x, y);   
480 }
481
482 //______________________________________________________________________________
483 void AliMpRowSegmentSpecial::SetGlobalIndices()
484 {
485 // Sets indices limits.
486 // ---
487
488   AliMpMotifPosition* firstPos = 0;
489   AliMpMotifPosition* lastPos = 0;
490         
491   for (Int_t i=0;i<GetNofMotifs();i++) {
492     AliMpMotifPosition* mPos
493       = GetRow()->GetMotifMap()
494         ->FindMotifPosition(GetMotifPositionId(i));
495         
496     if (!firstPos || 
497         mPos->GetLowIndicesLimit().GetFirst()
498         < firstPos->GetLowIndicesLimit().GetFirst())
499        firstPos = mPos;
500        
501     if (!lastPos || 
502         mPos->GetHighIndicesLimit().GetFirst()
503         >lastPos->GetHighIndicesLimit().GetFirst())
504        lastPos = mPos;
505   }
506
507   // Check if the motif positions has the limits set
508   if ( !firstPos->HasValidIndices() || !lastPos->HasValidIndices())
509     Fatal("SetGlobalIndices", "Indices of motif positions have to be set first.");
510
511   SetLowIndicesLimit(firstPos->GetLowIndicesLimit());
512   SetHighIndicesLimit(lastPos->GetHighIndicesLimit());
513 }  
514
515 //______________________________________________________________________________
516 Int_t AliMpRowSegmentSpecial::SetIndicesToMotifPosition(
517                                           Int_t i, AliMpIntPair indices)
518 {
519 // Sets global indices to i-th motif position and returns next index in x.
520 // ---
521
522   // Get motif position
523   AliMpMotifPosition* motifPosition
524     = GetRow()->GetMotifMap()->FindMotifPosition(GetMotifPositionId(i));
525
526   // Low limit
527   AliMpIntPair low 
528     = AliMpIntPair(GetLowIndicesLimit().GetFirst() + AliMpConstants::StartPadIndex(), 
529                indices.GetSecond())
530       + FindRelativeLowIndicesOf(GetMotifPositionId(i));
531             
532   if (! motifPosition->GetHighIndicesLimit().IsValid()) {   
533      motifPosition->SetLowIndicesLimit(low);
534   } 
535   else {
536     if (motifPosition->GetLowIndicesLimit().GetFirst() > low.GetFirst())
537       motifPosition->SetLowIndicesLimit(
538                         AliMpIntPair(low.GetFirst(),
539                                  motifPosition->GetLowIndicesLimit().GetSecond()));
540
541     if (motifPosition->GetLowIndicesLimit().GetSecond() > low.GetSecond())
542        motifPosition->SetLowIndicesLimit(
543                          AliMpIntPair(motifPosition->GetLowIndicesLimit().GetFirst(),
544                                   low.GetSecond()));
545   }
546              
547   // High limit      
548   AliMpMotifType* motifType = motifPosition->GetMotif()->GetMotifType();  
549   AliMpIntPair high 
550     = motifPosition->GetLowIndicesLimit()
551       + AliMpIntPair(motifType->GetNofPadsX()-1, motifType->GetNofPadsY()-1);            
552   motifPosition->SetHighIndicesLimit(high);
553   
554   // Increment index only if last motif position is processed 
555   if (i != GetNofMotifs()-1) 
556     return indices.GetFirst();
557     //return 0;
558   else
559     return indices.GetFirst() + MaxNofPadsInRow();  
560     //return MaxNofPadsInRow();  
561 }
562
563 //______________________________________________________________________________
564 AliMpRow*  AliMpRowSegmentSpecial::GetRow() const
565 {
566 // Returns the row.which this row segment belongs to.
567 // ---
568
569   return fRow;
570 }  
571
572 //______________________________________________________________________________
573 Int_t  AliMpRowSegmentSpecial::GetNofMotifs() const 
574
575 // Returns the number of different motifs present in this row segment.
576 // ---
577
578   return fMotifs.size();
579 }  
580
581 //______________________________________________________________________________
582 AliMpVMotif* AliMpRowSegmentSpecial::GetMotif(Int_t i) const  
583 {
584 // Returns the i-th motif present in this row segment.
585 // ---
586
587    return fMotifs[i]; 
588 }
589
590 //______________________________________________________________________________
591 Int_t  AliMpRowSegmentSpecial::GetMotifPositionId(Int_t i) const 
592
593 // Returns the i-th motif position Id present in this row segment.
594 // ---
595
596    return fMotifPositionIds[i]; 
597