Correct use of ROOT_INCLUDE_DIR
[u/mrichter/AliRoot.git] / MUON / MUONmapping / 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 fPositionX(0.),
85 fPositionY(0.)
86 {
87   /// Ctor. We adopt vseg.
88   
89   if (!vseg) 
90   {
91     AliError("Will get a hard time working with a NULL vseg !");
92     return;
93   }
94   
95   AliCodeTimerAuto(vseg->ClassName(),0);
96   
97   fPositionX = vseg->GetPositionX();
98   fPositionY = vseg->GetPositionY();
99   
100   TArrayI manus;
101   
102   vseg->GetAllElectronicCardIDs(manus);
103   
104   for ( Int_t i = 0; i < manus.GetSize(); ++i ) 
105   {
106     Int_t manuId = manus[i];
107     
108     AliMpMotifPosition* mp = vseg->MotifPosition(manuId);
109     
110     // Should never happen
111     if ( ! mp ) {
112       AliFatal("AliMpMotifPosition not found.");
113     }  
114     
115     Int_t index = 1 + fMotifPositions.GetLast();
116
117     fMotifPositions.AddLast(mp);
118
119     fManuId.Add(Encode2(manuId),1+index);
120
121     for ( Int_t manuChannel = 0; manuChannel < AliMpConstants::ManuNofChannels(); ++manuChannel )
122     {
123       if ( vseg->HasPadByLocation(manuId,manuChannel) )
124       {
125         AliMpPad pad = vseg->PadByLocation(manuId,manuChannel);
126         
127         fIxIy.Add(Encode(pad.GetIx(),pad.GetIy()),1+index);
128       }
129     }
130   }
131 }
132
133 //_____________________________________________________________________________
134 AliMpFastSegmentation::~AliMpFastSegmentation()
135 {
136   /// dtor
137   delete fHelper;
138 }
139
140 //_____________________________________________________________________________
141 AliMpVPadIterator* 
142 AliMpFastSegmentation::CreateIterator(const AliMpArea& area) const
143 {
144   /// Forward to our helper
145   return fHelper->CreateIterator(area);
146 }
147
148 //_____________________________________________________________________________
149 AliMpVPadIterator* 
150 AliMpFastSegmentation::CreateIterator() const
151 {
152   /// Forward to our helper
153   return fHelper->CreateIterator();
154 }
155
156 //_____________________________________________________________________________
157 Int_t 
158 AliMpFastSegmentation::GetNeighbours(const AliMpPad& pad, TObjArray& neighbours,
159                                      Bool_t includeSelf,
160                                      Bool_t includeVoid) const
161 {
162   /// Use default implementation
163   return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
164 }
165
166 //_____________________________________________________________________________
167 AliMpPad 
168 AliMpFastSegmentation::PadByLocation(Int_t manuId, Int_t manuChannel, 
169                                      Bool_t warning) const
170 {
171   /// Get the pad by location, using the manuid map.
172   
173   Int_t index = fManuId.GetValue(Encode2(manuId));
174   
175   if (!index) 
176   {
177     if (warning)
178     {
179       AliWarning(Form("Manu ID %d not found",manuId));
180       Print();
181     }
182     return AliMpPad::Invalid();
183   }
184   
185   AliMpMotifPosition* motifPos = InternalMotifPosition(index);
186   
187   if (!motifPos)
188   {
189     AliError(Form("InternalMotifPosition(%d) failed",index));
190     Print();
191     return AliMpPad::Invalid();
192   }
193   
194   AliMpVMotif* motif = motifPos->GetMotif();
195   MpPair_t localIndices 
196     =  motif->GetMotifType()->FindLocalIndicesByGassiNum(manuChannel);
197         
198   if ( localIndices < 0 ) 
199   {
200     if (warning) 
201     {
202       AliWarning(Form("The pad number %d doesn't exists", manuChannel));
203       Print();
204     }
205     return AliMpPad::Invalid();
206   }
207         
208 #ifdef CHECK
209   Double_t posx, posy;
210   motif->PadPositionLocal(localIndices, posx, posy);
211   posx += motifPos->GetPositionX() - fPositionX;
212   posy += motifPos->GetPositionY() - fPositionY;
213
214   Double_t dx, dy;
215   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
216   
217   AliMpPad pad1 = AliMpPad(manuId, manuChannel,
218                            motifPos->GlobalIndices(localIndices),
219                            posx, posy, dx, dy);
220
221   AliMpPad pad2 = fHelper->PadByLocation(manuId, manuChannel,warning);
222   if ( pad1 != pad2 ) 
223   {
224     Print();
225     pad1.Print();
226     pad2.Print();
227     assert(pad1==pad2);
228   }
229 #endif
230   Double_t posx, posy;
231   motif->PadPositionLocal(localIndices, posx, posy);
232   posx += motifPos->GetPositionX() - fPositionX;
233   posy += motifPos->GetPositionY() - fPositionY;
234
235   Double_t dx, dy;
236   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
237
238   return AliMpPad(manuId, manuChannel,
239                   motifPos->GlobalIndices(localIndices),
240                   posx, posy, dx, dy);
241 }
242
243 //_____________________________________________________________________________
244 AliMpMotifPosition*
245 AliMpFastSegmentation::InternalMotifPosition(Int_t index) const
246 {
247   /// Get the internal manu from the index
248   return static_cast<AliMpMotifPosition*>(fMotifPositions.UncheckedAt(index-1));
249 }
250
251 //_____________________________________________________________________________
252 AliMpPad 
253 AliMpFastSegmentation::PadByIndices (Int_t ix, Int_t iy, Bool_t warning) const
254 {
255   /// Get pad by indices
256   
257   Int_t index = fIxIy.GetValue(Encode(ix, iy));
258   
259   if ( !index )
260   {
261     if (warning)
262     {
263       AliWarning(Form("ManuID not found for pad indices (%d,%d)", ix, iy));       
264       Print();
265     }
266     return AliMpPad::Invalid();
267   }
268   
269   AliMpMotifPosition* motifPos = InternalMotifPosition(index);
270
271   if (!motifPos)
272         {
273     AliError(Form("InternalMotifPosition(%d) failed",index));
274     Print();
275                 return AliMpPad::Invalid();
276         }
277         
278   AliMpVMotif* motif = motifPos->GetMotif();
279   AliMpMotifType* motifType = motif->GetMotifType();
280   MpPair_t localIndices(AliMp::Pair(ix, iy) - motifPos->GetLowIndicesLimit());
281   AliMpConnection* connection = motifType->FindConnectionByLocalIndices(localIndices);
282   
283   if (!connection)
284   {
285     if ( warning )
286     {
287       AliWarning(Form("No connection for pad indices (%d,%d)", ix, iy));
288     }
289     return AliMpPad::Invalid();
290   }
291         
292 #ifdef CHECK
293   AliMpPad pad2 = fHelper->PadByIndices(ix, iy, warning);
294
295   Double_t posx, posy;
296   motif->PadPositionLocal(localIndices, posx, posy);
297   posx += motifPos->GetPositionX() - fPositionX;
298   posy += motifPos->GetPositionY() - fPositionY;
299
300   Double_t dx, dy;
301   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
302
303   AliMpPad pad1 = AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
304                           ix, iy, posx, posy, dx, dy);
305   
306   assert(pad1==pad2);
307 #endif
308   Double_t posx, posy;
309   motif->PadPositionLocal(localIndices, posx, posy);
310   posx += motifPos->GetPositionX() - fPositionX;
311   posy += motifPos->GetPositionY() - fPositionY;
312  
313   Double_t dx, dy;
314   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
315
316   return AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
317                   ix, iy, posx, posy, dx, dy);
318   
319 }
320
321 //_____________________________________________________________________________
322 AliMpPad 
323 AliMpFastSegmentation::PadByPosition(Double_t x, Double_t y, Bool_t warning ) const
324 {
325   /// Forward to our helper
326   return fHelper->PadByPosition(x, y, warning);
327 }
328
329 //_____________________________________________________________________________
330 Int_t 
331 AliMpFastSegmentation::MaxPadIndexX() const
332 {
333   /// Forward to our helper
334   return fHelper->MaxPadIndexX();
335 }
336
337 //_____________________________________________________________________________
338 Int_t  
339 AliMpFastSegmentation::MaxPadIndexY() const
340 {
341   /// Forward to our helper
342   return fHelper->MaxPadIndexY();
343 }
344
345 //_____________________________________________________________________________
346 Int_t  
347 AliMpFastSegmentation::NofPads() const
348 {
349   /// Forward to our helper
350   return fHelper->NofPads();
351 }
352
353 //_____________________________________________________________________________
354 Int_t
355 AliMpFastSegmentation::GetNofElectronicCards() const
356 {
357   /// Forward to our helper
358   return fHelper->GetNofElectronicCards();
359 }
360
361 //_____________________________________________________________________________
362 void
363 AliMpFastSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
364 {
365   /// Forward to our helper
366   fHelper->GetAllElectronicCardIDs(ecn);
367 }
368
369 //_____________________________________________________________________________
370 Bool_t 
371 AliMpFastSegmentation::HasPadByIndices(Int_t ix, Int_t iy) const
372 {
373   /// Whether there is a pad at the given indices
374   Int_t index = fIxIy.GetValue(Encode(ix, iy));
375   
376   if ( !index ) return kFALSE;
377   
378   AliMpMotifPosition* mp = InternalMotifPosition(index);
379   
380   Bool_t r1 = mp->HasPadByIndices(AliMp::Pair(ix, iy));
381 #ifdef CHECK
382   Bool_t r2 = fHelper->HasPadByIndices(ix, iy);
383   
384   assert(r1==r2);
385 #endif
386   return r1;
387 }
388
389 //_____________________________________________________________________________
390 Bool_t 
391 AliMpFastSegmentation::HasPadByLocation(Int_t manuId, Int_t manuChannel) const
392 {
393   /// Whether there is a pad at the given location (de,manuid)
394   
395   Int_t index = fManuId.GetValue(Encode2(manuId));
396   
397   if (!index) return kFALSE;
398   
399   AliMpMotifPosition* mp = InternalMotifPosition(index);
400   
401   Bool_t r1 = mp->HasPadByManuChannel(manuChannel);
402 #ifdef CHECK
403   Bool_t r2 = fHelper->HasPadByLocation(manuId, manuChannel);
404   
405   assert(r1==r2);
406 #endif
407   return r1;
408 }
409
410 //_____________________________________________________________________________
411 void
412 AliMpFastSegmentation::Print(Option_t* opt) const
413 {
414   /// Forward to our helper
415   fHelper->Print(opt);
416 }
417
418 //_____________________________________________________________________________
419 AliMp::PlaneType
420 AliMpFastSegmentation::PlaneType() const
421 {
422   /// Forward to our helper
423   return fHelper->PlaneType();
424 }
425
426 //_____________________________________________________________________________
427 Double_t  
428 AliMpFastSegmentation::GetDimensionX() const
429 {
430   /// Forward to our helper
431   return fHelper->GetDimensionX();
432 }
433
434 //_____________________________________________________________________________
435 Double_t  
436 AliMpFastSegmentation::GetDimensionY() const
437 {
438   /// Forward to our helper
439   return fHelper->GetDimensionY();
440 }
441
442 //_____________________________________________________________________________
443 Double_t  
444 AliMpFastSegmentation::GetPositionX() const
445 {
446   /// Forward to our helper
447   return fHelper->GetPositionX();
448 }
449
450 //_____________________________________________________________________________
451 Double_t  
452 AliMpFastSegmentation::GetPositionY() const
453 {
454   /// Forward to our helper
455   return fHelper->GetPositionY();
456 }
457
458 //_____________________________________________________________________________
459 Bool_t
460 AliMpFastSegmentation::HasMotifPosition(Int_t manuId) const
461 {
462   /// Whether or not we have a given manu
463   return ( fManuId.GetValue(Encode2(manuId)) != 0);
464 }
465
466 //_____________________________________________________________________________
467 AliMpMotifPosition*
468 AliMpFastSegmentation::MotifPosition(Int_t manuId) const
469 {
470   /// Get the motifPosition object of a given manu
471   Int_t index = fManuId.GetValue(Encode2(manuId));
472
473   if (!index) 
474   {
475     AliMpVPadIterator* it = CreateIterator();
476     it->First();
477     AliMpPad pad = it->CurrentItem();
478     delete it;
479     AliWarning(Form("DE %04d Manu ID %04d not found",pad.GetManuId(),manuId));
480     return 0x0;
481   }
482
483   return InternalMotifPosition(index);
484 }
485