Replacement of AliMpIntPair object with algoritmic
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpRowSegment.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: AliMpRowSegment.cxx,v 1.10 2006/05/24 13:58:46 ivana Exp $
18 // Category: sector
19
20 //-----------------------------------------------------------------------------
21 // Class AliMpRowSegment
22 // ---------------------
23 // Class describing a row segment composed of the 
24 // the identic motifs.
25 // Included in AliRoot: 2003/05/02
26 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
27 //-----------------------------------------------------------------------------
28
29 #include "AliMpRowSegment.h"
30 #include "AliMpRow.h"
31 #include "AliMpVMotif.h"
32 #include "AliMpMotifType.h"
33 #include "AliMpMotifTypePadIterator.h"
34 #include "AliMpMotifMap.h"
35 #include "AliMpMotifPosition.h"
36 #include "AliMpConstants.h"
37 #include "AliMpEncodePair.h"
38
39 #include "AliLog.h"
40
41 #include <TMath.h>
42 #include <Riostream.h>
43
44 /// \cond CLASSIMP
45 ClassImp(AliMpRowSegment)
46 /// \endcond
47
48 //_____________________________________________________________________________
49 AliMpRowSegment::AliMpRowSegment(AliMpRow* row, AliMpVMotif* motif, 
50                                  Int_t padOffsetX, Int_t padOffsetY,
51                                  Int_t nofMotifs,
52                                  Int_t motifPositionId, Int_t motifPositionDId)
53   : AliMpVRowSegment(),
54     fNofMotifs(nofMotifs),
55     fLPadOffset(AliMp::Pair(padOffsetX,padOffsetY)),
56     fOffset(TVector2()),
57     fRow(row),
58     fMotif(motif),
59     fMotifPositionId(motifPositionId),
60     fMotifPositionDId(motifPositionDId)
61 {
62 /// Standard constructor
63  
64   // Keep pad offset in the low indices limits
65   SetLowIndicesLimit(fLPadOffset);
66 }
67
68 //_____________________________________________________________________________
69 AliMpRowSegment::AliMpRowSegment() 
70   : AliMpVRowSegment(),
71     fNofMotifs(0),
72     fLPadOffset(0),
73     fOffset(TVector2()),
74     fRow(0),
75     fMotif(0),
76     fMotifPositionId(0),
77     fMotifPositionDId(0)
78 {
79 /// Default constructor
80 }
81
82 //_____________________________________________________________________________
83 AliMpRowSegment::~AliMpRowSegment() 
84 {
85 /// Destructor  
86 }
87
88 //\13
89 // private methods  
90 //
91
92 //_____________________________________________________________________________
93 Double_t AliMpRowSegment::FirstMotifCenterX() const
94 {
95 /// Return the x coordinate of the first motif center
96 /// in the global coordinate system.
97
98   return fOffset.X();
99 }  
100
101 //_____________________________________________________________________________
102 Double_t AliMpRowSegment::LastMotifCenterX() const
103 {
104 /// Return the x coordinate of the last motif center
105 /// in the global coordinate system.
106
107   return fOffset.X() + 2.*(fNofMotifs-1)*fMotif->Dimensions().X();
108 }
109
110 //_____________________________________________________________________________
111 Double_t AliMpRowSegment::MotifCenterX(Int_t motifPositionId) const
112 {
113 /// Return the x coordinate of the motif specified with
114 /// the given position identifier.
115
116   // Check if x is in the row segment range
117   if (! HasMotifPosition(motifPositionId)) {
118     AliErrorStream() << "Outside row segment region" << endl;
119     return 0;
120   }
121   
122   // Find the position number in the segment  
123   Int_t num = (motifPositionId - fMotifPositionId) *  fMotifPositionDId;
124
125   return fOffset.X() + num*(fMotif->Dimensions().X() * 2.0);
126 }
127
128 //_____________________________________________________________________________
129 Double_t AliMpRowSegment::MotifCenterY(Int_t motifPositionId) const
130 {
131 /// Return the y coordinate of the motif specified with
132 /// the given position identifier.
133
134   // Check if x is in the row segment range
135   if (! HasMotifPosition(motifPositionId)) {
136     AliErrorStream() << "Outside row segment region" << endl;
137     return 0;
138   }
139   
140   return GetRow()->Position().Y() + fOffset.Y();
141 }
142
143 //_____________________________________________________________________________
144 Bool_t AliMpRowSegment::IsInside(const TVector2& position, Bool_t warn) const
145 {
146 /// Check if the position is inside some motif of this row segment.
147
148   Double_t minY = GetRow()->Position().Y() + fOffset.Y() - fMotif->Dimensions().Y();
149   Double_t maxY = GetRow()->Position().Y() + fOffset.Y() + fMotif->Dimensions().Y();
150
151   if ( position.X() < LeftBorderX() || position.X() > RightBorderX() ||
152        position.Y() < minY || position.Y() > maxY ) {
153
154     if (warn)
155       AliWarningStream() << "Outside row segment region" << endl;
156     return false;
157   }
158   else
159     return true;
160 }    
161
162 //
163 // public methods  
164 //
165
166 //_____________________________________________________________________________
167 Double_t  AliMpRowSegment::LeftBorderX() const
168 {
169 /// Return the x coordinate of the left row segment border
170 /// in the global coordinate system.
171
172   return FirstMotifCenterX() - fMotif->Dimensions().X();
173 }
174
175 //_____________________________________________________________________________
176 Double_t  AliMpRowSegment::RightBorderX() const
177 {
178 /// Return the x coordinate of the right row segment border
179 /// in the global coordinate system.
180
181   return LastMotifCenterX() + fMotif->Dimensions().X();
182 }
183
184 //_____________________________________________________________________________
185 Double_t  AliMpRowSegment::HalfSizeY() const
186 {
187 /// Return the size in y of this row segment.
188
189   return fMotif->Dimensions().Y() + fOffset.Y();
190 }
191
192 //_____________________________________________________________________________
193 AliMpVMotif*  AliMpRowSegment::FindMotif(const TVector2& position) const
194 {
195 /// Return the motif of this row; 
196
197   if (IsInside(position, false))
198     return fMotif;
199   else  
200     return 0;
201 }  
202
203 //_____________________________________________________________________________
204 Int_t AliMpRowSegment::FindMotifPositionId(const TVector2& position) const
205 {
206 /// Return the motif position identified for the given
207 /// geometric position.
208
209   if (!IsInside(position, false)) return 0;
210
211   // Find the position number in the segment  
212   Int_t num 
213     = Int_t((position.X() - LeftBorderX()) / (fMotif->Dimensions().X() * 2.0));
214
215   // Calculate the position Id
216   return fMotifPositionId + num*fMotifPositionDId;  
217 }
218
219 //_____________________________________________________________________________
220 Bool_t AliMpRowSegment::HasMotifPosition(Int_t motifPositionId) const
221 {
222 /// Return true if the motif specified with the given position identifier
223 /// is in this segment.
224
225   Int_t minId = TMath::Min(fMotifPositionId, 
226                     fMotifPositionId + (fNofMotifs-1)*fMotifPositionDId);
227   Int_t maxId = TMath::Max(fMotifPositionId, 
228                     fMotifPositionId + (fNofMotifs-1)*fMotifPositionDId);
229
230   if (motifPositionId >= minId && motifPositionId <= maxId) {
231     return true;
232   }
233   else 
234     return false;
235 }
236
237 //_____________________________________________________________________________
238 TVector2 AliMpRowSegment::MotifCenter(Int_t motifPositionId) const
239 {
240 /// Return the coordinates of the motif specified with
241 /// the given position identifier.
242
243   return TVector2(MotifCenterX(motifPositionId), MotifCenterY(motifPositionId));
244 }
245
246 //_____________________________________________________________________________
247 TVector2 AliMpRowSegment::Position() const
248 {
249 /// Return the position of the row segment centre.
250
251   Double_t x = (LeftBorderX() + RightBorderX())/2.;                 
252   Double_t y = GetRow()->Position().Y();  
253     
254   return TVector2(x, y);   
255 }
256
257
258 //_____________________________________________________________________________
259 TVector2 AliMpRowSegment::Dimensions() const
260 {
261 /// Return the halflengths of the row segment in x, y.
262 // ---
263
264   Double_t x = (RightBorderX() - LeftBorderX())/2.;                 
265   Double_t y = GetRow()->Dimensions().Y();  
266     
267   return TVector2(x, y);   
268 }
269
270 //_____________________________________________________________________________
271 void   AliMpRowSegment::SetOffset(const TVector2& offset)
272 {
273 /// Calculate offset from given offset and 
274 /// stored offset in pads.
275
276   AliMpMotifTypePadIterator iter(fMotif->GetMotifType());
277   iter.First();
278
279   Int_t ix = iter.CurrentItem().GetIx();
280   Int_t iy = iter.CurrentItem().GetIy();
281      
282   Double_t offsetX 
283      = offset.X() 
284        + 2.*AliMp::PairFirst(fLPadOffset) * fMotif->GetPadDimensionsByIndices(ix, iy).X() 
285        + fMotif->Dimensions().X(); 
286
287   Double_t offsetY 
288     = offset.Y()
289       + AliMp::PairSecond(fLPadOffset) * fMotif->GetPadDimensionsByIndices(ix, iy).Y(); 
290
291   fOffset = TVector2(offsetX, offsetY);
292 }
293
294 //_____________________________________________________________________________
295 void AliMpRowSegment::SetGlobalIndices(AliMpRow* /*rowBefore*/)
296 {
297 /// Set global indices limits.
298
299   // The low/high indices limits has to be taken as the highest/lowest from all 
300   // motif positions
301   Int_t ixl = 9999;
302   Int_t iyl = 9999;
303   Int_t ixh = AliMpConstants::StartPadIndex();
304   Int_t iyh = AliMpConstants::StartPadIndex();
305
306   for (Int_t i=0; i<GetNofMotifs(); i++) {
307      
308      AliMpMotifPosition* mPos 
309        = GetRow()->GetMotifMap()->FindMotifPosition(GetMotifPositionId(i));
310        
311      // Check if the motif positions has the limits set
312      if ( !mPos->HasValidIndices() )
313        Fatal("SetGlobalIndices", 
314              "Indices of motif positions have to be set first.");
315             
316      if ( mPos->GetLowLimitIx() < ixl ) 
317        ixl = mPos->GetLowLimitIx();
318        
319      if ( mPos->GetLowLimitIy() < iyl ) 
320        iyl = mPos->GetLowLimitIy();
321
322      if ( mPos->GetHighLimitIx() > ixh ) 
323        ixh = mPos->GetHighLimitIx();
324        
325      if ( mPos->GetHighLimitIy() > iyh ) 
326        iyh = mPos->GetHighLimitIy();
327   }     
328
329   SetLowIndicesLimit(ixl, iyl);
330   SetHighIndicesLimit(ixh, iyh);
331 }  
332
333 //_____________________________________________________________________________
334 Int_t AliMpRowSegment::SetIndicesToMotifPosition(Int_t i, MpPair_t indices)
335 {
336 /// Set global indices to i-th motif position and returns next index
337 /// in x.
338
339   // Get motif position
340   AliMpMotifPosition* motifPosition
341     = GetRow()->GetMotifMap()->FindMotifPosition(GetMotifPositionId(i));
342
343   // Low limit
344   MpPair_t low = indices + AliMp::Pair(0, GetLowLimitIy());
345   motifPosition->SetLowIndicesLimit(low);
346           
347   // High limit
348   AliMpMotifType* motifType = motifPosition->GetMotif()->GetMotifType();    
349   MpPair_t high
350     = motifPosition->GetLowIndicesLimit()
351       + AliMp::Pair(motifType->GetNofPadsX()-1, motifType->GetNofPadsY()-1);
352   motifPosition->SetHighIndicesLimit(high);
353
354   // Return next index in x
355   return AliMp::PairFirst(high)+1;
356   // return motifType->GetNofPadsX();
357 }
358
359
360 //_____________________________________________________________________________
361 AliMpRow*  AliMpRowSegment::GetRow() const
362 {
363 /// Return the row.which this row segment belongs to.
364
365   return fRow;
366 }  
367
368 //_____________________________________________________________________________
369 Int_t  AliMpRowSegment::GetNofMotifs() const
370 {
371 /// Return number of motifs in this this row segment.
372
373   return fNofMotifs;
374 }  
375
376 //_____________________________________________________________________________
377 Int_t  AliMpRowSegment::GetMotifPositionId(Int_t i) const
378 {
379 /// Return number of motifs in this this row segment.
380
381   return fMotifPositionId + i*fMotifPositionDId;
382 }  
383
384 //_____________________________________________________________________________
385 AliMpVMotif*  AliMpRowSegment::GetMotif(Int_t /*i*/) const
386 {
387 /// Return the motif of this row segment.
388
389   return fMotif;
390 }