]> git.uio.no Git - u/mrichter/AliRoot.git/blob - MUON/mapping/AliMpSectorSegmentation.cxx
Fix for the problem during PbPb run of Nov 2010 (Indra)
[u/mrichter/AliRoot.git] / MUON / mapping / AliMpSectorSegmentation.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: AliMpSectorSegmentation.cxx,v 1.15 2006/05/24 13:58:46 ivana Exp $
18 // Category: sector
19
20 //-----------------------------------------------------------------------------
21 // Class AliMpSectorSegmentation
22 // -----------------------------
23 // Class describing the segmentation of the sector.        
24 // Provides methods related to pads:
25 // conversion between pad indices, pad location, pad position;
26 // finding pad neighbour.
27 //
28 // Authors: David Guez, Ivana Hrivnacova; IPN Orsay
29 //-----------------------------------------------------------------------------
30
31 #include "AliMpSectorSegmentation.h"
32 #include "AliMpSector.h"
33 #include "AliMpZone.h"
34 #include "AliMpSubZone.h"
35 #include "AliMpRow.h"
36 #include "AliMpVRowSegment.h"
37 #include "AliMpMotifMap.h"
38 #include "AliMpVMotif.h"
39 #include "AliMpMotifPosition.h"
40 #include "AliMpConnection.h"
41 #include "AliMpSectorAreaHPadIterator.h"
42 #include "AliMpSectorAreaVPadIterator.h"
43 #include "AliMpSectorPadIterator.h"
44 #include "AliMpArea.h"
45 #include "AliMpConstants.h"
46 #include "AliMpEncodePair.h"
47
48 #include "AliLog.h"
49
50 #include <Riostream.h>
51 #include <TMath.h>
52
53 /// \cond CLASSIMP
54 ClassImp(AliMpSectorSegmentation)
55 /// \endcond
56
57 //______________________________________________________________________________
58 AliMpSectorSegmentation::AliMpSectorSegmentation(
59                             const AliMpSector* sector, Bool_t own) 
60   : AliMpVSegmentation(),
61     fkSector(sector),
62     fIsOwner(own),
63     fPadBuffer(0),
64     fMaxIndexInX(0),
65     fMaxIndexInY(0)
66 {
67 /// Standard constructor
68
69   AliDebugStream(1) << "this = " << this << endl;
70
71   fPadBuffer = new AliMpPad(AliMpPad::Invalid());
72   
73   //FillPadDimensionsMap();
74 }
75
76 //______________________________________________________________________________
77 AliMpSectorSegmentation::AliMpSectorSegmentation() 
78   : AliMpVSegmentation(),
79     fkSector(0),
80     fIsOwner(false),
81     fPadBuffer(0),
82     fMaxIndexInX(0),
83     fMaxIndexInY(0)
84 {
85 /// Default constructor
86
87   AliDebugStream(1) << "this = " << this << endl;
88 }
89
90 //______________________________________________________________________________
91 AliMpSectorSegmentation::~AliMpSectorSegmentation() 
92 {
93 /// Destructor 
94
95   AliDebugStream(1) << "this = " << this << endl;
96
97   if ( fIsOwner ) delete fkSector;
98
99   delete fPadBuffer;
100   
101 }
102
103 //
104 // private methods
105 //
106
107 //______________________________________________________________________________
108 AliMpMotifPosition* 
109 AliMpSectorSegmentation::FindMotifPosition(Int_t ix, Int_t iy) const
110 {
111 /// Find the motif position which contains the given pad indices
112 /// return 0 if not found
113
114   switch ( fkSector->GetDirection() ) {
115     case AliMp::kX : {
116     // Case where all the pads have the same size along X direction
117
118       for ( Int_t irow=0; irow<fkSector->GetNofRows(); ++irow ) {
119         AliMpRow* row = fkSector->GetRow(irow);
120         if ( row->GetLowLimitIx() <= ix &&
121              row->GetHighLimitIx()>= ix ) {
122             
123           for ( Int_t iseg=0;iseg<row->GetNofRowSegments();++iseg ) {
124             AliMpVRowSegment* seg = row->GetRowSegment(iseg);
125             if ( seg->GetLowLimitIx() <= ix &&
126                  seg->GetHighLimitIx() >= ix ) {
127
128               AliMpMotifPosition* motifPos;
129               for ( Int_t imot=0;imot<seg->GetNofMotifs();++imot ) {
130                 motifPos 
131                   = fkSector->GetMotifMap()
132                     ->FindMotifPosition(seg->GetMotifPositionId(imot));
133                 if (motifPos && motifPos->HasPadByIndices(AliMp::Pair(ix,iy))) return motifPos;
134               }
135             }
136           }
137         }
138       }
139       return 0;
140     }
141     break;
142     ////////////////////////////////////////////////////////////////////////////////
143     case AliMp::kY : {
144       // Case where all the pads have the same size along Y direction   
145       // look for the row which contains the indices
146       AliMpRow* row=0;
147       Int_t irow;
148       for ( irow=0; irow<fkSector->GetNofRows(); ++irow ) {
149         row = fkSector->GetRow(irow);
150         AliMpVRowSegment* lastSeg = row->GetRowSegment(row->GetNofRowSegments()-1);
151         if ( lastSeg->GetLowLimitIy() <= iy &&
152              lastSeg->GetHighLimitIy() >= iy ) break;
153         // NOTE : We use the last row segment in order to ensure that
154         // we are not on a special motif
155       }
156       if ( irow==fkSector->GetNofRows() ) return 0;
157       // look for the row segment, in the found row, which contains the indices
158       AliMpVRowSegment* seg=0;
159       Int_t iseg;
160       for ( iseg=0;iseg<row->GetNofRowSegments();++iseg ) {
161         seg = row->GetRowSegment(iseg);
162         if (seg->HasIndices(AliMp::Pair(ix, iy))) break;
163       }
164       if ( iseg==row->GetNofRowSegments() ) return 0;
165   
166       // look for the motif position which contains the indices
167       AliMpMotifPosition* motifPos=0;
168       Int_t imot=0;
169       for ( imot=0;imot<seg->GetNofMotifs();++imot ) {
170         motifPos 
171           = fkSector->GetMotifMap()
172             ->FindMotifPosition(seg->GetMotifPositionId(imot));
173         if (motifPos && motifPos->HasPadByIndices(AliMp::Pair(ix, iy))) break;
174       }      
175       if (imot==seg->GetNofMotifs()) return 0;
176    
177       return motifPos;      
178     }
179     default: return 0;
180   }
181 }
182
183 //______________________________________________________________________________
184 AliMpPad 
185 AliMpSectorSegmentation::PadByXDirection(Double_t startx, Double_t starty, 
186                                          Double_t maxX) const
187 {
188 /// Find the first valid pad from starting position in the
189 /// direction of pad lines up to distance dx.
190
191   // Define step limits
192   Double_t  stepX = fkSector->GetMinPadDimensionX();
193  
194   // Search in X direction
195   AliMpPad pad;
196   Double_t posx = startx;
197   do {
198     pad = PadByPosition(posx, starty, false);
199     posx += stepX;
200   }   
201   while ( ! pad.IsValid() && 
202             posx - fkSector->GetMaxPadDimensionX() < maxX ); 
203   
204   // Invalidate pad if it is outside limits
205   if ( ( pad.GetPositionX() - pad.GetDimensionX()) > maxX ) 
206     pad = AliMpPad::Invalid();
207
208   return pad;
209 }
210
211 //______________________________________________________________________________
212 AliMpPad 
213 AliMpSectorSegmentation::PadByYDirection(Double_t startx, Double_t starty, 
214                                          Double_t maxY) const
215 {
216 /// Find the first valid pad from starting position in the
217 /// direction of pad columns up to distance dx.
218   
219   // Define step limits
220   Double_t stepY = fkSector->GetMinPadDimensionY();
221  
222   // Search in Y direction
223   AliMpPad pad;
224   Double_t posy = starty;
225   do {
226     pad = PadByPosition(startx, posy, false);
227     posy += stepY;
228   }   
229   while ( ! pad.IsValid() && 
230             posy - fkSector->GetMaxPadDimensionY()< maxY ); 
231   
232   // Invalidate pad if it is outside limits
233   if (( pad.GetPositionY() - pad.GetDimensionY()) > maxY ) 
234     pad = AliMpPad::Invalid();
235
236   return pad;
237 }
238
239 //
240 // public methods
241 //
242
243 //______________________________________________________________________________
244 AliMpVPadIterator* 
245 AliMpSectorSegmentation::CreateIterator(const AliMpArea& area) const
246 {
247 /// Create the area iterator. 
248
249   switch (fkSector->GetDirection()) {
250   
251     case AliMp::kX: return new AliMpSectorAreaVPadIterator(this, area);
252              ;;
253     case AliMp::kY: return new AliMpSectorAreaHPadIterator(this, area);
254              ;;
255   }
256   
257   Fatal("CreateIterator", "Incomplete switch on Sector direction");
258   return 0;  
259 }   
260   
261 //______________________________________________________________________________
262 AliMpVPadIterator* 
263 AliMpSectorSegmentation::CreateIterator() const
264 {
265 /// Create the sector iterator
266
267   return new AliMpSectorPadIterator(fkSector);
268 }
269
270 //______________________________________________________________________________
271 Int_t 
272 AliMpSectorSegmentation::GetNeighbours(const AliMpPad& pad, TObjArray& neighbours,
273                                        Bool_t includeSelf,
274                                        Bool_t includeVoid) const
275 {
276   /// Uses default implementation
277   return AliMpVSegmentation::GetNeighbours(pad,neighbours,includeSelf,includeVoid);
278 }
279
280 //______________________________________________________________________________
281 AliMpPad 
282 AliMpSectorSegmentation::PadByLocation(Int_t manuId, Int_t manuChannel, 
283                                        Bool_t warning) const
284 {
285 /// Find the pad which corresponds to the given location
286  
287   if ( fPadBuffer->GetManuId() == manuId &&
288        fPadBuffer->GetManuChannel() == manuChannel ) return (*fPadBuffer);
289   
290   AliMpMotifPosition* motifPos = 
291     fkSector->GetMotifMap()->FindMotifPosition(manuId);
292   if (!motifPos){
293     if (warning) Warning("PadByLocation","The pad motif position ID doesn't exists");
294     return AliMpPad::Invalid();
295   }
296   
297   AliMpVMotif* motif = motifPos->GetMotif();
298   MpPair_t localIndices = 
299     motif->GetMotifType()->FindLocalIndicesByGassiNum(manuChannel);
300   if ( localIndices < 0 ) {
301     if (warning) Warning("PadByLocation","The pad number doesn't exists");
302     return AliMpPad::Invalid();
303   }
304
305   Double_t posx, posy;
306   motif->PadPositionLocal(localIndices, posx, posy);
307   posx += motifPos->GetPositionX();
308   posy += motifPos->GetPositionY();
309
310   Double_t dx, dy;
311   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
312
313   return (*fPadBuffer) = AliMpPad(manuId, manuChannel,
314               motifPos->GlobalIndices(localIndices),
315               posx, posy, dx, dy);
316 }
317 //______________________________________________________________________________
318 AliMpPad 
319 AliMpSectorSegmentation::PadByIndices(Int_t ix, Int_t iy, Bool_t warning ) const
320 {
321 /// Find the pad which corresponds to the given indices  
322
323   if ( fPadBuffer->GetIx() == ix &&
324        fPadBuffer->GetIy() == iy ) return (*fPadBuffer);    
325        
326   MpPair_t indices = AliMp::Pair(ix, iy);     
327   AliMpMotifPosition* motifPos = FindMotifPosition(ix, iy);
328   if (!motifPos) {    
329     if (warning) 
330       Warning("PadByIndices","Pad indices not contained in any motif!");
331     return AliMpPad::Invalid();
332   }
333   
334   // retrieve the local indices in the found motif
335   AliMpVMotif* motif = motifPos->GetMotif();
336   MpPair_t localIndices = indices - motifPos->GetLowIndicesLimit();
337   
338   AliMpConnection* connection=
339     motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
340     
341   if (!connection){
342     if (warning) Warning("PadByIndices","No connection with the given indices!");
343     return AliMpPad::Invalid();
344   }
345
346   Double_t posx, posy;
347   motif->PadPositionLocal(localIndices, posx, posy);
348   posx += motifPos->GetPositionX();
349   posy += motifPos->GetPositionY();
350
351   Double_t dx, dy;
352   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
353
354   return (*fPadBuffer) 
355     = AliMpPad(motifPos->GetID(),connection->GetManuChannel(),
356                ix, iy, posx, posy, dx, dy);
357 }
358
359 //______________________________________________________________________________
360 AliMpPad 
361 AliMpSectorSegmentation::PadByPosition(Double_t x, Double_t y,
362                                        Bool_t warning) const
363 {
364 /// Find the pad which corresponds to the given position
365
366   if (fPadBuffer->GetPositionX()==x && 
367       fPadBuffer->GetPositionY()==y) return (*fPadBuffer);  
368
369   Int_t motifPosID = fkSector->FindMotifPositionId(x,y);
370   AliMpMotifPosition* motifPos 
371     = fkSector->GetMotifMap()
372         ->FindMotifPosition(motifPosID);
373     
374   if (!motifPos){
375     if (warning) Warning("PadByPosition","Position outside limits");
376     return AliMpPad::Invalid();
377   }
378
379   AliMpVMotif* motif =  motifPos->GetMotif();  
380   MpPair_t localIndices 
381     = motif->PadIndicesLocal(x-motifPos->GetPositionX(),
382                              y-motifPos->GetPositionY());
383
384   if ( localIndices < 0 ) {
385     if (warning) Warning("PadByPosition","Position outside motif limits");
386     return AliMpPad::Invalid();
387   }
388     
389   AliMpConnection* connect = 
390     motif->GetMotifType()->FindConnectionByLocalIndices(localIndices);
391
392   if ( ! connect ) {
393     if (warning) Warning("PadByPosition","Position outside motif limits");
394     return AliMpPad::Invalid();
395   }
396
397   Double_t posx, posy;
398   motif->PadPositionLocal(localIndices, posx, posy);
399   posx += motifPos->GetPositionX();
400   posy += motifPos->GetPositionY();
401
402   Double_t dx, dy;
403   motif->GetPadDimensionsByIndices(localIndices, dx, dy);
404   
405   return (*fPadBuffer)
406     = AliMpPad(motifPosID, connect->GetManuChannel(),
407                motifPos->GlobalIndices(localIndices),
408                posx, posy, dx, dy);
409 }
410
411 //______________________________________________________________________________
412 AliMpPad 
413 AliMpSectorSegmentation::PadByDirection(Double_t startx, Double_t starty, 
414                                         Double_t distance) const
415 {
416 /// Find the first valid pad from starting position in the
417 /// direction of pad lines/columns up to the specified distance.
418 /// Pad lines are the lines of pads in the sector with constant pad y size,
419 /// pad columns are the columns of pads in the sector with constant pad x size. 
420
421   switch (fkSector->GetDirection()) {
422   
423     case AliMp::kX: return PadByYDirection(startx, starty, distance);
424              ;;
425     case AliMp::kY: return PadByXDirection(startx, starty, distance);
426              ;;
427   }
428   
429   Fatal("PadByDirection", "Incomplete switch on Sector direction");
430   return AliMpPad::Invalid();  
431 }
432
433 //_____________________________________________________________________________
434 Bool_t 
435 AliMpSectorSegmentation::HasPadByIndices(Int_t ix, Int_t iy) const
436 {
437   ///  Whether or not we have a pad at indices=(ix,iy) 
438   
439   MpPair_t indices = AliMp::Pair(ix, iy);
440
441   AliMpMotifPosition* motifPos = FindMotifPosition(ix, iy);
442   
443   if (motifPos) return motifPos->HasPadByIndices(indices);
444   
445   return kFALSE;
446 }
447
448 //_____________________________________________________________________________
449 Bool_t 
450 AliMpSectorSegmentation::HasPadByLocation(Int_t manuId, Int_t manuChannel) const
451 {
452   /// Whether or not we have a pad at location=(manuId,manuChannel)
453   
454   AliMpMotifPosition* motifPos 
455     = fkSector->GetMotifMap()->FindMotifPosition(manuId);
456   
457   if ( motifPos ) return motifPos->HasPadByManuChannel(manuChannel);
458   
459   return kFALSE;
460 }
461
462 //______________________________________________________________________________
463 Int_t  AliMpSectorSegmentation::MaxPadIndexX() const
464 {
465 /// Return maximum pad index in x
466
467   return AliMp::PairFirst(fkSector->GetMaxPadIndices());
468 }
469
470 //______________________________________________________________________________
471 Int_t  AliMpSectorSegmentation::MaxPadIndexY() const
472 {
473 /// Return maximum pad index in y
474
475   return AliMp::PairSecond(fkSector->GetMaxPadIndices());
476 }
477
478 //______________________________________________________________________________
479 Int_t  AliMpSectorSegmentation::NofPads() const
480 {
481 /// Return number of pads defined in the sector
482
483   return fkSector->GetNofPads();
484 }
485
486 //_____________________________________________________________________________
487 void 
488 AliMpSectorSegmentation::GetAllElectronicCardIDs(TArrayI& ecn) const
489 {
490   /// Fill the array ecn with all manuIds
491
492   GetSector()->GetAllMotifPositionsIDs(ecn);
493 }
494
495 //_____________________________________________________________________________
496 Int_t 
497 AliMpSectorSegmentation::GetNofElectronicCards() const
498 {
499   /// Get the number of manus of this sector
500   
501   return fkSector->GetNofMotifPositions();  
502 }
503
504 //_____________________________________________________________________________
505 Bool_t 
506 AliMpSectorSegmentation::HasMotifPosition(Int_t manuId) const
507 {
508   /// Whether we get a given manu. Uses default implementation
509   return (AliMpVSegmentation::HasMotifPosition(manuId) != 0x0);
510 }
511
512 //_____________________________________________________________________________
513 AliMpMotifPosition* 
514 AliMpSectorSegmentation::MotifPosition(Int_t manuId) const
515 {
516   /// Return a given manu
517   return fkSector->GetMotifMap()->FindMotifPosition(manuId);
518 }
519
520 //______________________________________________________________________________
521 AliMp::PlaneType
522 AliMpSectorSegmentation::PlaneType() const
523 {
524   return GetSector()->GetPlaneType();
525 }
526
527 //_____________________________________________________________________________
528 Double_t  
529 AliMpSectorSegmentation::GetDimensionX() const
530 {
531 /// Return sector x dimensions
532   return GetSector()->GetDimensionX();
533 }
534
535 //_____________________________________________________________________________
536 Double_t  
537 AliMpSectorSegmentation::GetDimensionY() const
538 {
539 /// Return sector y dimensions
540   return GetSector()->GetDimensionY();
541 }
542
543 //_____________________________________________________________________________
544 Double_t  
545 AliMpSectorSegmentation::GetPositionX() const
546 {
547 /// Return x position 
548   return 0.;
549 }
550
551 //_____________________________________________________________________________
552 Double_t  
553 AliMpSectorSegmentation::GetPositionY() const
554 {
555 /// Return y position 
556   return 0.;
557 }
558
559 //______________________________________________________________________________
560 void
561 AliMpSectorSegmentation::Print(Option_t* opt) const
562 {
563 /// Print the sector
564
565   fkSector->Print(opt);
566 }
567
568 //______________________________________________________________________________
569 Double_t AliMpSectorSegmentation::GetMinPadDimensionX() const
570 {
571 /// Return the x dimension of the smallest pad.
572
573   return fkSector->GetMinPadDimensionX();
574 }  
575
576
577 //______________________________________________________________________________
578 Double_t AliMpSectorSegmentation::GetMinPadDimensionY() const
579 {
580 /// Return the y dimension of the smallest pad.
581
582   return fkSector->GetMinPadDimensionY();
583 }  
584
585
586 //______________________________________________________________________________
587 Bool_t AliMpSectorSegmentation::CircleTest(Int_t ix, Int_t iy) const
588 {
589 /// Verify that all methods for retrieving pads are consistents between them.
590 /// Return true if the pad with specified indices was found and verified,
591 /// false otherwise.
592
593   if ( ! HasPadByIndices(ix, iy) ) return false;
594
595   // Verify the indice->location->position->indice way
596   AliMpPad pad1 = PadByIndices(ix, iy);  
597   AliMpPad pad2 = PadByLocation(pad1.GetManuId(), pad1.GetManuChannel());
598   AliMpPad pad3 = PadByPosition(pad2.GetPositionX(),pad2.GetPositionY());
599                                       
600   MpPair_t retIndices = pad3.GetIndices();
601     
602   if ( retIndices != AliMp::Pair(ix, iy) ) {
603     cout << "Pad (" << ix << ',' << iy << ") lead to inconsistency" << endl;
604     cout << "in indice->location->position->indice way..." << endl;
605     cout << "starting from indices " << pad1 << endl
606          << "--> location " << pad2 << endl
607          << "--> position " 
608          << '(' << pad3.GetPositionX() << ',' << pad3.GetPositionY() << ')'
609          <<  endl << endl;
610   }
611     
612   // Verify the indice->position->location->indice way  
613   AliMpPad pad2bis = PadByPosition(pad1.GetPositionX(),pad1.GetPositionY());
614   AliMpPad pad3bis = PadByLocation(pad2bis.GetManuId(), pad2bis.GetManuChannel());
615   
616   retIndices = pad3bis.GetIndices();
617
618   if ( retIndices != AliMp::Pair(ix, iy) ) {
619     cout << "Pad (" << ix << ',' << iy << ") lead to inconsistency" << endl;
620     cout << "in indice->position->location->indice way..." << endl;
621     cout << "starting from indices " << pad1 << endl
622          << "--> position " 
623          << '(' << pad2bis.GetPositionX() << ',' << pad2bis.GetPositionY() << ')' << endl
624          << "--> location " << pad3bis
625          << endl << endl;
626   }
627   
628   return true;
629 }