00001
00002
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
00073
00074
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
00086
00087
00088
00089
00090 int mxgrid = std::max(m_xgrid, playout.xGrid() );
00091 int mygrid = std::max(m_ygrid, playout.yGrid() );
00092
00093
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
00104
00105
00106
00107
00108
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
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
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
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
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
00286
00287
00288
00289 unsigned int nreg = pad.region();
00290 std::vector<LHCb::MuonTileID> vtm = neighbours(pad,dirX,dirY,1);
00291
00292 if(vtm.empty()) return vtm;
00293
00294
00295 if(vtm[0].region() >= nreg) return vtm;
00296
00297 if(vtm.size() == 1) return vtm;
00298
00299
00300 nreg = vtm[0].region();
00301 std::vector<LHCb::MuonTileID> xvtm,result;
00302 std::vector<LHCb::MuonTileID>::iterator ivtm;
00303
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
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
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
00360
00361
00362
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
00374
00375
00376
00377
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
00390 int mxgrid = std::max(m_xgrid, playout.xGrid() );
00391 int mygrid = std::max(m_ygrid, playout.yGrid() );
00392
00393
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
00404
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
00434
00435
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
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
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
00504
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 }