1 #include "gearimpl/RectangularPadRowLayout.h"
38 _repeatRows = right._repeatRows;
40 _extent = right._extent;
41 _nRows = right._nRows;
47 _padIndices.resize( _nRow ) ;
48 for (std::vector< std::vector<int>* >::iterator rowIter = _padIndices.begin() ;
49 rowIter < _padIndices.end(); rowIter++)
61 double rowHeight ,
double leftOffset,
62 double rightOffset ) {
68 assert( ! ( padWidth < 0. ) ) ;
69 assert( ! ( padHeight < 0. ) ) ;
70 assert( ! ( rowHeight < 0. ) ) ;
71 assert( ! ( leftOffset < 0. ) ) ;
72 assert( ! ( rightOffset < 0. ) ) ;
75 double xMin = _extent[0] + leftOffset ;
76 double xMax = _extent[1] - rightOffset ;
78 double rowWidth = xMax - xMin ;
80 if( nPad * padWidth > rowWidth ) {
82 std::stringstream sstr ;
83 sstr <<
"RectangularPadRowLayout::addRow: can't fit "
84 << nPad <<
" pads in row with width " << rowWidth
85 <<
" ( offsets left/right: " << leftOffset <<
" / " << rightOffset <<
" ) " ;
92 _nPad += abs( nRow ) * abs( nPad ) ;
94 row.WidthPerPad = rowWidth / nPad ;
96 if( rowHeight == 0.0 )
97 rowHeight = padHeight ;
99 if( rowHeight < padHeight ){
101 std::stringstream sstr ;
102 sstr <<
"RectangularPadRowLayout::addRow: row height ( "
103 << rowHeight <<
" ) can't be smaller than pad height ( " << padHeight <<
" ) !" ;
110 row.PadWidth = padWidth ;
111 row.PadHeight = padHeight ;
113 row.Height = rowHeight ;
115 row.LeftOffset = leftOffset ;
116 row.RightOffset = rightOffset ;
119 for(
int i = 0 ; i < nRow ; i++ ) {
121 row.Center = _extent[3] + rowHeight / 2. ;
123 _extent[3]+= rowHeight ;
125 _rows.push_back( row ) ;
127 _padIndices.push_back( 0 ) ;
130 _nRows.push_back( nRow ) ;
136 if( _repeatRows > 0 )
139 _repeatRows = count ;
141 int nRow = _rows.size() ;
143 for(
unsigned i=0 ; i< count-1 ; ++i ){
144 for(
int j=0 ; j< nRow; ++j ){
146 const Row& r = _rows[j] ;
148 addRow( 1 , r.NPad , r.PadWidth ,r.PadHeight ,
149 r.Height , r.LeftOffset, r.RightOffset ) ;
156 return _rows.size() ;
160 return _rows.at(rowNumber).Height ;
167 return _rows[rowNum].PadHeight ;
175 return _rows[rowNum].PadWidth ;
182 return _rows[rowNum].WidthPerPad ;
191 const Row& row = _rows[ rowNum ] ;
193 double x = _extent[0] + row.LeftOffset + padNum * row.WidthPerPad + row.WidthPerPad / 2. ;
195 double y = row.Center ;
222 for(
unsigned i=0; i<_padIndices.size(); ++i ){
223 delete _padIndices[i] ;
229 static std::vector<int> empty ;
233 if( _padIndices.at(rowNumber ) == 0 ) {
235 int nPad = _rows.at(rowNumber).NPad ;
237 _padIndices[ rowNumber ] =
new std::vector<int>( nPad ) ;
239 for(
int i = 0 ; i < nPad ; i++){
241 _padIndices[rowNumber]->operator[](i) =
getPadIndex( rowNumber , i ) ;
245 }
catch( std::out_of_range& r) {
252 return *_padIndices[ rowNumber ] ;
258 int rn = ( 0xffff0000 & padIndex ) >> 16 ;
260 if( rn < 0 || rn >
int(_rows.size() - 1) ){
262 std::stringstream sstr ;
264 sstr <<
"RectangularPadRowLayout::getRowNumber: illegal rownumber: "
265 << rn <<
" for padIndex 0x" << std::hex << padIndex <<
" nRows: " << _rows.size() << std::dec ;
277 if( (
unsigned) rowNum > _rows.size() - 1 ) {
279 throw std::out_of_range(
" RectangularPadRowLayout::getPadIndex row number too large !");
282 if( padNum > _rows[rowNum].NPad - 1 ) {
284 std::stringstream sstr ;
286 sstr <<
"RectangularPadRowLayout::getPadIndex: pad number too large: "
287 << padNum <<
" only " << _rows[rowNum].NPad <<
" pads in row " << rowNum ;
289 throw std::out_of_range( sstr.str() );
292 return (rowNum << 16 ) | ( 0x0000ffff & padNum ) ;
296 int RectangularPadRowLayout::getNearestPadOld(
double x,
double y)
const {
299 if( x < _extent[0] ) x = _extent[0] ;
300 if( x > _extent[1] ) x = _extent[1] ;
301 if( y < _extent[2] ) y = _extent[2] ;
302 if( y > _extent[3] ) y = _extent[3] ;
306 double dMin = 2. * ( _extent[3] - _extent[2] ) ;
311 for(
unsigned i=0 ; i < _rows.size() ; ++i ) {
313 const Row& row = _rows[i] ;
315 double xmin = _extent[0] + row.LeftOffset ;
316 double xmax = _extent[1] - row.RightOffset ;
317 double ymin = row.Center - row.PadHeight / 2. ;
318 double ymax = row.Center + row.PadHeight / 2. ;
324 if( ( d =
distanceToBox( p , xmin, ymin, xmax, ymax ) ) < dMin ){
330 if( dMin < 0.0 ) break ;
337 const Row& row = _rows[rowNum] ;
339 if( x < ( _extent[0] + row.LeftOffset ) ){
343 }
else if( x >= ( _extent[1] - row.RightOffset ) ) {
345 padNum = row.NPad - 1 ;
349 padNum = (int) ( ( x - ( _extent[0] + row.LeftOffset ) ) / row.WidthPerPad ) ;
360 if( x < _extent[0] ) x = _extent[0] ;
361 if( x > _extent[1] ) x = _extent[1] ;
362 if( y < _extent[2] ) y = _extent[2] ;
363 if( y > _extent[3] ) y = _extent[3] ;
366 int row_number = (int)( round( (_rows.size() - 1) * (y - _extent[2]) / (_extent[3] - _extent[2]) ) );
371 const Row &row = _rows[row_number];
372 const double y_displacement = y - row.Center;
376 if( fabs(y_displacement) <= (row.PadHeight/2) ) {
381 else if( fabs(y_displacement) <= (row.Height/2) ) {
384 const int next_row_number = (y_displacement < 0)? row_number - 1: row_number + 1;
385 const Row &next_row = _rows[next_row_number];
387 const double y_distance_from_pads = fabs(y_displacement) - (row.PadHeight/2);
388 const double y_distance_from_next_pads = fabs(y - next_row.Center) - (next_row.PadHeight/2);
390 row_number = (y_distance_from_next_pads < y_distance_from_pads)? next_row_number: row_number;
396 double remaining_distance;
399 if( y_displacement < 0 ) {
401 remaining_rows = row_number;
402 remaining_distance = row.Center - _extent[2] - (row.Height/2.);
403 offset = y_displacement + (row.Height/2);
407 remaining_rows = _rows.size() - row_number - 1;
408 remaining_distance = _extent[3] - row.Center - (row.Height/2.);
409 offset = y_displacement - (row.Height/2);
412 const double param = remaining_rows * (offset / remaining_distance);
413 const int delta_row = (int)((param < 0)? floor(param): ceil(param));
420 std::cout <<
"delta_row is 0, breaking loop" << std::endl;
424 row_number += delta_row;
435 const Row& row = _rows[row_number] ;
437 if( x <= ( _extent[0] + row.LeftOffset ) ) {
441 }
else if( x >= ( _extent[1] - row.RightOffset ) ) {
443 pad_number = row.NPad - 1;
447 pad_number = (int) ( ( x - ( _extent[0] + row.LeftOffset ) ) / row.WidthPerPad ) ;
460 int nPad = _rows.at(rn).NPad ;
463 throw Exception(
"RectangularPadRowLayout::getRightNeighbour: no right neighbour pad !");
477 throw Exception(
"RectangularPadRowLayout::getLeftNeighbour: no left neighbour pad !");
490 const Row& row = _rows[rn] ;
493 double pXMin = _extent[0] + row.LeftOffset + pn * row.WidthPerPad + ( row.WidthPerPad - row.PadWidth )/ 2.;
494 double pXMax = _extent[0] + row.LeftOffset + (pn+1) * row.WidthPerPad - ( row.WidthPerPad - row.PadWidth )/ 2.;
495 double pYMin = row.Center - row.PadHeight / 2. ;
496 double pYMax = row.Center + row.PadHeight / 2. ;
498 return ( pXMin <= x && x <= pXMax &&
499 pYMin <= y && y <= pYMax ) ;
505 if( x < _extent[0] || x > _extent[1] ||
506 y < _extent[2] || y > _extent[3] )
514 double xmin,
double ymin,
515 double xmax,
double ymax )
const {
536 d = sqrt( (xmin-x) * (xmin-x) + (ymin-y) * (ymin-y) ) ;
538 }
else if ( y > ymax ) {
540 d = sqrt( (xmin-x) * (xmin-x) + (ymax-y) * (ymax-y) ) ;
547 }
else if( x > xmax ) {
551 d = sqrt( (xmax-x) * (xmax-x) + (ymin-y) * (ymin-y) ) ;
553 }
else if ( y > ymax ) {
555 d = sqrt( (xmax-x) * (xmax-x) + (ymax-y) * (ymax-y) ) ;
568 }
else if ( y > ymax ) {
590 testCoordinates[0]=c0; testCoordinates[1]=c1;
592 double distance =
distanceToBox( testCoordinates, padCentre[0] - padWidth*0.5,
593 padCentre[1] - padHeight*0.5,
594 padCentre[0] + padWidth*0.5,
595 padCentre[1] + padHeight*0.5);
597 return (distance < 0. ? 0. : distance);
double distanceToBox(const Vector2D &p, double xMin, double yMin, double xMax, double yMax) const
Helper function for finding the nearest pad - returns the distance for points outside the box and -1...
virtual double getDistanceToPad(double c0, double c1, int padIndex) const
Returns the closest distance to the edge (outer border) of the pad.
virtual int getRowNumber(int padIndex) const
The number of the row that contains the pad at padIndex - numbering starts at y==0 (bottom)...
Abstract description of a planar subdetector with pads (cells) that are positioned in rows (circular ...
virtual double getPadPitch(int padIndex) const
The pitch (i.
Base exception class for GEAR - all other exceptions extend this.
virtual int getNearestPad(double x, double y) const
The index of the pad nearest to the given point in 2d coordinates (x,y,) or (r,phi).
PadRowLayout2D * clone() const
Returns a copy (clone) of this class.
virtual int getPadIndex(int rowNum, int padNum) const
Create a padIndex for the given row and pad ( column ) number.
virtual ~RectangularPadRowLayout()
Destructor.
virtual const std::vector< int > & getPadsInRow(int rowNumber) const
Indices of all pads in row rowNumber (row indices start from 0 at the bottom (CARTESIAN) or at the ce...
virtual double getPadWidth(int padIndex) const
The width of the pad at padIndex in mm.
virtual Vector2D getPadCenter(int padIndex) const
The center of the pad in 2d coordinates, (x,y) or (r,phi).
RectangularPadRowLayout(double xMin, double xMax, double yMin=0.0)
Construct the empty RectangularPadRowLayout with the width and x position specified through xMin and ...
virtual void addRow(int nRow, int nPad, double padWidth, double padHeight, double rowHeight=0.0, double leftOffset=0.0, double rightOffset=0.0)
Add nRow rows with the given parameters.
virtual int getPadNumber(int padIndex) const
The pad number (column) within the row - numbering starts at x==0 (left).
RectangularPadRowLayout & operator=(const RectangularPadRowLayout &)
The assignment operator.
virtual double getRowHeight(int rowNumber) const
The row height in mm.
virtual bool isInsidePad(double x, double y, int padIndex) const
True if coordinate (x,y) is within the given pad.
void cleanup()
function to delete all the objects pointed to and owned by the GearMgr.
virtual int getRightNeighbour(int padIndex) const
The index of the right neighbour pad.
virtual double getPadHeight(int padIndex) const
The height of the pad in mm.
void copy_and_assign(const RectangularPadRowLayout &)
function to copy all internal variables, incl.
virtual int getPadLayoutType() const
virtual void repeatRows(unsigned count)
Repeat the current rows 'count' times - this allows to easily repeat a pattern of several rows...
virtual int getLeftNeighbour(int padIndex) const
The index of the left neighbour pad.
virtual int getCoordinateType() const
The type of the row layouts coordinate system: PadRowLayout2D.CARTESIAN.
Implementation of PadRowLayout2D for a rectangular row based layout where all pads in a given row are...
Internal helper class for RectangularPadRowLayout.
virtual int getNRows() const
The number of rows.