| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

MuonLayout.cpp

Go to the documentation of this file.
00001 // $Id: MuonLayout.cpp,v 1.1 2005/12/02 16:28:07 cattanem Exp $
00002 // Include files
00003 #include <iostream>
00004 #include <algorithm>
00005 #include <numeric>
00006 #include "Kernel/MuonLayout.h"
00007 #include "Kernel/MuonTileID.h"
00008 
00009 //------------------------------------------------------------------------------
00010 //
00012 //
00014 //
00015 //------------------------------------------------------------------------------
00016 
00017 MuonLayout::MuonLayout() {      
00018     m_xgrid = 0;
00019     m_ygrid = 0;        
00020 }
00021 
00022 MuonLayout::MuonLayout(unsigned int x, unsigned int y) {
00023     m_xgrid = x;
00024     m_ygrid = y;       
00025 }
00026 
00027 MuonLayout::MuonLayout(std::pair<unsigned int, unsigned int> grid) {    
00028     m_xgrid = grid.first;
00029     m_ygrid = grid.second;       
00030 }
00031 
00032 MuonLayout::~MuonLayout() {} 
00033 
00034 int MuonLayout::region(unsigned int ix, unsigned int iy) const {
00035 
00036   int nrx;
00037   if ( ix/m_xgrid < 1 ) {
00038     nrx = -1;
00039   } else if ( ix/m_xgrid == 1 ) {
00040     nrx = 0;
00041   } else if ( ix/m_xgrid <= 3 ) {
00042     nrx = 1;  
00043   } else if ( ix/m_xgrid <= 7 ) {
00044     nrx = 2;    
00045   } else {
00046     nrx = 3;    
00047   }
00048   int nry;
00049   if ( iy/m_ygrid < 1 ) {
00050     nry = -1;
00051   } else if ( iy/m_ygrid == 1 ) {
00052     nry = 0;
00053   } else if ( iy/m_ygrid <= 3 ) {
00054     nry = 1;  
00055   } else if ( iy/m_ygrid <= 7 ) {
00056     nry = 2;    
00057   } else {
00058     nry = 3;    
00059   }     
00060   return std::max(nrx,nry);
00061     
00062 }
00063 
00064 std::vector<LHCb::MuonTileID> 
00065 MuonLayout::tiles(const LHCb::MuonTileID& pad) const {
00066   return tilesInArea(pad,0,0);
00067 }
00068 
00069 std::vector<LHCb::MuonTileID> 
00070 MuonLayout::tilesInArea(const LHCb::MuonTileID& pad, int areaX, int areaY) const
00071 {
00072 //  This function returns all the MuonTileID's touched by the "pad"
00073 //  defined with the "playout" MuonLayout +- areaX and +- areaY.
00074 //  The areaX and areaY are defined in terms of this layout.
00075 
00076   MuonLayout playout = pad.layout();
00077   std::vector<LHCb::MuonTileID> vmt;
00078   
00079   if( ! isDefined() ) return vmt;
00080 
00081   int quarter = pad.quarter();
00082   int nreg = pad.region();
00083   int sta = pad.station();
00084 
00085    //std::cout << quarter << " " << nreg << " " << rfactor(nreg) << std::endl;  
00086    //std::cout << m_xgrid << m_ygrid << endl;           
00087    //cout << playout.xGrid() << playout.yGrid() << endl;        
00088 
00089   // the finest grid of the two layouts
00090   int mxgrid = std::max(m_xgrid, playout.xGrid() );
00091   int mygrid = std::max(m_ygrid, playout.yGrid() );
00092 
00093 //   std::cout << mxgrid << mygrid << std::endl;            
00094 
00095   MuonLayout fineGrid(mxgrid,mygrid);
00096 
00097   int xratio = m_xgrid/playout.xGrid();
00098   int yratio = m_ygrid/playout.yGrid();
00099 
00100   xratio = (xratio == 0) ? 1 : xratio ;
00101   yratio = (yratio == 0) ? 1 : yratio ;
00102 
00103   // input pad area in terms of the finest grid
00104 //   int maxX = (pad.nX()+areaX+1)*playout.rfactor(nreg)*xratio-1;
00105 //   int maxY = (pad.nY()+areaY+1)*playout.rfactor(nreg)*yratio-1;
00106 //   int minX = maxX - playout.rfactor(nreg)*xratio*(2*areaX+1) + 1;
00107 //   int minY = maxY - playout.rfactor(nreg)*yratio*(2*areaY+1) + 1;
00108   // input pad area in terms of the finest grid and smallest region  
00109   int maxX = (pad.nX()+1)*rfactor(nreg)*xratio+areaX*rfactor(nreg)-1;
00110   int maxY = (pad.nY()+1)*rfactor(nreg)*yratio+areaY*rfactor(nreg)-1;
00111   int minX = maxX - rfactor(nreg)*xratio - 2*areaX*rfactor(nreg) + 1;
00112   int minY = maxY - rfactor(nreg)*yratio - 2*areaY*rfactor(nreg) + 1;
00113   
00114   minX = std::max(0,minX);
00115   minY = std::max(0,minY);
00116 
00117   // Which tiles are hit ?
00118 
00119   xratio = mxgrid/m_xgrid;
00120   yratio = mygrid/m_ygrid;
00121   
00122   int ix = minX;
00123   int iy = minY;
00124   bool regleap = false;
00125   int nr = 0;
00126   int nrx = 0;
00127 
00128   while ( ix <= maxX ) {
00129     nrx = fineGrid.region(ix,iy);
00130     if( nrx == -1 ) nrx = 0;
00131     if( nrx > 3 ) break;
00132     while ( iy <= maxY ) {
00133       // which region   
00134       nr = fineGrid.region(ix,iy);
00135       if( nr == -1 ) nr = 0;
00136       if( nr > 3 ) break;                    
00137       if(nr == nrx || !regleap) {
00138         unsigned int newx = ix/rfactor(nr)/xratio;        
00139         unsigned int newy = iy/rfactor(nr)/yratio;
00140         if(newy < 2*yGrid() && newx < 2*xGrid()) {
00141     LHCb::MuonTileID newtile(sta,*this,nr,quarter,newx,newy); 
00142           if(newtile.isValid()) {
00143             vmt.push_back(newtile);
00144           } 
00145         }   
00146       }         
00147       iy += rfactor(nr)*yratio;
00148     }   
00149     if(regleap) {
00150       regleap = false;
00151     } else if (nr != nrx) {
00152       regleap = true;   
00153     } 
00154     iy = minY;
00155     ix += rfactor(nrx)*xratio;
00156   }    
00157   return vmt;
00158 }
00159 
00160 std::vector<LHCb::MuonTileID> MuonLayout::tiles() const {
00161   
00162   std::vector<LHCb::MuonTileID> vmt;
00163   std::vector<LHCb::MuonTileID> vmtr;
00164   
00165   if( ! isDefined() ) return vmt;
00166   
00167   for(int iq = 0; iq <4; iq++) {
00168     for(int ir = 0; ir <4; ir++) {
00169       vmtr = tiles(iq,ir);
00170       vmt.insert(vmt.end(),vmtr.begin(),vmtr.end());
00171     }
00172   }
00173   
00174   return vmt;
00175   
00176 }
00177 
00178 std::vector<LHCb::MuonTileID> MuonLayout::tiles(int iq) const {
00179   
00180   std::vector<LHCb::MuonTileID> vmt;
00181   std::vector<LHCb::MuonTileID> vmtr;
00182   
00183   if( ! isDefined() ) return vmt;
00184     
00185   for(int ir = 0; ir <4; ir++) {
00186     vmtr = tiles(iq,ir);
00187     vmt.insert(vmt.end(),vmtr.begin(),vmtr.end());
00188   }
00189   
00190   return vmt;
00191   
00192 }
00193 
00194 std::vector<LHCb::MuonTileID> MuonLayout::tiles(int iq, int ir) const {
00195 
00196   std::vector<LHCb::MuonTileID> vmt;
00197   if( ! isDefined() ) return vmt;
00198   
00199   vmt.reserve(xGrid()*yGrid()*3);
00200   
00201   LHCb::MuonTileID newpad;
00202   
00203   unsigned int ix; unsigned int iy;
00204   for(ix = 0; ix < 2*xGrid(); ix++) {
00205     for(iy = yGrid(); iy < 2*yGrid(); iy++) {
00206       vmt.push_back(LHCb::MuonTileID(0,*this,ir,iq,ix,iy));
00207     }
00208   }
00209   for(ix = xGrid(); ix < 2*xGrid(); ix++) {
00210     for(iy = 0; iy < yGrid(); iy++) {
00211       vmt.push_back(LHCb::MuonTileID(0,*this,ir,iq,ix,iy));
00212     }
00213   }
00214   return vmt; 
00215 }
00216 
00217 std::vector<LHCb::MuonTileID> 
00218 MuonLayout::tilesInRegion(const LHCb::MuonTileID& pad, int pregion) const{
00219                                                 
00220   std::vector<LHCb::MuonTileID> vmt;
00221   if( ! isDefined() ) return vmt;                                               
00222     
00223   int nr = pad.region();
00224   int nq = pad.quarter();
00225   int sta = pad.station();
00226   
00227   if(nr == pregion) {
00228     return tiles(pad);    
00229   } else {
00230     vmt = tiles(pad); 
00231     std::vector<LHCb::MuonTileID>::iterator ivmt;
00232     std::vector<LHCb::MuonTileID> nvmt;
00233     // Bring the pads in vmt to the pregion definition
00234     for (ivmt = vmt.begin(); ivmt != vmt.end(); ivmt++) {      
00235       if(nr<pregion) {
00236         int factor = rfactor(pregion)/rfactor(nr);
00237         int newX = ivmt->nX()/factor;
00238         int newY = ivmt->nY()/factor;
00239         LHCb::MuonTileID tile(sta,*this,pregion,nq,newX,newY);
00240         nvmt.push_back(tile);
00241       } else {
00242         int factor = rfactor(nr)/rfactor(pregion);
00243         int minX = ivmt->nX()*factor;
00244         int minY = ivmt->nY()*factor;
00245         for(int ix=0; ix<factor; ix++) {
00246           for(int iy=0; iy<factor; iy++) {
00247             LHCb::MuonTileID tile(sta,*this,pregion,nq,minX+ix,minY+iy);
00248             nvmt.push_back(tile);
00249           }
00250         }
00251       }
00252     }
00253     return nvmt;
00254   }
00255 }
00256 
00257 std::vector<LHCb::MuonTileID> 
00258 MuonLayout::neighbours(const LHCb::MuonTileID& pad) const {
00259 
00260   // This function returns all the neighbours within unity depth
00261   std::vector<LHCb::MuonTileID> result;
00262   std::vector<LHCb::MuonTileID> vmt;
00263   vmt = neighbours(pad,MuonBase::RIGHT,MuonBase::DOWN);
00264   result.insert(result.end(),vmt.begin(),vmt.end());
00265   vmt = neighbours(pad,MuonBase::RIGHT,MuonBase::CENTER);
00266   result.insert(result.end(),vmt.begin(),vmt.end());    
00267   vmt = neighbours(pad,MuonBase::RIGHT,MuonBase::UP);
00268   result.insert(result.end(),vmt.begin(),vmt.end());
00269   vmt = neighbours(pad,MuonBase::LEFT,MuonBase::DOWN);
00270   result.insert(result.end(),vmt.begin(),vmt.end());
00271   vmt = neighbours(pad,MuonBase::LEFT,MuonBase::CENTER);
00272   result.insert(result.end(),vmt.begin(),vmt.end());    
00273   vmt = neighbours(pad,MuonBase::LEFT,MuonBase::UP);
00274   result.insert(result.end(),vmt.begin(),vmt.end());    
00275   vmt = neighbours(pad,MuonBase::CENTER,MuonBase::UP);
00276   result.insert(result.end(),vmt.begin(),vmt.end());    
00277   vmt = neighbours(pad,MuonBase::CENTER,MuonBase::DOWN);
00278   result.insert(result.end(),vmt.begin(),vmt.end());
00279   return result;                             
00280 }
00281 
00282 std::vector<LHCb::MuonTileID> 
00283 MuonLayout::neighbours(const LHCb::MuonTileID& pad, int dirX, int dirY ) const {
00284                                                
00285 //  This function returns all the MuonTileID's which are neighbours
00286 //  of the given pad in the direction indicated by dirX and dirY and 
00287 //  defined in terms of this layout. 
00288 
00289   unsigned int nreg = pad.region();
00290   std::vector<LHCb::MuonTileID> vtm = neighbours(pad,dirX,dirY,1);
00291   // if no neigbours at all
00292   if(vtm.empty()) return vtm;
00293   // if the neigbours are all in the same region or the neighboring 
00294   // region is larger than the pad's one
00295   if(vtm[0].region() >= nreg) return vtm;
00296   // if there is only one neighbour
00297   if(vtm.size() == 1) return vtm;
00298   
00299   // We have got to the smaller region
00300   nreg = vtm[0].region();
00301   std::vector<LHCb::MuonTileID> xvtm,result;
00302   std::vector<LHCb::MuonTileID>::iterator ivtm;
00303   // Find the limits of the returned pad's area
00304   unsigned int minx=9999;
00305   unsigned int maxx=0;
00306   unsigned int miny=9999;
00307   unsigned int maxy=0;
00308   for ( ivtm = vtm.begin(); ivtm != vtm.end(); ivtm++) {
00309     if( (*ivtm).nY() > maxy ) maxy = (*ivtm).nY();
00310     if( (*ivtm).nX() > maxx ) maxx = (*ivtm).nX();
00311     if( (*ivtm).nY() < miny ) miny = (*ivtm).nY();
00312     if( (*ivtm).nX() < minx ) minx = (*ivtm).nX();
00313   }
00314   
00315   // perform the check in the X direction first
00316   if ( dirX == MuonBase::LEFT ) {
00317     for ( ivtm = vtm.begin(); ivtm != vtm.end(); ivtm++) {
00318       if( (*ivtm).nX() == maxx ) {
00319         xvtm.push_back(*ivtm);
00320       }
00321     }
00322   } else if ( dirX == MuonBase::RIGHT ) {
00323     for ( ivtm = vtm.begin(); ivtm != vtm.end(); ivtm++) {
00324       if( (*ivtm).nX() == minx ) {
00325         xvtm.push_back(*ivtm);
00326       }
00327     }  
00328   } else {
00329     for ( ivtm = vtm.begin(); ivtm != vtm.end(); ivtm++) {
00330       xvtm.push_back(*ivtm);
00331     } 
00332   }
00333     
00334   // check in the Y direction with the pads that are left 
00335   if ( dirY == MuonBase::DOWN ) {
00336     for ( ivtm = xvtm.begin(); ivtm != xvtm.end(); ivtm++) {
00337       if( (*ivtm).nY() == maxy ) {
00338         result.push_back(*ivtm);
00339       }
00340     }
00341   } else if ( dirY == MuonBase::UP ) {
00342     for ( ivtm = xvtm.begin(); ivtm != xvtm.end(); ivtm++) {
00343       if( (*ivtm).nY() == miny ) {
00344         result.push_back(*ivtm);
00345       }
00346     }  
00347   } else {
00348     for ( ivtm = xvtm.begin(); ivtm != xvtm.end(); ivtm++) {
00349       result.push_back(*ivtm);
00350     } 
00351   }
00352   return result;                                                                               
00353 }
00354 
00355 std::vector<LHCb::MuonTileID> 
00356 MuonLayout::neighbours(const LHCb::MuonTileID& pad, int dirX, int dirY,
00357                                                                                   int depth) const {
00358                                                
00359 //  This function returns all the MuonTileID's touched by the area
00360 //  situated in the direction indicated by dirX and dirY and defined
00361 //  in terms of this layout. The depth of the area is defined by
00362 //  the depth parameter
00363 
00364   return neighboursInArea(pad,dirX,dirY,depth,depth);
00365                                                
00366 }
00367 
00368 //========================================================================
00369 std::vector<LHCb::MuonTileID> 
00370 MuonLayout::neighboursInArea(const LHCb::MuonTileID& pad, int dirX, int dirY,
00371                                                                                   int depthX, int depthY) const {
00372                                                
00373 //  This function returns all the MuonTileID's touched by the area
00374 //  situated in the direction indicated by dirX and dirY and defined
00375 //  in terms of this layout. The depth of the area is defined by
00376 //  the depthX and depthY parameters. It is identical to the neighbours()
00377 //  apart from the corner neighbours.
00378 
00379 
00380   MuonLayout playout = pad.layout();
00381   std::vector<LHCb::MuonTileID> vmt;
00382   
00383   if ( ! isDefined() ) return vmt;
00384 
00385   int quarter = pad.quarter();
00386   int nreg    = pad.region();
00387   int sta     = pad.station();
00388 
00389   // the finest grid of the two layouts
00390   int mxgrid = std::max(m_xgrid, playout.xGrid() );
00391   int mygrid = std::max(m_ygrid, playout.yGrid() );
00392 
00393   // cout << mxgrid << mygrid << endl;      
00394 
00395   MuonLayout fineGrid(mxgrid,mygrid);
00396 
00397   int xratio = m_xgrid/playout.xGrid();
00398   int yratio = m_ygrid/playout.yGrid();
00399 
00400   xratio = (xratio == 0) ? 1 : xratio ;
00401   yratio = (yratio == 0) ? 1 : yratio ;
00402 
00403   // input pad area in terms of the finest grid and smallest region  
00404   // depending on the direction of the search
00405  
00406   int maxX,maxY,minX,minY;
00407   
00408   if(dirX == MuonBase::RIGHT) {
00409     maxX = (pad.nX()+1)*rfactor(nreg)*xratio+depthX*rfactor(nreg)-1;
00410     minX = (pad.nX()+1)*rfactor(nreg)*xratio;
00411   } else if (dirX == MuonBase::LEFT) {
00412     maxX = pad.nX()*rfactor(nreg)*xratio-1;
00413     minX = pad.nX()*rfactor(nreg)*xratio - depthX*rfactor(nreg) ;
00414   } else {
00415     maxX = (pad.nX()+1)*rfactor(nreg)*xratio-1;
00416     minX = (pad.nX())*rfactor(nreg)*xratio;
00417   } 
00418   
00419   if(dirY == MuonBase::UP) {
00420     maxY = (pad.nY()+1)*rfactor(nreg)*yratio+depthY*rfactor(nreg)-1;
00421     minY = (pad.nY()+1)*rfactor(nreg)*yratio;
00422   } else if (dirY == MuonBase::DOWN){
00423     maxY = pad.nY()*rfactor(nreg)*yratio-1;
00424     minY = pad.nY()*rfactor(nreg)*yratio - depthY*rfactor(nreg) ;
00425   } else {
00426     maxY = (pad.nY()+1)*rfactor(nreg)*yratio-1;
00427     minY = (pad.nY())*rfactor(nreg)*yratio;
00428   }
00429     
00430   minX = std::max(0,minX);
00431   minY = std::max(0,minY);
00432 
00433   //cout << minX << " " << minY << " " << maxX << " " << maxY << " " << endl;
00434 
00435   // Which tiles are hit ?
00436 
00437   xratio = mxgrid/m_xgrid;
00438   yratio = mygrid/m_ygrid;
00439 
00440   int ix = minX;
00441   int iy = minY;
00442   bool regleap = false;
00443   int nr = 0;
00444   int nrx = 0;
00445   
00446   while ( ix <= maxX ) {
00447     nrx = fineGrid.region(ix,iy);
00448     if( nrx == -1 ) nrx = 0;
00449     while ( iy <= maxY ) {
00450       // which region   
00451       nr = fineGrid.region(ix,iy);
00452       if( nr == -1 ) nr = 0;
00453       if(nr == nrx || !regleap) {
00454         unsigned int newx = ix/rfactor(nr)/xratio;        
00455         unsigned int newy = iy/rfactor(nr)/yratio;
00456         // New tile should not come out of its region
00457         if(newy < 2*yGrid() && newx < 2*xGrid()) {
00458           LHCb::MuonTileID newtile(sta,*this,nr,quarter,newx,newy);
00459           if (newtile.isValid()) {
00460             vmt.push_back(newtile);
00461           }
00462         }  
00463       }         
00464       iy += rfactor(nr)*yratio;
00465     }   
00466     if(regleap) {
00467       regleap = false;
00468     } else if (nr != nrx) {
00469       regleap = true;   
00470     } 
00471     iy = minY;
00472     ix += rfactor(nrx)*xratio;
00473   }  
00474   return vmt;                                          
00475 }
00476 
00477 //==========================================================
00478 bool MuonLayout::isValidID(const LHCb::MuonTileID& mt) const {
00479 
00480   if(mt.layout() != *this) return false;
00481 
00482   int nx = mt.nX();
00483   int ny = mt.nY();
00484   int xg = xGrid();
00485   int yg = yGrid();
00486   
00487   if(nx >= 0 && 
00488      nx < (2*xg) && 
00489      ny >= (yg) && 
00490      ny < 2*yg) {
00491     return true;
00492   }
00493   if(nx >= xg && 
00494      nx < 2*xg && 
00495      ny >= 0 && 
00496      ny < yg) {
00497     return true;
00498   }
00499   return false;
00500 }
00501 
00502 LHCb::MuonTileID MuonLayout::contains(const LHCb::MuonTileID& pad) const {
00503   // It is responsibility of the user to assure that the pad
00504   // layout is finer than the containing layout
00505   std::vector<LHCb::MuonTileID> mtiles = tiles(pad);
00506   if( mtiles.empty() ) return LHCb::MuonTileID();
00507   LHCb::MuonTileID tile = mtiles[0];
00508   return tile;
00509 } 
00510 
00511 bool MuonLayout::isDefined() const {
00512   return xGrid() > 0 && yGrid() > 0;
00513 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:03:13 2011 for LHCbKernel by doxygen 1.4.7