LCOV - code coverage report
Current view: top level - MUON/MUONmapping - AliMpPCBPadIterator.cxx (source / functions) Hit Total Coverage
Test: coverage.info Lines: 79 95 83.2 %
Date: 2016-06-14 17:26:59 Functions: 14 15 93.3 %

          Line data    Source code
       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$
      18             : 
      19             : #include "AliMpPCBPadIterator.h"
      20             : 
      21             : #include "AliMpArea.h"
      22             : #include "AliMpConstants.h"
      23             : #include "AliLog.h"
      24             : #include "AliMpPCB.h"
      25             : #include "AliMpSlat.h"
      26             : #include "AliMpSlatSegmentation.h"
      27             : #include "AliMpEncodePair.h"
      28             : 
      29             : #include "Riostream.h"
      30             : #include "TMath.h"
      31             : 
      32             : 
      33             : //-----------------------------------------------------------------------------
      34             : /// \class AliMpPCBPadIterator
      35             : /// 
      36             : /// Iterates over slat pads within a region of constant pad size.
      37             : /// 
      38             : /// \author Laurent Aphecetche
      39             : //-----------------------------------------------------------------------------
      40             : 
      41             : using std::cout;
      42             : using std::endl;
      43             : /// \cond CLASSIMP
      44          18 : ClassImp(AliMpPCBPadIterator)
      45             : /// \endcond
      46             : 
      47             : //_____________________________________________________________________________
      48             : AliMpPCBPadIterator::AliMpPCBPadIterator(const AliMpSlat* slat,
      49             :                                          const AliMpArea& area)
      50         110 : : AliMpVPadIterator(),
      51         110 : fkSlat(slat),
      52         330 : fSlatSegmentation(new AliMpSlatSegmentation(slat)),
      53         110 : fMinIndices(0),
      54         110 : fMaxIndices(0),
      55         110 : fOffset(0),
      56         110 : fCurrentPad(),
      57         110 : fIsDone(kTRUE)
      58         550 : {
      59             :   ///
      60             :   /// Normal ctor.
      61             :   /// Iteration will be done on the slat, over the crop of (area,slat_area)
      62             :   ///
      63         220 :   if (!CropArea(area)) 
      64             :   {
      65           0 :     AliError(Form("Could not crop area : (x,y)min=(%e,%e) ; max=(%e,%e) for slat %s",
      66             :                   area.LeftBorder(),area.DownBorder(),
      67             :                   area.RightBorder(),area.UpBorder(),fkSlat->GetID()));
      68             :   }
      69         110 :   Invalidate();
      70         220 : }
      71             : 
      72             : //_____________________________________________________________________________
      73             : AliMpPCBPadIterator::~AliMpPCBPadIterator()
      74         660 : {
      75             :   ///
      76             :   /// Dtor.
      77             :   ///
      78         220 :   delete fSlatSegmentation;
      79         330 : }
      80             : 
      81             : //_____________________________________________________________________________
      82             : Bool_t
      83             : AliMpPCBPadIterator::CropArea(const AliMpArea& area)
      84             : {
      85             :   ///
      86             :   /// Checks the area is correct, and truncate it
      87             :   /// if it goes outside the slat.
      88             :   
      89         440 :   AliDebug(3,Form("Input area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
      90             :                   area.LeftBorder(),area.DownBorder(),
      91             :                   area.RightBorder(),area.UpBorder()));
      92             :   
      93         110 :   const Double_t kEpsilon = AliMpConstants::LengthTolerance();
      94             :   
      95             :   // Left and right x-limits have to come from first and last pcbs
      96             :   // to deal with short and rounded pcbs cases.
      97         110 :   AliMpPCB* first = fkSlat->FindPCB(area.LeftBorder(),area.DownBorder());
      98         220 :   AliMpPCB* last = fkSlat->FindPCB(area.RightBorder()-kEpsilon,
      99         110 :                                    area.DownBorder());
     100             :   
     101             :   // Check we're indeed dealing with only one pcb
     102         110 :   if ( first != last )
     103             :   {
     104           0 :     AliError("This iterator supposed to work on a single PCB. Please check");
     105           0 :     return kFALSE;
     106             :   }
     107             :   
     108         330 :   AliDebug(3,Form("PCB %s Ixmin %2d Ixmax %2d",
     109             :                   first->GetID(),first->Ixmin(),first->Ixmax()));
     110             :   
     111         110 :   Double_t xleft = first->ActiveXmin();
     112         110 :   Double_t xright = first->ActiveXmax() - kEpsilon;
     113             :   
     114         330 :   AliDebug(3,Form("xleft,xright=%e,%e",xleft,xright));
     115             :   
     116         110 :   Double_t xmin = TMath::Max(area.LeftBorder(),xleft);
     117         110 :   Double_t xmax = TMath::Min(area.RightBorder(),xright);
     118         110 :   Double_t ymin = TMath::Max(area.DownBorder(),0.0);
     119         110 :   Double_t ymax = TMath::Min(area.UpBorder(),first->DY()*2.0-kEpsilon);
     120             :   
     121         330 :   AliDebug(3,Form("Cropped area (%e,%e)->(%e,%e)",
     122             :                   xmin,ymin,xmax,ymax));
     123             :   
     124             :   // At this point (xmin,ymin)->(xmax,ymax) should be a zone completely included
     125             :   // inside the slat.
     126             :   // We now try to convert this into a couple of indices pair indicating the
     127             :   // region to iterate over, using integer values, not floating point ones.
     128             :   // For this, we must find out the 4 pads that intersect the (xmin,ymin;xmax,ymax)
     129             :   // area.
     130             :   
     131         110 :   Int_t ixmin = first->Ixmin() + TMath::FloorNint((xmin-first->ActiveXmin())/first->PadSizeX());
     132         110 :   Int_t ixmax = first->Ixmin() + TMath::CeilNint((xmax-first->ActiveXmin())/first->PadSizeX()) - 1;
     133         110 :   Int_t iymin = first->Iymin() + TMath::FloorNint((ymin-first->Ymin())/first->PadSizeY());
     134         110 :   Int_t iymax = first->Iymin() + TMath::CeilNint((ymax-first->Ymin())/first->PadSizeY()) - 1;
     135             :   
     136             :   
     137         110 :   fMinIndices = AliMp::Pair(ixmin,iymin);
     138         110 :   fMaxIndices = AliMp::Pair(ixmax,iymax);
     139             :   
     140         330 :   AliDebug(3,Form("Paddified cropped area (%d,%d)->(%d,%d) %d,%d ; %d,%d",
     141             :                   ixmin,iymin,ixmax,iymax,
     142             :                   AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
     143             :                   AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
     144             :   
     145         220 :   return fMinIndices >= 0 && fMaxIndices >= 0;
     146         110 : }
     147             : 
     148             : //_____________________________________________________________________________
     149             : AliMpPad
     150             : AliMpPCBPadIterator::CurrentItem() const
     151             : {
     152             :   ///
     153             :   /// Returns the current iteration position (i.e. a pad)
     154             :   ///
     155        2762 :   return fCurrentPad;
     156             : }
     157             : 
     158             : //_____________________________________________________________________________
     159             : void
     160             : AliMpPCBPadIterator::First()
     161             : {
     162             :   ///
     163             :   /// (re)Starts the iteration.
     164             :   ///
     165             :   
     166         440 :   AliDebug(3,Form("area = (%d,%d)->(%d,%d)",
     167             :                   AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
     168             :                   AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
     169         110 :   fOffset = fMinIndices;
     170         110 :   fIsDone = kFALSE;
     171         110 :   SetPad(fCurrentPad,AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset));
     172         110 :   if ( ! fCurrentPad.IsValid() ) Next();
     173         110 :   if ( ! fCurrentPad.IsValid() ) 
     174             :   {
     175             :     // did not find any valid pad in there, bailing out.
     176           0 :     fIsDone = kTRUE;
     177           0 :     AliError(Form("Could not initiate iterator for slat %s. "
     178             :                   " Please check the area you gave : %d,%d to %d,%d",
     179             :                   fkSlat->GetName(),
     180             :                   AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
     181             :                   AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
     182           0 :     return;
     183             :   }
     184         110 : }
     185             : 
     186             : //_____________________________________________________________________________
     187             : Bool_t
     188             : AliMpPCBPadIterator::GetNextPosition(Int_t& ix, Int_t& iy) const
     189             : {
     190             :   /// Get the next iteration position. 
     191             :   /// On input, fOffset must be a valid position (i.e. within iteration
     192             :   /// area already).
     193             :   
     194        2762 :   ++ix;
     195             :   
     196        1381 :   if ( ix > AliMp::PairFirst(fMaxIndices) )
     197             :   {
     198             :     // Go back leftmost position...
     199         552 :     ix = AliMp::PairFirst(fMinIndices);
     200             :     // ... and up
     201         552 :     ++iy;
     202         552 :     if ( iy > AliMp::PairSecond(fMaxIndices) )
     203             :     {
     204         110 :       return false;
     205             :     }
     206             :   }
     207        1271 :   return true;
     208        1381 : }
     209             : 
     210             : 
     211             : //_____________________________________________________________________________
     212             : void
     213             : AliMpPCBPadIterator::Invalidate()
     214             : {
     215             :   ///
     216             :   /// Invalidate the iterator.
     217             :   ///
     218         440 :   fOffset = 0;
     219         440 :   fCurrentPad = AliMpPad::Invalid();
     220         220 :   fIsDone = kTRUE;
     221         220 : }
     222             : 
     223             : //_____________________________________________________________________________
     224             : Bool_t
     225             : AliMpPCBPadIterator::IsDone() const
     226             : {
     227             :   ///
     228             :   /// Whether the iteration is finished or not.
     229             :   ///
     230        5728 :   return fIsDone;
     231             : }
     232             : 
     233             : //_____________________________________________________________________________
     234             : void
     235             : AliMpPCBPadIterator::Next()
     236             : {
     237             :   /// This one is the meat of the class.
     238             :   /// We're iterating in x-direction mainly, starting from 
     239             :   /// lower-left of the iteration area, and proceeding right,
     240             :   /// until we reach right border, in which case we increment y
     241             :   /// and go back to leftmost position.
     242             :   /// End of iteration occurs when both x and y are outside the iteration
     243             :   /// window.
     244             :   
     245        2762 :   if (IsDone()) return;
     246             :   
     247        1381 :   AliMpPad pad(fCurrentPad);
     248             :   int n = 0;
     249        2762 :   Int_t ix(AliMp::PairFirst(fOffset));
     250        2762 :   Int_t iy(AliMp::PairSecond(fOffset));
     251             :   
     252       11989 :   while ( ( pad == fCurrentPad || ! pad.IsValid() ) && n<100 )
     253             :   {
     254        1381 :     ++n;
     255        2762 :     if (GetNextPosition(ix,iy)==kFALSE) 
     256             :     {
     257         110 :       Invalidate();
     258         110 :       return;
     259             :     } 
     260        1271 :     SetPad(pad,ix,iy);
     261             :   }
     262        1271 :   if ( n>=100 )
     263             :   {
     264           0 :     AliFatal("This should not happen!");
     265             :   }
     266        1271 :   fCurrentPad = pad;
     267        4033 : }
     268             : 
     269             : //_____________________________________________________________________________
     270             : void 
     271             : AliMpPCBPadIterator::Print(Option_t*) const
     272             : {
     273             :   /// printout
     274           0 :   cout << Form("fkSlat=%p fSlatSegmentation=%p (%s)",fkSlat,fSlatSegmentation,
     275           0 :                fkSlat->GetName()) << endl
     276           0 :   << Form("minIndices=(%d,%d) maxIndices=(%d,%d)",
     277           0 :           AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
     278           0 :           AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)) << endl
     279           0 :   << Form("currentOffset=(%d,%d) isdone=%d currentpad=",
     280           0 :           AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset),fIsDone) << endl;
     281           0 :   fCurrentPad.Print();
     282           0 : }
     283             : 
     284             : //_____________________________________________________________________________
     285             : void
     286             : AliMpPCBPadIterator::SetPad(AliMpPad& pad, Int_t ix, Int_t iy)
     287             : {
     288             :   ///
     289             :   /// Sets the current pad.
     290             :   ///
     291        4143 :   pad = fSlatSegmentation->PadByIndices(ix, iy,kFALSE);
     292        1381 :   if (pad.IsValid())
     293             :   {
     294        1381 :     fOffset = AliMp::Pair(ix,iy);
     295        1381 :   }
     296        1381 : }

Generated by: LCOV version 1.11