00001 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003
00004 #include <algorithm>
00005
00006 const int EEDetId::QuadColLimits[EEDetId::nCols+1] = { 0, 8,17,27,36,45,54,62,70,76,79 };
00007
00008 const int EEDetId::iYoffset[EEDetId::nCols+1] = { 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0 };
00009
00010 const unsigned short EEDetId::kxf[] = {
00011 41, 51, 41, 51, 41, 51, 36, 51, 36, 51,
00012 26, 51, 26, 51, 26, 51, 21, 51, 21, 51,
00013 21, 51, 21, 51, 21, 51, 16, 51, 16, 51,
00014 14, 51, 14, 51, 14, 51, 14, 51, 14, 51,
00015 9, 51, 9, 51, 9, 51, 9, 51, 9, 51,
00016 6, 51, 6, 51, 6, 51, 6, 51, 6, 51,
00017 6, 51, 6, 51, 6, 51, 6, 51, 6, 51,
00018 4, 51, 4, 51, 4, 51, 4, 51, 4, 56,
00019 1, 58, 1, 59, 1, 60, 1, 61, 1, 61,
00020 1, 62, 1, 62, 1, 62, 1, 62, 1, 62,
00021 1, 62, 1, 62, 1, 62, 1, 62, 1, 62,
00022 1, 61, 1, 61, 1, 60, 1, 59, 1, 58,
00023 4, 56, 4, 51, 4, 51, 4, 51, 4, 51,
00024 6, 51, 6, 51, 6, 51, 6, 51, 6, 51,
00025 6, 51, 6, 51, 6, 51, 6, 51, 6, 51,
00026 9, 51, 9, 51, 9, 51, 9, 51, 9, 51,
00027 14, 51, 14, 51, 14, 51, 14, 51, 14, 51,
00028 16, 51, 16, 51, 21, 51, 21, 51, 21, 51,
00029 21, 51, 21, 51, 26, 51, 26, 51, 26, 51,
00030 36, 51, 36, 51, 41, 51, 41, 51, 41, 51
00031 } ;
00032
00033 const unsigned short EEDetId::kdi[] = {
00034 0, 10, 20, 30, 40, 50, 60, 75, 90, 105,
00035 120, 145, 170, 195, 220, 245, 270, 300, 330, 360,
00036 390, 420, 450, 480, 510, 540, 570, 605, 640, 675,
00037 710, 747, 784, 821, 858, 895, 932, 969, 1006, 1043,
00038 1080, 1122, 1164, 1206, 1248, 1290, 1332, 1374, 1416, 1458,
00039 1500, 1545, 1590, 1635, 1680, 1725, 1770, 1815, 1860, 1905,
00040 1950, 1995, 2040, 2085, 2130, 2175, 2220, 2265, 2310, 2355,
00041 2400, 2447, 2494, 2541, 2588, 2635, 2682, 2729, 2776, 2818,
00042 2860, 2903, 2946, 2988, 3030, 3071, 3112, 3152, 3192, 3232,
00043 3272, 3311, 3350, 3389, 3428, 3467, 3506, 3545, 3584, 3623,
00044 3662, 3701, 3740, 3779, 3818, 3857, 3896, 3935, 3974, 4013,
00045 4052, 4092, 4132, 4172, 4212, 4253, 4294, 4336, 4378, 4421,
00046 4464, 4506, 4548, 4595, 4642, 4689, 4736, 4783, 4830, 4877,
00047 4924, 4969, 5014, 5059, 5104, 5149, 5194, 5239, 5284, 5329,
00048 5374, 5419, 5464, 5509, 5554, 5599, 5644, 5689, 5734, 5779,
00049 5824, 5866, 5908, 5950, 5992, 6034, 6076, 6118, 6160, 6202,
00050 6244, 6281, 6318, 6355, 6392, 6429, 6466, 6503, 6540, 6577,
00051 6614, 6649, 6684, 6719, 6754, 6784, 6814, 6844, 6874, 6904,
00052 6934, 6964, 6994, 7024, 7054, 7079, 7104, 7129, 7154, 7179,
00053 7204, 7219, 7234, 7249, 7264, 7274, 7284, 7294, 7304, 7314
00054 } ;
00055
00056 EEDetId::EEDetId( int index1, int index2, int iz, int mode ) : DetId( Ecal, EcalEndcap )
00057 {
00058 int crystal_ix=0;
00059 int crystal_iy=0;
00060 if (mode == XYMODE)
00061 {
00062 crystal_ix = index1;
00063 crystal_iy = index2;
00064 }
00065 else if (mode == SCCRYSTALMODE)
00066 {
00067 int SC = index1;
00068 int crystal = index2;
00069
00070
00071 crystal_ix=iz*ix(SC,crystal);
00072 if (crystal_ix<0)
00073 crystal_ix++;
00074 crystal_ix+=50;
00075 crystal_iy=iy(SC,crystal);
00076 if (crystal_iy<0)
00077 crystal_iy++;
00078 crystal_iy+=50;
00079
00080 }
00081 else
00082 {
00083 throw cms::Exception("InvalidDetId") << "EEDetId: Cannot create object. Unknown mode for (int, int, int) constructor.";
00084 }
00085
00086 if (!validDetId(crystal_ix,crystal_iy,iz))
00087 {
00088 throw cms::Exception("InvalidDetId") << "EEDetId: Cannot create object. Indexes out of bounds \n"
00089 << "x = " << crystal_ix << " y = " << crystal_iy << " z = " << iz;
00090 }
00091
00092 id_|=(crystal_iy&0x7f)|((crystal_ix&0x7f)<<7)|((iz>0)?(0x4000):(0));
00093 }
00094
00095
00096
00097
00098 EEDetId
00099 EEDetId::unhashIndex( int hi )
00100 {
00101 if( validHashIndex( hi ) )
00102 {
00103 const int iz ( hi<kEEhalf ? -1 : 1 ) ;
00104 const uint32_t di ( hi%kEEhalf ) ;
00105 const int ii ( ( std::upper_bound( kdi, kdi+(2*IY_MAX), di ) - kdi ) - 1 ) ;
00106 const int iy ( 1 + ii/2 ) ;
00107 const int ix ( kxf[ii] + di - kdi[ii] ) ;
00108 return EEDetId( ix, iy, iz ) ;
00109 }
00110 else
00111 {
00112 return EEDetId() ;
00113 }
00114 }
00115
00116 int
00117 EEDetId::ix( int iSC, int iCrys ) const
00118 {
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 int nSCinQuadrant = QuadColLimits[nCols];
00132
00133 if (iSC > 4*nSCinQuadrant || iSC < 1)
00134 {
00135 throw new std::exception();
00136 }
00137
00138
00139 int iSCmap, iqx,iq;
00140 if (iSC > 3*nSCinQuadrant)
00141 {
00142 iSCmap = iSC - 3*nSCinQuadrant;
00143 iqx = 1;
00144 iq=4;
00145 }
00146 else if (iSC > 2*nSCinQuadrant)
00147 {
00148 iSCmap = iSC - 2*nSCinQuadrant;
00149 iqx = -1;
00150 iq=3;
00151 }
00152 else if (iSC > nSCinQuadrant)
00153 {
00154 iSCmap = iSC - nSCinQuadrant;
00155 iqx = -1;
00156 iq=2;
00157 }
00158 else
00159 {
00160 iSCmap = iSC;
00161 iqx = 1;
00162 iq=1;
00163 }
00164
00165
00166 int iCol = 0 ;
00167 while (iSCmap > QuadColLimits[iCol++]) ;
00168 iCol-- ;
00169
00170 int ixCrys=-1;
00171 if (iq == 1 || iq == 3)
00172 ixCrys = iqx*(5*(iCol-1) + (int)(iCrys+4)/5);
00173 else if (iq == 2 || iq == 4)
00174 ixCrys = iqx*(5*(iCol-1) + (iCrys-1)%5 + 1);
00175
00176
00177
00178 return ixCrys;
00179 }
00180
00181 int EEDetId::iy( int iSC, int iCrys ) const
00182 {
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194 int nSCinQuadrant = QuadColLimits[nCols];
00195 if (iSC > 4*nSCinQuadrant || iSC < 1)
00196 {
00197 throw new std::exception();
00198 }
00199
00200
00201 int iSCmap, iqy,iq;
00202 if (iSC > 3*nSCinQuadrant)
00203 {
00204 iSCmap = iSC - 3*nSCinQuadrant;
00205 iqy = -1;
00206 iq=4;
00207 }
00208 else if (iSC > 2*nSCinQuadrant)
00209 {
00210 iSCmap = iSC - 2*nSCinQuadrant;
00211 iqy = -1;
00212 iq=3;
00213 }
00214 else if (iSC > nSCinQuadrant)
00215 {
00216 iSCmap = iSC - nSCinQuadrant;
00217 iqy = 1;
00218 iq=2;
00219 } else
00220 {
00221 iSCmap = iSC;
00222 iqy = 1;
00223 iq=1;
00224 }
00225
00226
00227 int iCol = 0;
00228 while (iSCmap > QuadColLimits[iCol++]) ;
00229 iCol--;
00230
00231 int iSCy = iSCmap - QuadColLimits[iCol-1] + iYoffset[iCol];
00232
00233 int iyCrys=-1;
00234 if (iq == 1 || iq == 3)
00235 iyCrys = iqy*(5*(iSCy-1) + (iCrys-1)%5 + 1);
00236 else if (iq == 2 || iq == 4)
00237 iyCrys = iqy*(5*(iSCy-1) + (int)(iCrys+4)/5 );
00238 return iyCrys;
00239 }
00240
00241 int EEDetId::ixQuadrantOne() const
00242 {
00243 int iQuadrant = iquadrant();
00244 if ( iQuadrant == 1 || iQuadrant == 4)
00245 return (ix() - 50);
00246 else if ( iQuadrant == 2 || iQuadrant == 3)
00247 return (51 - ix());
00248
00249 return -1;
00250 }
00251
00252 int EEDetId::iyQuadrantOne() const
00253 {
00254 int iQuadrant = iquadrant();
00255 if ( iQuadrant == 1 || iQuadrant == 2)
00256 return (iy() - 50);
00257 else if ( iQuadrant == 3 || iQuadrant == 4)
00258 return 51 - iy();
00259
00260 return -1;
00261 }
00262
00263 int
00264 EEDetId::iquadrant() const
00265 {
00266 if (ix()>50)
00267 {
00268 if(iy()>50)
00269 return 1;
00270 else
00271 return 4;
00272 }
00273 else
00274 {
00275 if(iy()>50)
00276 return 2;
00277 else
00278 return 3;
00279 }
00280
00281 return -1;
00282 }
00283
00284 int
00285 EEDetId::isc() const
00286 {
00287 return isc( 1 + ( ix() - 1 )/nCrys,
00288 1 + ( iy() - 1 )/nCrys ) ;
00289 }
00290
00291 int
00292 EEDetId::isc( int jx, int jy )
00293 {
00294 if( 0 < jx &&
00295 21 > jx &&
00296 0 < jy &&
00297 21 > jy )
00298 {
00299 const int iquad ( ( 10<jx && 10<jy ? 1 :
00300 ( 11>jx && 10<jy ? 2 :
00301 ( 11>jx && 11>jy ? 3 : 4 ) ) ) ) ;
00302
00303 const int iCol = ( 1 == iquad || 4 == iquad ? jx - 10 : 11 - jx ) ;
00304 const int iRow = ( 1 == iquad || 2 == iquad ? jy - 10 : 11 - jy ) ;
00305
00306 static int nSCinQuadrant = ISC_MAX/4;
00307
00308 const int yOff ( iYoffset[iCol] ) ;
00309
00310 const int qOff ( nSCinQuadrant*( iquad - 1 ) ) ;
00311
00312 const int iscOne ( QuadColLimits[iCol-1] + iRow - yOff ) ;
00313
00314 return ( yOff >= iRow ? -1 :
00315 ( QuadColLimits[iCol] < iscOne ? -2 :
00316 iscOne + qOff ) ) ;
00317 }
00318 else
00319 {
00320 return -3 ;
00321 }
00322 }
00323
00324 int EEDetId::ic() const
00325 {
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 int iQuadrant = iquadrant();
00339 int icrCol=-1;
00340 int icrRow=-1;
00341
00342 if (iQuadrant == 1 || iQuadrant == 3)
00343 {
00344 icrCol=(ixQuadrantOne()-1) % nCrys;
00345 icrRow=(iyQuadrantOne()-1) % nCrys;
00346 }
00347
00348 else if (iQuadrant == 2 || iQuadrant == 4)
00349 {
00350 icrRow=(ixQuadrantOne()-1) % nCrys;
00351 icrCol=(iyQuadrantOne()-1) % nCrys;
00352 }
00353
00354 int icrys = 5*icrCol + icrRow + 1;
00355
00356 return icrys;
00357 }
00358
00359
00360 bool
00361 EEDetId::isNextToBoundary( EEDetId id )
00362 {
00363 return isNextToDBoundary( id ) || isNextToRingBoundary( id ) ;
00364 }
00365
00366 bool
00367 EEDetId::isNextToDBoundary( EEDetId id )
00368 {
00369
00370 return id.ix() == 50 || id.ix() == 51 ;
00371 }
00372
00373
00374 bool
00375 EEDetId::isNextToRingBoundary(EEDetId id)
00376 {
00377 for (int i = -1; i <= 1; ++i) {
00378 for (int j = -1; j <= 1; ++j) {
00379 if ( ! validDetId( id.ix() + i, id.iy() + j, id.zside() ) ) {
00380 return true;
00381 }
00382 }
00383 }
00384 return false;
00385 }
00386
00387 int
00388 EEDetId::iPhiOuterRing() const
00389 {
00390 int returnValue ( 0 ) ;
00391 if( isOuterRing() )
00392 {
00393 const int ax ( abs( ix() - IX_MAX/2 ) ) ;
00394 const int ay ( abs( iy() - IY_MAX/2 ) ) ;
00395 returnValue = ax + 50 - ay ;
00396 if( ay <= 47 ) --returnValue ;
00397 if( ay <= 45 ) --returnValue ;
00398 if( ay <= 42 ) --returnValue ;
00399 if( ay <= 37 ) --returnValue ;
00400 if( ay <= 35 ) --returnValue ;
00401 if( ay <= 30 ) --returnValue ;
00402 if( ay <= 25 ) --returnValue ;
00403 if( ay <= 15 ) --returnValue ;
00404 if( ay <= 10 ) --returnValue ;
00405 const int iq ( iquadrant() ) ;
00406 if( 1==iq )
00407 {
00408 returnValue = 91 - returnValue ;
00409 }
00410 else
00411 {
00412 if( 2==iq )
00413 {
00414 returnValue += 90 ;
00415 }
00416 else
00417 {
00418 if( 3==iq )
00419 {
00420 returnValue = 271 - returnValue ;
00421 }
00422 else
00423 {
00424 returnValue += 270 ;
00425 }
00426 }
00427 }
00428 returnValue = 1 + ( 360 + returnValue - 10 -1 )%360 ;
00429 }
00430
00431 return returnValue ;
00432 }
00433
00434 EEDetId
00435 EEDetId::idOuterRing( int iPhi , int zEnd )
00436 {
00437 iPhi -= 10 ;
00438 while( iPhi < 1 ) iPhi+=360 ;
00439 while( iPhi > 360 ) iPhi-=360 ;
00440
00441 const int index1 ( iPhi - 1 ) ;
00442 const int quad ( index1/90 ) ;
00443 int indexq ( index1 - quad*90 + 1 ) ;
00444 if( 0==quad || 2==quad ) indexq = 91 - indexq ;
00445 const int indexh ( indexq > 45 ? 91 - indexq : indexq ) ;
00446 const int axh ( indexh<=10 ? indexh :
00447 ( indexh<=12 ? 10 :
00448 ( indexh<=17 ? indexh - 2 :
00449 ( indexh<=18 ? 15 :
00450 ( indexh<=28 ? indexh - 3 :
00451 ( indexh<=30 ? 25 :
00452 ( indexh<=35 ? indexh - 5 :
00453 ( indexh<=39 ? 30 :
00454 ( indexh<=44 ? indexh - 9 : 35 ))))))))) ;
00455 const int ayh ( indexh<=10 ? 50 :
00456 ( indexh<=12 ? 60 - indexh :
00457 ( indexh<=17 ? 47 :
00458 ( indexh<=18 ? 64 - indexh :
00459 ( indexh<=28 ? 45 :
00460 ( indexh<=30 ? 73 - indexh :
00461 ( indexh<=35 ? 42 :
00462 ( indexh<=39 ? 77 - indexh :
00463 ( indexh<=44 ? 37 : 36 ))))))))) ;
00464 const int bxh ( indexq>45 ? ayh : axh ) ;
00465 const int byh ( indexq>45 ? axh : ayh ) ;
00466 const int cx ( ( quad==0 || quad==3 ? bxh : -bxh+1 ) + IX_MAX/2 ) ;
00467 const int cy ( ( quad==0 || quad==1 ? byh : -byh+1 ) + IY_MAX/2 ) ;
00468
00469 return EEDetId( cx, cy, ( zEnd > 0 ? 1 : -1 ) ) ;
00470 }
00471
00472
00473 EEDetId
00474 EEDetId::offsetBy(int nrStepsX, int nrStepsY ) const
00475 {
00476 int newX = ix() + nrStepsX;
00477 int newY = iy() + nrStepsY;
00478
00479 if( validDetId( newX, newY, zside() ) ) {
00480 return EEDetId( newX, newY, zside() );
00481 } else {
00482 return EEDetId(0);
00483 }
00484 }
00485
00486 EEDetId
00487 EEDetId::switchZSide() const
00488 {
00489 int newZSide = -1 * zside();
00490 if( validDetId(ix(), iy(), newZSide ) ) {
00491 return EEDetId( ix(), iy(), newZSide );
00492 } else {
00493 return EEDetId(0);
00494 }
00495 }
00496
00497 DetId
00498 EEDetId::offsetBy( const DetId startId, int nrStepsX, int nrStepsY )
00499 {
00500 if( startId.det() == DetId::Ecal && startId.subdetId() == EcalEndcap ) {
00501 EEDetId eeStartId( startId );
00502 return eeStartId.offsetBy( nrStepsX, nrStepsY ).rawId();
00503 } else {
00504 return DetId(0);
00505 }
00506 }
00507
00508 DetId
00509 EEDetId::switchZSide( const DetId startId )
00510 {
00511 if( startId.det() == DetId::Ecal && startId.subdetId() == EcalEndcap ) {
00512 EEDetId eeStartId(startId);
00513 return eeStartId.switchZSide().rawId();
00514 } else {
00515 return DetId(0);
00516 }
00517 }
00518
00519 bool
00520 EEDetId::isOuterRing() const
00521 {
00522 const int kx ( ix() ) ;
00523 const int ky ( iy() ) ;
00524 const int ax ( kx>IX_MAX/2 ? kx-IX_MAX/2 : IX_MAX/2 + 1 - kx ) ;
00525 const int ay ( ky>IY_MAX/2 ? ky-IY_MAX/2 : IY_MAX/2 + 1 - ky ) ;
00526 return ( isOuterRingXY( ax, ay ) ||
00527 isOuterRingXY( ay, ax ) ) ;
00528 }
00529
00530 bool
00531 EEDetId::isOuterRingXY( int ax, int ay )
00532 {
00533 return ( ( ax<=10 && ay==50 ) ||
00534 ( ax==10 && ay>=48 ) ||
00535 ( ax<=15 && ax>=11 && ay==47 ) ||
00536 ( ax==15 && ay==46 ) ||
00537 ( ax<=25 && ax>=16 && ay==45 ) ||
00538 ( ax==25 && ay<=44 && ay>=43 ) ||
00539 ( ax<=30 && ax>=26 && ay==42 ) ||
00540 ( ax==30 && ay<=41 && ay>=38 ) ||
00541 ( ax<=35 && ax>=31 && ay==37 ) ||
00542 ( ax==35 && ay==36 ) ) ;
00543 }
00544
00545 bool
00546 EEDetId::slowValidDetId(int crystal_ix, int crystal_iy)
00547 {
00548 return
00549 !(
00550 (crystal_ix >= 1 && crystal_ix <= 3 && (crystal_iy <= 40 || crystal_iy > 60) ) ||
00551 (crystal_ix >= 4 && crystal_ix <= 5 && (crystal_iy <= 35 || crystal_iy > 65) ) ||
00552 (crystal_ix >= 6 && crystal_ix <= 8 && (crystal_iy <= 25 || crystal_iy > 75) ) ||
00553 (crystal_ix >= 9 && crystal_ix <= 13 && (crystal_iy <= 20 || crystal_iy > 80) ) ||
00554 (crystal_ix >= 14 && crystal_ix <= 15 && (crystal_iy <= 15 || crystal_iy > 85) ) ||
00555 (crystal_ix >= 16 && crystal_ix <= 20 && (crystal_iy <= 13 || crystal_iy > 87) ) ||
00556 (crystal_ix >= 21 && crystal_ix <= 25 && (crystal_iy <= 8 || crystal_iy > 92) ) ||
00557 (crystal_ix >= 26 && crystal_ix <= 35 && (crystal_iy <= 5 || crystal_iy > 95) ) ||
00558 (crystal_ix >= 36 && crystal_ix <= 39 && (crystal_iy <= 3 || crystal_iy > 97) ) ||
00559 (crystal_ix >= 98 && crystal_ix <= 100 && (crystal_iy <= 40 || crystal_iy > 60) ) ||
00560 (crystal_ix >= 96 && crystal_ix <= 97 && (crystal_iy <= 35 || crystal_iy > 65) ) ||
00561 (crystal_ix >= 93 && crystal_ix <= 95 && (crystal_iy <= 25 || crystal_iy > 75) ) ||
00562 (crystal_ix >= 88 && crystal_ix <= 92 && (crystal_iy <= 20 || crystal_iy > 80) ) ||
00563 (crystal_ix >= 86 && crystal_ix <= 87 && (crystal_iy <= 15 || crystal_iy > 85) ) ||
00564 (crystal_ix >= 81 && crystal_ix <= 85 && (crystal_iy <= 13 || crystal_iy > 87) ) ||
00565 (crystal_ix >= 76 && crystal_ix <= 80 && (crystal_iy <= 8 || crystal_iy > 92) ) ||
00566 (crystal_ix >= 66 && crystal_ix <= 75 && (crystal_iy <= 5 || crystal_iy > 95) ) ||
00567 (crystal_ix >= 62 && crystal_ix <= 65 && (crystal_iy <= 3 || crystal_iy > 97) ) ||
00568 ( (crystal_ix == 40 || crystal_ix == 61) && ( (crystal_iy >= 46 && crystal_iy <= 55 ) || crystal_iy <= 3 || crystal_iy > 97 )) ||
00569 ( (crystal_ix == 41 || crystal_ix == 60) && crystal_iy >= 44 && crystal_iy <= 57 ) ||
00570 ( (crystal_ix == 42 || crystal_ix == 59) && crystal_iy >= 43 && crystal_iy <= 58 ) ||
00571 ( (crystal_ix == 43 || crystal_ix == 58) && crystal_iy >= 42 && crystal_iy <= 59 ) ||
00572 ( (crystal_ix == 44 || crystal_ix == 45 || crystal_ix == 57 || crystal_ix == 56) && crystal_iy >= 41 && crystal_iy <= 60 ) ||
00573 ( crystal_ix >= 46 && crystal_ix <= 55 && crystal_iy >= 40 && crystal_iy <= 61 )
00574 );
00575 }
00576
00577 int EEDetId::distanceX(const EEDetId& a,const EEDetId& b)
00578 {
00579 return abs(a.ix()-b.ix());
00580 }
00581
00582 int EEDetId::distanceY(const EEDetId& a,const EEDetId& b)
00583 {
00584 return abs(a.iy() - b.iy());
00585 }
00586
00587 #include <ostream>
00588 std::ostream& operator<<(std::ostream& s,const EEDetId& id)
00589 {
00590 return s << "(EE iz " << ((id.zside()>0)?("+ "):("- "))
00591 << " ix " << id.ix() << " , iy " << id.iy() << ')';
00592 }