00001 #include <iostream>
00002 #include <cstdio>
00003 #include <utility>
00004 #include <vector>
00005 #include <map>
00006 #include "EmcIndexer.h"
00007 #include "PbScIndexer.h"
00008 #include "PbGlIndexer.h"
00009
00011
00012
00013
00014
00016
00017 using namespace std;
00018
00019
00020
00022 struct emcTowerLocation {
00023 int arm,sector,yrow,zrow;
00024 };
00025
00026 vector<string> EmcIndexer::fEmcSectorIdent ;
00027
00028
00029 int
00030 EmcIndexer::EmcSectorNumber(const char * SectorId)
00031 {
00032 if (fEmcSectorIdent.empty()) {
00033 fEmcSectorIdent.push_back("W0") ;
00034 fEmcSectorIdent.push_back("W1") ;
00035 fEmcSectorIdent.push_back("W2") ;
00036 fEmcSectorIdent.push_back("W3") ;
00037 fEmcSectorIdent.push_back("E2") ;
00038 fEmcSectorIdent.push_back("E3") ;
00039 fEmcSectorIdent.push_back("E0") ;
00040 fEmcSectorIdent.push_back("E1") ;
00041 fEmcSectorIdent.push_back("NONE") ;
00042 }
00043
00044 int SectorNumber=0;
00045
00046 while (SectorNumber<8 && fEmcSectorIdent[SectorNumber]!=SectorId) {
00047 SectorNumber++ ;
00048 }
00049
00050 if(SectorNumber>7) {
00051 return -1;
00052 }
00053 else {
00054 return SectorNumber;
00055 }
00056 }
00057
00058
00059 const char*
00060 EmcIndexer::EmcSectorId(int SectorNumber)
00061 {
00062 if (fEmcSectorIdent.empty()) {
00063 EmcIndexer::EmcSectorNumber("W0") ;
00064 }
00065
00066 return fEmcSectorIdent[SectorNumber].c_str() ;
00067 }
00068
00069
00070 int EmcIndexer::SoftwareKey(int TowerId)
00071 {
00072 static vector<int> softkeys ;
00073 static const int PXMAX = 24768 ;
00074
00075 if (softkeys.size()==0) {
00076
00077 softkeys.resize(PXMAX) ;
00078
00079 int ItemId ;
00080
00081 int iS ;
00082 int iSMT ;
00083 int iarm ;
00084 int iy ;
00085 int iz ;
00086
00087
00088
00089
00090
00091 int swkey ;
00092
00093
00094
00095
00096
00097
00098 for ( ItemId = 0 ; ItemId < PXMAX ; ItemId++ ) {
00099
00100 EmcIndexer::iPXiSiST(ItemId,iS,iSMT) ;
00101
00102 iarm = ((iS<4)?0:1) ;
00103 if (iS<6) {
00104 iy = iSMT/72 ;
00105 iz = iSMT%72 ;
00106 }
00107 else {
00108 iy = iSMT/96 ;
00109 iz = iSMT%96 ;
00110 }
00111
00112 if(iS>=4){
00113
00114 iS = ((iS -=6)<0)? iS+4 : iS;
00115 }
00116 swkey = SoftwareKey(iarm,iS,iy,iz) ;
00117 softkeys[ItemId] = swkey ;
00118 }
00119 }
00120
00121 int rv ;
00122
00123 if (TowerId<0 || static_cast<unsigned int>(TowerId) >= softkeys.size())
00124 {
00125 rv = 0 ;
00126 }
00127 else
00128 {
00129 rv = softkeys[TowerId] ;
00130 }
00131 return rv ;
00132 }
00133
00134
00135 int
00136 EmcIndexer::SoftwareKey(int arm, int sector_in_arm, int yrow, int zrow)
00137 {
00138 return 100000*arm + 10000*sector_in_arm + 100*yrow + zrow ;
00139 }
00140
00141
00142 void
00143 EmcIndexer::PXSM144_iSiSM144(int PXSM144, int &iS, int &iSM144)
00144 {
00145
00146 if(PXSM144<108){
00147 iS = PXSM144/18;
00148 iSM144= PXSM144%18;
00149 } else {
00150 iS = 6 + (PXSM144-108)/32;
00151 iSM144= (PXSM144-108)%32;
00152 }
00153 }
00154
00155
00156
00157 int
00158 EmcIndexer::iSiSM144_PXSM144(int iS, int iSM144)
00159 {
00160
00161 if(iS<6){
00162 return iS*18+iSM144;
00163 } else {
00164 return 108 + (iS-6)*32+iSM144;
00165 }
00166 }
00167
00168
00169
00170 int
00171 EmcIndexer::iSiSMiSMTiST(int SectorNumber, int SMNumber, int SMTower)
00172 {
00173
00174 if(SMTower<0) return SMTower;
00175 if(SectorNumber<6){
00176 PbScIndexer * gPbSc = PbScIndexer::buildPbScIndexer();
00177 return gPbSc->SMiSMTiST(SMNumber ,SMTower);
00178 } else {
00179 PbGlIndexer * gPbGl = PbGlIndexer::buildPbGlIndexer();
00180 return gPbGl->SMiSMTiST(SMNumber ,SMTower);
00181 }
00182 }
00183
00184
00185 int
00186 EmcIndexer::iSiSMiSMTiPX(int SectorNumber, int SMNumber, int SMTower)
00187 {
00188
00189 if(SMTower<0) return SMTower;
00190 if(SectorNumber<6){
00191 PbScIndexer * gPbSc = PbScIndexer::buildPbScIndexer();
00192 return 2592*SectorNumber + gPbSc->SMiSMTiST(SMNumber ,SMTower);
00193 } else {
00194 PbGlIndexer * gPbGl = PbGlIndexer::buildPbGlIndexer();
00195 return 15552 + 4608*(SectorNumber-6) + gPbGl->SMiSMTiST(SMNumber ,SMTower);
00196 }
00197 }
00198
00199
00200 void
00201 EmcIndexer::iSiSTiSMiSMT(const int iS, const int iST, int & iSM, int & iSMT)
00202 {
00203
00204 int x, y;
00205 if(iS<6){
00206 PbScIndexer * gPbSc = PbScIndexer::buildPbScIndexer();
00207 gPbSc->iST_SMInd(iST, iSM, iSMT, x, y);
00208 } else {
00209 PbGlIndexer * gPbGl = PbGlIndexer::buildPbGlIndexer();
00210 gPbGl->iST_SMInd(iST, iSM, iSMT, x, y);
00211 }
00212 }
00213
00214
00215 int
00216 EmcIndexer::PXSM144iCH_iPX(const int PXSM144, const int iCH)
00217 {
00219 static vector<vector<int> > ifem_vs_ichannel_to_towerID ;
00220
00221 static int nfem = MaxNumberOfFEMs() ;
00222 static int nchannels = 144 ;
00223
00224
00225
00226
00227
00228 assert(PXSM144>=0 && PXSM144<nfem) ;
00229 assert(iCH>=0 && iCH<nchannels) ;
00230
00231 if (ifem_vs_ichannel_to_towerID.empty()) {
00232
00233 ifem_vs_ichannel_to_towerID.resize(nfem) ;
00234
00235 int ifem, ichannel ;
00236 int iS, iSM144, iSMT ;
00237
00238 for (ifem=0;ifem<nfem;ifem++) {
00239
00240 ifem_vs_ichannel_to_towerID[ifem].resize(nchannels) ;
00241
00242 for (ichannel=0;ichannel<nchannels;ichannel++) {
00243
00244 PXSM144_iSiSM144(ifem, iS, iSM144);
00245 iSMT = iCHiSMT(ichannel);
00246 ifem_vs_ichannel_to_towerID[ifem][ichannel] =
00247 iSiSMiSMTiPX(iS, iSM144, iSMT);
00248 }
00249 }
00250 }
00251
00252 return ifem_vs_ichannel_to_towerID[PXSM144][iCH] ;
00253 }
00254
00255
00256 int
00257 EmcIndexer::iCHiSMT(int iCH)
00258 {
00259
00260
00261
00262 int ASIC = iCH/24;
00263 int preamp = (iCH%24)/4;
00264
00265 int input = iCH%4;
00266
00267 int xc, yc;
00268 yc = input/2;
00269 xc = 1-input%2;
00270 return 12*((5-preamp)*2+yc)+ASIC*2+xc;
00271 }
00272
00273
00274 int
00275 EmcIndexer::iCHiSMT(const int Channel, const bool ASIC24)
00276 {
00277
00278
00279
00280
00281 int chPerBoard = (ASIC24)? 24 : 32;
00282 int ASIC = Channel/chPerBoard;
00283 int ASICCh = Channel%chPerBoard;
00284 if(!ASIC24) {
00285 if((ASICCh>11&&ASICCh<16)||ASICCh>27) return -1;
00286 if(ASICCh>=16) ASICCh -=4;
00287 }
00288 int preamp = ASICCh/4;
00289
00290 int input = Channel%4;
00291
00292 int xc, yc;
00293 yc = input/2;
00294 xc = 1-input%2;
00295 return 12*((5-preamp)*2+yc)+ASIC*2+xc;
00296 }
00297
00298
00299 int
00300 EmcIndexer::iSMTiCH(const int iSMT, bool ASIC24)
00301 {
00302
00303
00304 int x, y;
00305 iSM144TxySM144T(iSMT, x, y);
00306 int ASIC = x/2;
00307 int ym = y/2;
00308 int preamp = 5-ym;
00309 int xc = x%2;
00310 int yc = y%2;
00311 int cell = 2*yc+(1-xc);
00312 if(ASIC24) {return ASIC*24+preamp*4+cell;
00313 } else {
00314 if(preamp<3) {return ASIC*32+preamp*4+cell;
00315 } else { return ASIC*32+4+preamp*4+cell;}
00316 }
00317 }
00318
00319
00320 int
00321 EmcIndexer::absFEMCHiPX(const int absFEMCH)
00322 {
00323 int FEM, iS, iCH, iSM, iSMT;
00324 FEM = absFEMCH/192;
00325 iCH = absFEMCH%192;
00326 iSMT = iCHiSMT(iCH, false);
00327 if(iSMT<0) return iSMT;
00328 if(FEM<108){
00329 iS = FEM/18;
00330 iSM = FEM%18;
00331 } else {
00332 iS = 6+(FEM-108)/32;
00333 iSM = (FEM-108)%32;
00334 }
00335 return iSiSMiSMTiPX(iS, iSM, iSMT);
00336 }
00337
00338
00339 int
00340 EmcIndexer::iPXabsFEMCH(const int iPX)
00341 {
00342 int iS,iST, iCH, iSM, iSMT;
00343 bool ASIC24 = false;
00344 EmcIndexer::iPXiSiST(iPX, iS, iST);
00345 iSiSTiSMiSMT(iS, iST, iSM, iSMT);
00346 iCH = iSMTiCH(iSMT, ASIC24);
00347 if(iS<6){
00348 return 192*(iS*18+iSM)+iCH;
00349 } else {
00350 return 192*(108+32*(iS-6)+iSM)+iCH;
00351 }
00352 }
00353
00354
00355 void
00356 EmcIndexer::iCH192ASICi32(const int iCH192, int & ASIC, int & iCH32)
00357 {
00358 ASIC = iCH192/32;
00359 iCH32 = iCH192%32;
00360 }
00361
00362
00363 void
00364 EmcIndexer::iSM144TxySM144T(const int iSMT, int & xsmt, int & ysmt)
00365 {
00366 ysmt = iSMT/12;
00367 xsmt = iSMT - ysmt*12;
00368 }
00369
00370
00371 void
00372 EmcIndexer::iSM144TtoHWIndexes(int iSMT, bool ASIC24, int & QB, int &Cell,
00373 int &ASIC, int &Preamp, int &Input,
00374 int &FEMChannel)
00375 {
00376 int x, y;
00377 iSM144TxySM144T(iSMT, x, y);
00378 ASIC = x/2;
00379 int ym = y/2;
00380 Preamp = 5-ym;
00381 QB = ym*6 + ASIC;
00382 int xc = x%2;
00383 int yc = y%2;
00384 Cell = 2*yc+(1-xc);
00385 Input = Preamp*4 + Cell;
00386 if(ASIC24) {
00387 FEMChannel = ASIC*24+Preamp*4+Cell;
00388 } else {
00389 if(Preamp<3) {
00390 FEMChannel = ASIC*32+Preamp*4+Cell;
00391 } else {
00392 FEMChannel = ASIC*32+4+Preamp*4+Cell;
00393 }
00394 }
00395 }
00396
00397
00398 void
00399 EmcIndexer::findItemIdentity(const int ItemId, const bool ASIC24,
00400 const bool EMCalMapStyle, int & iS, int & iSM,
00401 int & iSMT, int &iFEM, int &iCH192, int &ASIC,
00402 int &ASICCh)
00403 {
00404
00405 if(EMCalMapStyle) {
00406
00407 int iST;
00408 EmcIndexer::iPXiSiST(ItemId, iS, iST);
00409 EmcIndexer::iSiSTiSMiSMT(iS , iST , iSM , iSMT);
00410 iCH192 = iSMTiCH(iSMT, 0);
00411 iFEM = (iS>5)? 108+(iS-6)*32 : iS*18;
00412 iFEM += iSM;
00413 } else {
00414
00415 iFEM = ItemId/192;
00416 iCH192 = ItemId%192;
00417 PXSM144_iSiSM144(iFEM, iS, iSM);
00418 iSMT = iCHiSMT(iCH192,ASIC24);
00419 }
00420 iCH192ASICi32(iCH192 , ASIC, ASICCh);
00421 }
00422
00423
00424 bool
00425 EmcIndexer::IsValid(int iS, int x, int y){
00426 if(x<0||y<0) return false;
00427 if(iS<6){
00428 if(x>=72||y>=36) return false;
00429 } else {
00430 if(x>=96||y>=48) return false;
00431 }
00432 return true;
00433 }
00434
00435
00436
00437 int EmcIndexer::iSiSTiPX(int iS, int iST){
00438 return ((iS<6)? 2592*iS+iST : 15552+4608*(iS-6)+iST);
00439 }
00440
00441
00442 void EmcIndexer::iPXiSiST(const int iPX, int & iS, int & iST)
00443 {
00444 if(iPX<15552){
00445
00446 iS = iPX/2592;
00447 iST = iPX%2592;
00448 } else {
00449
00450 iS = 6+(iPX-15552)/4608;
00451 iST = (iPX-15552)%4608;
00452 }
00453 }
00454
00455
00456 void EmcIndexer::iPXiSiSMiSMT(int iPX, int &iS, int &iSM, int &iSMT){
00457 int iST, ix, iy;
00458 if(iPX<15552){
00459
00460 iS = iPX/2592;
00461 iST = iPX%2592;
00462 ix = iST%72;
00463 iy = iST/72;
00464 iSM = iS*18 + (iy/12)*6+(ix/12);
00465 } else {
00466
00467 iS = 6+(iPX-15552)/4608;
00468 iST = (iPX-15552)%4608;
00469 ix = iST%96;
00470 iy = iST/96;
00471 iSM = 108+(iS-6)*32 + (iy/12)*8+(ix/12);
00472 }
00473 iSMT = (iy%12)*12+ix%12;
00474 }
00475
00476
00477 void EmcIndexer::iSTxyST(int iS, int iST, int & x, int & y){
00478 y = iST/((iS<6)? 72 : 96);
00479 x = iST%((iS<6)? 72 : 96);
00480 }
00481
00482
00483
00484 int EmcIndexer::xySTiST(int iS, int x,int y){
00485 return ((iS<6)? 72*y+x : 96*y+x);
00486 }
00487
00488
00489
00490 int EmcIndexer::getTowerId(int iS, int x,int y){
00491 return ((iS<6)? 2592*iS+72*y+x : 15552+4608*(iS-6)+96*y+x);
00492 }
00493
00494
00495
00496 void EmcIndexer::decodeTowerId(int TowerId, int & iS, int & x,int & y){
00497 int iST;
00498 iPXiSiST(TowerId, iS, iST);
00499 iSTxyST(iS, iST, x, y);
00500 }
00501
00502
00503 void
00504 EmcIndexer::TowerLocation(int towerID, int& arm, int& sector_in_arm,
00505 int& yrow, int& zrow)
00506 {
00507 static map<int,emcTowerLocation> towerLocationMap ;
00508
00509 if (towerLocationMap.empty()) {
00510
00511 size_t i ;
00512 int iS, iST, x, y ;
00513
00514 for ( i = 0 ; i < 24768 ; i++ ) {
00515 iPXiSiST(i, iS, iST) ;
00516 iSTxyST(iS, iST, x, y) ;
00517 emcTowerLocation& tl = towerLocationMap[i] ;
00518 tl.arm = (iS<4) ? 0 : 1 ;
00519 if (tl.arm==1) {
00520 iS -= 6 ;
00521 if (iS<0) iS+=4 ;
00522 }
00523 tl.sector = iS ;
00524 tl.yrow = y ;
00525 tl.zrow = x ;
00526 }
00527 }
00528
00529 emcTowerLocation& tl = towerLocationMap[towerID] ;
00530
00531 arm = tl.arm ;
00532 sector_in_arm = tl.sector ;
00533 yrow = tl.yrow ;
00534 zrow = tl.zrow ;
00535 }
00536
00537
00538
00539
00540
00541
00542
00543
00544 void EmcIndexer::PXPXSM144CH(int PX, int& PXSM144, int& CH)
00545 {
00546 static vector<pair<int,int> > fPXPXSM144CH ;
00547 static const int PXMAX = 24768 ;
00548
00549 if (PX<0 || PX>=PXMAX) {
00550 PXSM144 = -1 ;
00551 CH = -1 ;
00552 }
00553
00554 else {
00555
00556 if (fPXPXSM144CH.empty()) {
00557
00558
00559
00560 fPXPXSM144CH.resize(PXMAX) ;
00561 int i ;
00562 int iS, iST, iSM, iSMT ;
00563 for (i=0;i<PXMAX;i++) {
00564 iPXiSiST(i,iS,iST) ;
00565 iSiSTiSMiSMT(iS,iST,iSM,iSMT);
00566 fPXPXSM144CH[i].first = iSiSM144_PXSM144(iS,iSM) ;
00567 fPXPXSM144CH[i].second = iSMTiCH(iSMT) ;
00568 }
00569 }
00570
00571 pair<int,int>& thepair = fPXPXSM144CH[PX] ;
00572
00573 PXSM144 = thepair.first ;
00574 CH = thepair.second ;
00575 }
00576 }
00577
00578
00579
00580 int
00581 EmcIndexer::sectorOfflineToOnline(int arm, int offline_sector)
00582 {
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595 int online_sector = -1 ;
00596
00597
00598 if ( arm==0 ) {
00599 online_sector = offline_sector ;
00600 }
00601 else {
00602 online_sector = ( offline_sector >= 2 ) ? offline_sector+2
00603 : offline_sector+6 ;
00604 }
00605 return online_sector ;
00606 }
00607
00608
00609
00611 bool EmcIndexer::isPbScReference(int TowerId)
00612 {
00613
00614 if(TowerId<24768) return false;
00615
00616 int absFEM=((TowerId-24768)%96)/12+172;
00617 return ( absFEM>=172 && absFEM<=175 );
00618
00619 }
00620
00622 bool EmcIndexer::isPbGlReference(int TowerId)
00623 {
00624
00625 if(TowerId<24768) return false;
00626
00627 int absFEM=((TowerId-24768)%96)/12+172;
00628 return (absFEM>=176 && absFEM<=179 );
00629 }
00630
00631
00632 void
00633 EmcIndexer::sectorOnlineToOffline(int sectorOnline, int& arm,
00634 int& offline_sector)
00635 {
00636 if ( sectorOnline < 0 || sectorOnline > 8 )
00637 {
00638 arm=-1;
00639 offline_sector=-1;
00640 }
00641
00642 if ( sectorOnline < 4 )
00643 {
00644 arm = 0;
00645 offline_sector = sectorOnline;
00646 }
00647 else if ( sectorOnline < 6 )
00648 {
00649 arm = 1;
00650 offline_sector = sectorOnline-2;
00651 }
00652 else
00653 {
00654 arm = 1;
00655 offline_sector = sectorOnline-6;
00656 }
00657 }
00658
00659
00660 void
00661 EmcIndexer::decodeSoftwareKey(int key, int& arm, int& sector,
00662 int& yrow, int& zrow)
00663 {
00664 arm = key / 100000;
00665 sector = ( key - arm * 100000 ) / 10000;
00666 yrow = ( key - arm * 100000 - sector * 10000 ) / 100;
00667 zrow = key - arm * 100000 - sector * 10000 - yrow * 100;
00668 }
00669
00670
00671 int
00672 EmcIndexer::TowerID(int arm, int sector_in_arm, int yrow, int zrow)
00673 {
00674 int iS = sectorOfflineToOnline(arm,sector_in_arm);
00675 int iST = xySTiST(iS,zrow,yrow);
00676 return iSiSTiPX(iS,iST);
00677 }
00678
00679
00680 int
00681 EmcIndexer::TowerID(int softwarekey)
00682 {
00683 int arm,sector,yrow,zrow;
00684 EmcIndexer::decodeSoftwareKey(softwarekey,arm,sector,yrow,zrow);
00685 return TowerID(arm,sector,yrow,zrow);
00686 }