ROOT logo
/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

// $Id$
// $MpId$

#include "AliMpPCBPadIterator.h"

#include "AliMpArea.h"
#include "AliMpConstants.h"
#include "AliLog.h"
#include "AliMpPCB.h"
#include "AliMpSlat.h"
#include "AliMpSlatSegmentation.h"
#include "AliMpEncodePair.h"

#include "Riostream.h"
#include "TMath.h"


//-----------------------------------------------------------------------------
/// \class AliMpPCBPadIterator
/// 
/// Iterates over slat pads within a region of constant pad size.
/// 
/// \author Laurent Aphecetche
//-----------------------------------------------------------------------------

using std::cout;
using std::endl;
/// \cond CLASSIMP
ClassImp(AliMpPCBPadIterator)
/// \endcond

//_____________________________________________________________________________
AliMpPCBPadIterator::AliMpPCBPadIterator(const AliMpSlat* slat,
                                         const AliMpArea& area)
: AliMpVPadIterator(),
fkSlat(slat),
fSlatSegmentation(new AliMpSlatSegmentation(slat)),
fMinIndices(0),
fMaxIndices(0),
fOffset(0),
fCurrentPad(),
fIsDone(kTRUE)
{
  ///
  /// Normal ctor.
  /// Iteration will be done on the slat, over the crop of (area,slat_area)
  ///
  if (!CropArea(area)) 
  {
    AliError(Form("Could not crop area : (x,y)min=(%e,%e) ; max=(%e,%e) for slat %s",
                  area.LeftBorder(),area.DownBorder(),
                  area.RightBorder(),area.UpBorder(),fkSlat->GetID()));
  }
  Invalidate();
}

//_____________________________________________________________________________
AliMpPCBPadIterator::~AliMpPCBPadIterator()
{
  ///
  /// Dtor.
  ///
  delete fSlatSegmentation;
}

//_____________________________________________________________________________
Bool_t
AliMpPCBPadIterator::CropArea(const AliMpArea& area)
{
  ///
  /// Checks the area is correct, and truncate it
  /// if it goes outside the slat.
  
  AliDebug(3,Form("Input area (%7.2f,%7.2f)->(%7.2f,%7.2f)",
                  area.LeftBorder(),area.DownBorder(),
                  area.RightBorder(),area.UpBorder()));
  
  const Double_t kEpsilon = AliMpConstants::LengthTolerance();
  
  // Left and right x-limits have to come from first and last pcbs
  // to deal with short and rounded pcbs cases.
  AliMpPCB* first = fkSlat->FindPCB(area.LeftBorder(),area.DownBorder());
  AliMpPCB* last = fkSlat->FindPCB(area.RightBorder()-kEpsilon,
                                   area.DownBorder());
  
  // Check we're indeed dealing with only one pcb
  if ( first != last )
  {
    AliError("This iterator supposed to work on a single PCB. Please check");
    return kFALSE;
  }
  
  AliDebug(3,Form("PCB %s Ixmin %2d Ixmax %2d",
                  first->GetID(),first->Ixmin(),first->Ixmax()));
  
  Double_t xleft = first->ActiveXmin();
  Double_t xright = first->ActiveXmax() - kEpsilon;
  
  AliDebug(3,Form("xleft,xright=%e,%e",xleft,xright));
  
  Double_t xmin = TMath::Max(area.LeftBorder(),xleft);
  Double_t xmax = TMath::Min(area.RightBorder(),xright);
  Double_t ymin = TMath::Max(area.DownBorder(),0.0);
  Double_t ymax = TMath::Min(area.UpBorder(),first->DY()*2.0-kEpsilon);
  
  AliDebug(3,Form("Cropped area (%e,%e)->(%e,%e)",
                  xmin,ymin,xmax,ymax));
  
  // At this point (xmin,ymin)->(xmax,ymax) should be a zone completely included
  // inside the slat.
  // We now try to convert this into a couple of indices pair indicating the
  // region to iterate over, using integer values, not floating point ones.
  // For this, we must find out the 4 pads that intersect the (xmin,ymin;xmax,ymax)
  // area.
  
  Int_t ixmin = first->Ixmin() + TMath::FloorNint((xmin-first->ActiveXmin())/first->PadSizeX());
  Int_t ixmax = first->Ixmin() + TMath::CeilNint((xmax-first->ActiveXmin())/first->PadSizeX()) - 1;
  Int_t iymin = first->Iymin() + TMath::FloorNint((ymin-first->Ymin())/first->PadSizeY());
  Int_t iymax = first->Iymin() + TMath::CeilNint((ymax-first->Ymin())/first->PadSizeY()) - 1;
  
  
  fMinIndices = AliMp::Pair(ixmin,iymin);
  fMaxIndices = AliMp::Pair(ixmax,iymax);
  
  AliDebug(3,Form("Paddified cropped area (%d,%d)->(%d,%d) %d,%d ; %d,%d",
                  ixmin,iymin,ixmax,iymax,
                  AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
                  AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
  
  return fMinIndices >= 0 && fMaxIndices >= 0;
}

//_____________________________________________________________________________
AliMpPad
AliMpPCBPadIterator::CurrentItem() const
{
  ///
  /// Returns the current iteration position (i.e. a pad)
  ///
  return fCurrentPad;
}

//_____________________________________________________________________________
void
AliMpPCBPadIterator::First()
{
  ///
  /// (re)Starts the iteration.
  ///
  
  AliDebug(3,Form("area = (%d,%d)->(%d,%d)",
                  AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
                  AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
  fOffset = fMinIndices;
  fIsDone = kFALSE;
  SetPad(fCurrentPad,AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset));
  if ( ! fCurrentPad.IsValid() ) Next();
  if ( ! fCurrentPad.IsValid() ) 
  {
    // did not find any valid pad in there, bailing out.
    fIsDone = kTRUE;
    AliError(Form("Could not initiate iterator for slat %s. "
                  " Please check the area you gave : %d,%d to %d,%d",
                  fkSlat->GetName(),
                  AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
                  AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)));
    return;
  }
}

//_____________________________________________________________________________
Bool_t
AliMpPCBPadIterator::GetNextPosition(Int_t& ix, Int_t& iy) const
{
  /// Get the next iteration position. 
  /// On input, fOffset must be a valid position (i.e. within iteration
  /// area already).
  
  ++ix;
  
  if ( ix > AliMp::PairFirst(fMaxIndices) )
  {
    // Go back leftmost position...
    ix = AliMp::PairFirst(fMinIndices);
    // ... and up
    ++iy;
    if ( iy > AliMp::PairSecond(fMaxIndices) )
    {
      return false;
    }
  }
  return true;
}


//_____________________________________________________________________________
void
AliMpPCBPadIterator::Invalidate()
{
  ///
  /// Invalidate the iterator.
  ///
  fOffset = 0;
  fCurrentPad = AliMpPad::Invalid();
  fIsDone = kTRUE;
}

//_____________________________________________________________________________
Bool_t
AliMpPCBPadIterator::IsDone() const
{
  ///
  /// Whether the iteration is finished or not.
  ///
  return fIsDone;
}

//_____________________________________________________________________________
void
AliMpPCBPadIterator::Next()
{
  /// This one is the meat of the class.
  /// We're iterating in x-direction mainly, starting from 
  /// lower-left of the iteration area, and proceeding right,
  /// until we reach right border, in which case we increment y
  /// and go back to leftmost position.
  /// End of iteration occurs when both x and y are outside the iteration
  /// window.
  
  if (IsDone()) return;
  
  AliMpPad pad(fCurrentPad);
  int n = 0;
  Int_t ix(AliMp::PairFirst(fOffset));
  Int_t iy(AliMp::PairSecond(fOffset));
  
  while ( ( pad == fCurrentPad || ! pad.IsValid() ) && n<100 )
  {
    ++n;
    if (GetNextPosition(ix,iy)==kFALSE) 
    {
      Invalidate();
      return;
    } 
    SetPad(pad,ix,iy);
  }
  if ( n>=100 )
  {
    AliFatal("This should not happen!");
  }
  fCurrentPad = pad;
}

//_____________________________________________________________________________
void 
AliMpPCBPadIterator::Print(Option_t*) const
{
  /// printout
  cout << Form("fkSlat=%p fSlatSegmentation=%p (%s)",fkSlat,fSlatSegmentation,
               fkSlat->GetName()) << endl
  << Form("minIndices=(%d,%d) maxIndices=(%d,%d)",
          AliMp::PairFirst(fMinIndices),AliMp::PairSecond(fMinIndices),
          AliMp::PairFirst(fMaxIndices),AliMp::PairSecond(fMaxIndices)) << endl
  << Form("currentOffset=(%d,%d) isdone=%d currentpad=",
          AliMp::PairFirst(fOffset),AliMp::PairSecond(fOffset),fIsDone) << endl;
  fCurrentPad.Print();
}

//_____________________________________________________________________________
void
AliMpPCBPadIterator::SetPad(AliMpPad& pad, Int_t ix, Int_t iy)
{
  ///
  /// Sets the current pad.
  ///
  pad = fSlatSegmentation->PadByIndices(ix, iy,kFALSE);
  if (pad.IsValid())
  {
    fOffset = AliMp::Pair(ix,iy);
  }
}
 AliMpPCBPadIterator.cxx:1
 AliMpPCBPadIterator.cxx:2
 AliMpPCBPadIterator.cxx:3
 AliMpPCBPadIterator.cxx:4
 AliMpPCBPadIterator.cxx:5
 AliMpPCBPadIterator.cxx:6
 AliMpPCBPadIterator.cxx:7
 AliMpPCBPadIterator.cxx:8
 AliMpPCBPadIterator.cxx:9
 AliMpPCBPadIterator.cxx:10
 AliMpPCBPadIterator.cxx:11
 AliMpPCBPadIterator.cxx:12
 AliMpPCBPadIterator.cxx:13
 AliMpPCBPadIterator.cxx:14
 AliMpPCBPadIterator.cxx:15
 AliMpPCBPadIterator.cxx:16
 AliMpPCBPadIterator.cxx:17
 AliMpPCBPadIterator.cxx:18
 AliMpPCBPadIterator.cxx:19
 AliMpPCBPadIterator.cxx:20
 AliMpPCBPadIterator.cxx:21
 AliMpPCBPadIterator.cxx:22
 AliMpPCBPadIterator.cxx:23
 AliMpPCBPadIterator.cxx:24
 AliMpPCBPadIterator.cxx:25
 AliMpPCBPadIterator.cxx:26
 AliMpPCBPadIterator.cxx:27
 AliMpPCBPadIterator.cxx:28
 AliMpPCBPadIterator.cxx:29
 AliMpPCBPadIterator.cxx:30
 AliMpPCBPadIterator.cxx:31
 AliMpPCBPadIterator.cxx:32
 AliMpPCBPadIterator.cxx:33
 AliMpPCBPadIterator.cxx:34
 AliMpPCBPadIterator.cxx:35
 AliMpPCBPadIterator.cxx:36
 AliMpPCBPadIterator.cxx:37
 AliMpPCBPadIterator.cxx:38
 AliMpPCBPadIterator.cxx:39
 AliMpPCBPadIterator.cxx:40
 AliMpPCBPadIterator.cxx:41
 AliMpPCBPadIterator.cxx:42
 AliMpPCBPadIterator.cxx:43
 AliMpPCBPadIterator.cxx:44
 AliMpPCBPadIterator.cxx:45
 AliMpPCBPadIterator.cxx:46
 AliMpPCBPadIterator.cxx:47
 AliMpPCBPadIterator.cxx:48
 AliMpPCBPadIterator.cxx:49
 AliMpPCBPadIterator.cxx:50
 AliMpPCBPadIterator.cxx:51
 AliMpPCBPadIterator.cxx:52
 AliMpPCBPadIterator.cxx:53
 AliMpPCBPadIterator.cxx:54
 AliMpPCBPadIterator.cxx:55
 AliMpPCBPadIterator.cxx:56
 AliMpPCBPadIterator.cxx:57
 AliMpPCBPadIterator.cxx:58
 AliMpPCBPadIterator.cxx:59
 AliMpPCBPadIterator.cxx:60
 AliMpPCBPadIterator.cxx:61
 AliMpPCBPadIterator.cxx:62
 AliMpPCBPadIterator.cxx:63
 AliMpPCBPadIterator.cxx:64
 AliMpPCBPadIterator.cxx:65
 AliMpPCBPadIterator.cxx:66
 AliMpPCBPadIterator.cxx:67
 AliMpPCBPadIterator.cxx:68
 AliMpPCBPadIterator.cxx:69
 AliMpPCBPadIterator.cxx:70
 AliMpPCBPadIterator.cxx:71
 AliMpPCBPadIterator.cxx:72
 AliMpPCBPadIterator.cxx:73
 AliMpPCBPadIterator.cxx:74
 AliMpPCBPadIterator.cxx:75
 AliMpPCBPadIterator.cxx:76
 AliMpPCBPadIterator.cxx:77
 AliMpPCBPadIterator.cxx:78
 AliMpPCBPadIterator.cxx:79
 AliMpPCBPadIterator.cxx:80
 AliMpPCBPadIterator.cxx:81
 AliMpPCBPadIterator.cxx:82
 AliMpPCBPadIterator.cxx:83
 AliMpPCBPadIterator.cxx:84
 AliMpPCBPadIterator.cxx:85
 AliMpPCBPadIterator.cxx:86
 AliMpPCBPadIterator.cxx:87
 AliMpPCBPadIterator.cxx:88
 AliMpPCBPadIterator.cxx:89
 AliMpPCBPadIterator.cxx:90
 AliMpPCBPadIterator.cxx:91
 AliMpPCBPadIterator.cxx:92
 AliMpPCBPadIterator.cxx:93
 AliMpPCBPadIterator.cxx:94
 AliMpPCBPadIterator.cxx:95
 AliMpPCBPadIterator.cxx:96
 AliMpPCBPadIterator.cxx:97
 AliMpPCBPadIterator.cxx:98
 AliMpPCBPadIterator.cxx:99
 AliMpPCBPadIterator.cxx:100
 AliMpPCBPadIterator.cxx:101
 AliMpPCBPadIterator.cxx:102
 AliMpPCBPadIterator.cxx:103
 AliMpPCBPadIterator.cxx:104
 AliMpPCBPadIterator.cxx:105
 AliMpPCBPadIterator.cxx:106
 AliMpPCBPadIterator.cxx:107
 AliMpPCBPadIterator.cxx:108
 AliMpPCBPadIterator.cxx:109
 AliMpPCBPadIterator.cxx:110
 AliMpPCBPadIterator.cxx:111
 AliMpPCBPadIterator.cxx:112
 AliMpPCBPadIterator.cxx:113
 AliMpPCBPadIterator.cxx:114
 AliMpPCBPadIterator.cxx:115
 AliMpPCBPadIterator.cxx:116
 AliMpPCBPadIterator.cxx:117
 AliMpPCBPadIterator.cxx:118
 AliMpPCBPadIterator.cxx:119
 AliMpPCBPadIterator.cxx:120
 AliMpPCBPadIterator.cxx:121
 AliMpPCBPadIterator.cxx:122
 AliMpPCBPadIterator.cxx:123
 AliMpPCBPadIterator.cxx:124
 AliMpPCBPadIterator.cxx:125
 AliMpPCBPadIterator.cxx:126
 AliMpPCBPadIterator.cxx:127
 AliMpPCBPadIterator.cxx:128
 AliMpPCBPadIterator.cxx:129
 AliMpPCBPadIterator.cxx:130
 AliMpPCBPadIterator.cxx:131
 AliMpPCBPadIterator.cxx:132
 AliMpPCBPadIterator.cxx:133
 AliMpPCBPadIterator.cxx:134
 AliMpPCBPadIterator.cxx:135
 AliMpPCBPadIterator.cxx:136
 AliMpPCBPadIterator.cxx:137
 AliMpPCBPadIterator.cxx:138
 AliMpPCBPadIterator.cxx:139
 AliMpPCBPadIterator.cxx:140
 AliMpPCBPadIterator.cxx:141
 AliMpPCBPadIterator.cxx:142
 AliMpPCBPadIterator.cxx:143
 AliMpPCBPadIterator.cxx:144
 AliMpPCBPadIterator.cxx:145
 AliMpPCBPadIterator.cxx:146
 AliMpPCBPadIterator.cxx:147
 AliMpPCBPadIterator.cxx:148
 AliMpPCBPadIterator.cxx:149
 AliMpPCBPadIterator.cxx:150
 AliMpPCBPadIterator.cxx:151
 AliMpPCBPadIterator.cxx:152
 AliMpPCBPadIterator.cxx:153
 AliMpPCBPadIterator.cxx:154
 AliMpPCBPadIterator.cxx:155
 AliMpPCBPadIterator.cxx:156
 AliMpPCBPadIterator.cxx:157
 AliMpPCBPadIterator.cxx:158
 AliMpPCBPadIterator.cxx:159
 AliMpPCBPadIterator.cxx:160
 AliMpPCBPadIterator.cxx:161
 AliMpPCBPadIterator.cxx:162
 AliMpPCBPadIterator.cxx:163
 AliMpPCBPadIterator.cxx:164
 AliMpPCBPadIterator.cxx:165
 AliMpPCBPadIterator.cxx:166
 AliMpPCBPadIterator.cxx:167
 AliMpPCBPadIterator.cxx:168
 AliMpPCBPadIterator.cxx:169
 AliMpPCBPadIterator.cxx:170
 AliMpPCBPadIterator.cxx:171
 AliMpPCBPadIterator.cxx:172
 AliMpPCBPadIterator.cxx:173
 AliMpPCBPadIterator.cxx:174
 AliMpPCBPadIterator.cxx:175
 AliMpPCBPadIterator.cxx:176
 AliMpPCBPadIterator.cxx:177
 AliMpPCBPadIterator.cxx:178
 AliMpPCBPadIterator.cxx:179
 AliMpPCBPadIterator.cxx:180
 AliMpPCBPadIterator.cxx:181
 AliMpPCBPadIterator.cxx:182
 AliMpPCBPadIterator.cxx:183
 AliMpPCBPadIterator.cxx:184
 AliMpPCBPadIterator.cxx:185
 AliMpPCBPadIterator.cxx:186
 AliMpPCBPadIterator.cxx:187
 AliMpPCBPadIterator.cxx:188
 AliMpPCBPadIterator.cxx:189
 AliMpPCBPadIterator.cxx:190
 AliMpPCBPadIterator.cxx:191
 AliMpPCBPadIterator.cxx:192
 AliMpPCBPadIterator.cxx:193
 AliMpPCBPadIterator.cxx:194
 AliMpPCBPadIterator.cxx:195
 AliMpPCBPadIterator.cxx:196
 AliMpPCBPadIterator.cxx:197
 AliMpPCBPadIterator.cxx:198
 AliMpPCBPadIterator.cxx:199
 AliMpPCBPadIterator.cxx:200
 AliMpPCBPadIterator.cxx:201
 AliMpPCBPadIterator.cxx:202
 AliMpPCBPadIterator.cxx:203
 AliMpPCBPadIterator.cxx:204
 AliMpPCBPadIterator.cxx:205
 AliMpPCBPadIterator.cxx:206
 AliMpPCBPadIterator.cxx:207
 AliMpPCBPadIterator.cxx:208
 AliMpPCBPadIterator.cxx:209
 AliMpPCBPadIterator.cxx:210
 AliMpPCBPadIterator.cxx:211
 AliMpPCBPadIterator.cxx:212
 AliMpPCBPadIterator.cxx:213
 AliMpPCBPadIterator.cxx:214
 AliMpPCBPadIterator.cxx:215
 AliMpPCBPadIterator.cxx:216
 AliMpPCBPadIterator.cxx:217
 AliMpPCBPadIterator.cxx:218
 AliMpPCBPadIterator.cxx:219
 AliMpPCBPadIterator.cxx:220
 AliMpPCBPadIterator.cxx:221
 AliMpPCBPadIterator.cxx:222
 AliMpPCBPadIterator.cxx:223
 AliMpPCBPadIterator.cxx:224
 AliMpPCBPadIterator.cxx:225
 AliMpPCBPadIterator.cxx:226
 AliMpPCBPadIterator.cxx:227
 AliMpPCBPadIterator.cxx:228
 AliMpPCBPadIterator.cxx:229
 AliMpPCBPadIterator.cxx:230
 AliMpPCBPadIterator.cxx:231
 AliMpPCBPadIterator.cxx:232
 AliMpPCBPadIterator.cxx:233
 AliMpPCBPadIterator.cxx:234
 AliMpPCBPadIterator.cxx:235
 AliMpPCBPadIterator.cxx:236
 AliMpPCBPadIterator.cxx:237
 AliMpPCBPadIterator.cxx:238
 AliMpPCBPadIterator.cxx:239
 AliMpPCBPadIterator.cxx:240
 AliMpPCBPadIterator.cxx:241
 AliMpPCBPadIterator.cxx:242
 AliMpPCBPadIterator.cxx:243
 AliMpPCBPadIterator.cxx:244
 AliMpPCBPadIterator.cxx:245
 AliMpPCBPadIterator.cxx:246
 AliMpPCBPadIterator.cxx:247
 AliMpPCBPadIterator.cxx:248
 AliMpPCBPadIterator.cxx:249
 AliMpPCBPadIterator.cxx:250
 AliMpPCBPadIterator.cxx:251
 AliMpPCBPadIterator.cxx:252
 AliMpPCBPadIterator.cxx:253
 AliMpPCBPadIterator.cxx:254
 AliMpPCBPadIterator.cxx:255
 AliMpPCBPadIterator.cxx:256
 AliMpPCBPadIterator.cxx:257
 AliMpPCBPadIterator.cxx:258
 AliMpPCBPadIterator.cxx:259
 AliMpPCBPadIterator.cxx:260
 AliMpPCBPadIterator.cxx:261
 AliMpPCBPadIterator.cxx:262
 AliMpPCBPadIterator.cxx:263
 AliMpPCBPadIterator.cxx:264
 AliMpPCBPadIterator.cxx:265
 AliMpPCBPadIterator.cxx:266
 AliMpPCBPadIterator.cxx:267
 AliMpPCBPadIterator.cxx:268
 AliMpPCBPadIterator.cxx:269
 AliMpPCBPadIterator.cxx:270
 AliMpPCBPadIterator.cxx:271
 AliMpPCBPadIterator.cxx:272
 AliMpPCBPadIterator.cxx:273
 AliMpPCBPadIterator.cxx:274
 AliMpPCBPadIterator.cxx:275
 AliMpPCBPadIterator.cxx:276
 AliMpPCBPadIterator.cxx:277
 AliMpPCBPadIterator.cxx:278
 AliMpPCBPadIterator.cxx:279
 AliMpPCBPadIterator.cxx:280
 AliMpPCBPadIterator.cxx:281
 AliMpPCBPadIterator.cxx:282
 AliMpPCBPadIterator.cxx:283
 AliMpPCBPadIterator.cxx:284
 AliMpPCBPadIterator.cxx:285
 AliMpPCBPadIterator.cxx:286
 AliMpPCBPadIterator.cxx:287
 AliMpPCBPadIterator.cxx:288
 AliMpPCBPadIterator.cxx:289
 AliMpPCBPadIterator.cxx:290
 AliMpPCBPadIterator.cxx:291
 AliMpPCBPadIterator.cxx:292
 AliMpPCBPadIterator.cxx:293
 AliMpPCBPadIterator.cxx:294
 AliMpPCBPadIterator.cxx:295
 AliMpPCBPadIterator.cxx:296