Replacement of AliMpIntPair object with algoritmic
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpFastSegmentation.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
18 /// \class AliMpFastSegmentation
19 /// An implementation of AliMpVSegmentation, which uses
20 /// some internal maps to speed up the (Has)PadByIndices and PadByLocation
21 /// methods.
22 /// 
23 /// L. Aphecetche, Subatech
24 ///
25
26 #include "AliMpFastSegmentation.h"
27
28 #include "AliCodeTimer.h"
29 #include "AliLog.h"
30 #include "AliMpConnection.h"
31 #include "AliMpConstants.h"
32 #include "AliMpMotifMap.h"
33 #include "AliMpMotifPosition.h"
34 #include "AliMpMotifType.h"
35 #include "AliMpPad.h"
36 #include "AliMpSector.h"
37 #include "AliMpSlat.h"
38 #include "AliMpVPadIterator.h"
39 #include "AliMpEncodePair.h"
40
41 #include <TArrayI.h>
42
43 /// \cond CLASSIMP
44 ClassImp(AliMpFastSegmentation)
45 /// \endcond
46
47 //#define CHECK
48
49 #ifdef CHECK
50 #include <cassert>
51 #endif
52
53 namespace
54 {
55   ///
56   /// The values in Encode and Encode2 are not exactly random.
57   /// They are the result of a few "try and see" efforts to optimize the
58   /// timing of the TExMap::GetValue (you should note that the TExMap implementation
59   /// speed depends on the "non-uniformity" of the keys).
60   ///
61   /// So don't change those values w/o at least testing a bit the implications...
62   /// But feel free to experiment though, in order to optimizer further ;-)
63   ///
64   Int_t Encode(Int_t a, Int_t b)
65   {
66     return a*1009 + b;
67   }
68
69   Int_t Encode2(Int_t a)
70   {
71     /// Ideally this method should be different for sectors and slats, as we have
72     /// much less manus per DE for slats, and hence the "non-uniformity" is less...
73     return ( a ^ (1<<10) ) << 16 ;
74   }
75 }
76
77 //_____________________________________________________________________________
78 AliMpFastSegmentation::AliMpFastSegmentation(AliMpVSegmentation* vseg)
79 : AliMpVSegmentation(),
80 fHelper(vseg),
81 fMotifPositions(),
82 fIxIy(),
83 fManuId(),
84 fPosition()
85 {
86   /// Ctor. We adopt vseg.
87   
88   AliCodeTimerAuto(vseg->ClassName());
89   
90   if (!vseg) 
91   {
92     AliError("Will get a hard time working with a NULL vseg !");
93     return;
94   }
95   
96   fPosition = vseg->Position();
97   
98   TArrayI manus;
99   
100   vseg->GetAllElectronicCardIDs(manus);
101   
102   for ( Int_t i = 0; i < manus.GetSize(); ++i ) 
103   {
104     Int_t manuId = manus[i];
105     
106     AliMpMotifPosition* mp = vseg->MotifPosition(manuId);
107     
108     // Should never happen
109     if ( ! mp ) {
110       AliFatal("AliMpMotifPosition not found.");
111     }  
112     
113     Int_t index = 1 + fMotifPositions.GetLast();
114
115     fMotifPositions.AddLast(mp);
116
117     fManuId.Add(Encode2(manuId),1+index);
118
119     for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
120     {
121       if ( vseg->HasPadByLocation(manuId,manuChannel) )
122       {
123         AliMpPad pad = vseg->PadByLocation(manuId,manuChannel);
124         
125         fIxIy.Add(Encode(pad.GetIx(),pad.GetIy()),1+index);
126       }
127     }
128   }
129 }
130
131 //_____________________________________________________________________________
132 AliMpFastSegmentation::~AliMpFastSegmentation()
133 {
134   /// dtor
135   delete fHelper;
136 }
137
138 //_____________________________________________________________________________
139 AliMpVPadIterator* 
140 AliMpFastSegmentation::CreateIterator(const AliMpArea& area) const
141 {
142   /// Forward to our helper
143   return fHelper->CreateIterator(area);
144 }
145
146 //_____________________________________________________________________________
147 AliMpVPadIterator* 
148 AliMpFastSegmentation::CreateIterator() const
149 {
150   /// Forward to our helper
151   return fHelper->CreateIterator();
152 }
153
154 //_____________________________________________________________________________
155 Int_t 
156 AliMpFastSegmentation::GetNeighbours(const AliMpPad& pad, TObjArray& neighbours,
157                                      Bool_t includeSelf,
158                                      Bool_t includeVoid) const
159 {
160   /// Use default implementation
161   return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
162 }
163
164 //_____________________________________________________________________________
165 AliMpPad 
166 AliMpFastSegmentation::PadByLocation(Int_t manuId, Int_t manuChannel, 
167                                      Bool_t warning) const
168 {
169   /// Get the pad by location, using the manuid map.
170   
171   Int_t index = fManuId.GetValue(Encode2(manuId));
172   
173   if (!index) 
174   {
175     if (warning)
176     {
177       AliWarning(Form("Manu ID %d not found",manuId));
178       Print();
179     }
180     return AliMpPad::Invalid();
181   }
182   
183   AliMpMotifPosition* motifPos = InternalMotifPosition(index);
184   
185   if (!motifPos)
186   {
187     AliError(Form("InternalMotifPosition(%d) failed",index));
188     Print();
189     return AliMpPad::Invalid();
190   }
191   
192   AliMpVMotif* motif = motifPos->GetMotif();
193   MpPair_t localIndices 
194     =  motif->GetMotifType()->FindLocalIndicesByGassiNum(manuChannel);
195         
196   if ( localIndices < 0 ) 
197   {
198     if (warning) 
199     {
200       AliWarning(Form("The pad number %d doesn't exists", manuChannel));
201       Print();
202     }
203     return AliMpPad::Invalid();
204   }
205         
206 #ifdef CHECK
207   AliMpPad pad1 = AliMpPad(manuId, manuChannel,
208                            motifPos->GlobalIndices(localIndices),
209                            motifPos->Position() 
210                            + motif->PadPositionLocal(localIndices) 
211                            - fPosition,
212                            motif->GetPadDimensionsByIndices(localIndices));  
213   AliMpPad pad2 = fHelper->PadByLocation(manuId, manuChannel,warning);
214   if ( pad1 != pad2 ) 
215   {
216     Print();
217     pad1.Print();
218     pad2.Print();
219     assert(pad1==pad2);
220   }
221 #endif
222   
223   return AliMpPad(manuId, manuChannel,
224                   motifPos->GlobalIndices(localIndices),
225                   motifPos->Position() 
226                   + motif->PadPositionLocal(localIndices) 
227                   - fPosition,
228                   motif->GetPadDimensionsByIndices(localIndices));  
229 }
230
231 //_____________________________________________________________________________
232 AliMpMotifPosition*
233 AliMpFastSegmentation::InternalMotifPosition(Int_t index) const
234 {
235   /// Get the internal manu from the index
236   return static_cast<AliMpMotifPosition*>(fMotifPositions.UncheckedAt(index-1));
237 }
238
239 //_____________________________________________________________________________
240 AliMpPad 
241 AliMpFastSegmentation::PadByIndices (Int_t ix, Int_t iy, Bool_t warning) const
242 {
243   /// Get pad by indices
244   
245   Int_t index = fIxIy.GetValue(Encode(ix, iy));
246   
247   if ( !index )
248   {
249     if (warning)
250     {
251       AliWarning(Form("ManuID not found for pad indices (%d,%d)", ix, iy));       
252       Print();
253     }
254     return AliMpPad::Invalid();
255   }
256   
257   AliMpMotifPosition* motifPos = InternalMotifPosition(index);
258
259   if (!motifPos)
260         {
261     AliError(Form("InternalMotifPosition(%d) failed",index));
262     Print();
263                 return AliMpPad::Invalid();
264         }
265         
266   AliMpVMotif* motif = motifPos->GetMotif();
267   AliMpMotifType* motifType = motif->GetMotifType();
268   MpPair_t localIndices(AliMp::Pair(ix, iy) - motifPos->GetLowIndicesLimit());
269   AliMpConnection* connection = motifType->FindConnectionByLocalIndices(localIndices);
270   
271   if (!connection)
272   {
273     if ( warning )
274     {
275       AliWarning(Form("No connection for pad indices (%d,%d)", ix, iy));
276     }
277     return AliMpPad::Invalid();
278   }
279         
280 #ifdef CHECK
281   AliMpPad pad2 = fHelper->PadByIndices(ix, iy, warning);
282   AliMpPad pad1 = AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
283                           ix, iy,
284                           motifPos->Position()
285                           + motif->PadPositionLocal(localIndices)
286                           - fPosition,
287                           motif->GetPadDimensionsByIndices(localIndices));
288   
289   
290   
291   assert(pad1==pad2);
292 #endif
293   
294   return AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
295                   ix, iy,
296                   motifPos->Position()
297                   + motif->PadPositionLocal(localIndices)
298                   - fPosition,
299                   motif->GetPadDimensionsByIndices(localIndices));
300   
301 }
302
303 //_____________________________________________________________________________
304 AliMpPad 
305 AliMpFastSegmentation::PadByPosition(const TVector2& position, Bool_t warning ) const
306 {
307   /// Forward to our helper
308   return fHelper->PadByPosition(position,warning);
309 }
310
311 //_____________________________________________________________________________
312 Int_t 
313 AliMpFastSegmentation::MaxPadIndexX() const
314 {
315   /// Forward to our helper
316   return fHelper->MaxPadIndexX();
317 }
318
319 //_____________________________________________________________________________
320 Int_t  
321 AliMpFastSegmentation::MaxPadIndexY() const
322 {
323   /// Forward to our helper
324   return fHelper->MaxPadIndexY();
325 }
326
327 //_____________________________________________________________________________
328 Int_t  
329 AliMpFastSegmentation::NofPads() const
330 {
331   /// Forward to our helper
332   return fHelper->NofPads();
333 }
334
335 //_____________________________________________________________________________
336 Int_t
337 AliMpFastSegmentation::GetNofElectronicCards() const
338 {
339   /// Forward to our helper
340   return fHelper->GetNofElectronicCards();
341 }
342
343 //_____________________________________________________________________________
344 void
345 AliMpFastSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
346 {
347   /// Forward to our helper
348   fHelper->GetAllElectronicCardIDs(ecn);
349 }
350
351 //_____________________________________________________________________________
352 Bool_t 
353 AliMpFastSegmentation::HasPadByIndices(Int_t ix, Int_t iy) const
354 {
355   /// Whether there is a pad at the given indices
356   Int_t index = fIxIy.GetValue(Encode(ix, iy));
357   
358   if ( !index ) return kFALSE;
359   
360   AliMpMotifPosition* mp = InternalMotifPosition(index);
361   
362   Bool_t r1 = mp->HasPadByIndices(AliMp::Pair(ix, iy));
363 #ifdef CHECK
364   Bool_t r2 = fHelper->HasPadByIndices(ix, iy);
365   
366   assert(r1==r2);
367 #endif
368   return r1;
369 }
370
371 //_____________________________________________________________________________
372 Bool_t 
373 AliMpFastSegmentation::HasPadByLocation(Int_t manuId, Int_t manuChannel) const
374 {
375   /// Whether there is a pad at the given location (de,manuid)
376   
377   Int_t index = fManuId.GetValue(Encode2(manuId));
378   
379   if (!index) return kFALSE;
380   
381   AliMpMotifPosition* mp = InternalMotifPosition(index);
382   
383   Bool_t r1 = mp->HasPadByManuChannel(manuChannel);
384 #ifdef CHECK
385   Bool_t r2 = fHelper->HasPadByLocation(manuId, manuChannel);
386   
387   assert(r1==r2);
388 #endif
389   return r1;
390 }
391
392 //_____________________________________________________________________________
393 void
394 AliMpFastSegmentation::Print(Option_t* opt) const
395 {
396   /// Forward to our helper
397   fHelper->Print(opt);
398 }
399
400 //_____________________________________________________________________________
401 AliMp::PlaneType
402 AliMpFastSegmentation::PlaneType() const
403 {
404   /// Forward to our helper
405   return fHelper->PlaneType();
406 }
407
408 //_____________________________________________________________________________
409 TVector2 
410 AliMpFastSegmentation::Dimensions() const
411 {
412   /// Forward to our helper
413   return fHelper->Dimensions();
414 }
415
416 //_____________________________________________________________________________
417 TVector2 
418 AliMpFastSegmentation::Position() const
419 {
420   /// Forward to our helper
421   return fHelper->Position();
422 }
423
424 //_____________________________________________________________________________
425 Bool_t
426 AliMpFastSegmentation::HasMotifPosition(Int_t manuId) const
427 {
428   /// Whether or not we have a given manu
429   return ( fManuId.GetValue(Encode2(manuId)) != 0);
430 }
431
432 //_____________________________________________________________________________
433 AliMpMotifPosition*
434 AliMpFastSegmentation::MotifPosition(Int_t manuId) const
435 {
436   /// Get the motifPosition object of a given manu
437   Int_t index = fManuId.GetValue(Encode2(manuId));
438
439   if (!index) 
440   {
441     AliMpVPadIterator* it = CreateIterator();
442     it->First();
443     AliMpPad pad = it->CurrentItem();
444     delete it;
445     AliWarning(Form("DE %04d Manu ID %04d not found",pad.GetManuId(),manuId));
446     return 0x0;
447   }
448
449   return InternalMotifPosition(index);
450 }
451