CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_7/src/Geometry/EcalMapping/src/EcalElectronicsMapping.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; c-basic-offset: 8;  -*-
00002 #include "Geometry/EcalMapping/interface/EcalElectronicsMapping.h"
00003 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00004 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00005 #include "DataFormats/EcalDetId/interface/EcalTrigTowerDetId.h"
00006 
00007 
00008 #include "DataFormats/EcalDetId/interface/EcalElectronicsId.h"
00009 #include "DataFormats/EcalDetId/interface/EcalTriggerElectronicsId.h"
00010 
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "FWCore/Utilities/interface/Exception.h"
00013 #include <cassert>
00014 
00015 
00016 using boost::multi_index_container;
00017 using namespace boost::multi_index;
00018 
00019         // -----------------------------------------------------------------------
00020         //
00021         // -- Conventions :
00022         //
00023         //    DCCid and TCCid numbering : cf slides of Ph. Gras :
00024         //     in EE- : DCCid between 1 and 8.
00025         //              DCCid number 1 covers the range -30 deg < phi < 10 deg.
00026         //     in EB- : DCCid between 10 and 27.
00027         //              DCCid number 10 covers the range -10 deg < phi < 10 deg.
00028         //     in EB+:  DCCid between 28 and 45.
00029         //              DCCid number 28 covers the range -10 deg < phi < 10 deg.
00030         //     in EE+:  DCCid between 46 and 54;
00031         //              DCCid number 46 covers the range -30 deg < phi < 10 deg.
00032         //
00033         //    SMid : 1-18 correspond to EB+   (SMid 1 corresponds to DCC 28)
00034         //           19-36 correspond to EB-
00035         //
00036         // ------------------------------------------------------------------------
00037 
00038 
00039 EcalElectronicsMapping::EcalElectronicsMapping() {
00040 
00041         // Fill the map (Barrel) for the Laser Monitoring readout numbers :
00042         // Each DCC actually corresponds to 2 LMs,  ilm and ilm + 1
00043 
00044         int ilm = MIN_LM_EBM;
00045         for (int dcc=MIN_DCCID_EBM; dcc <= MAX_DCCID_EBM; dcc++) {
00046                 LaserMonitoringMap_EB[dcc] = ilm;
00047                 ilm += 2;
00048         }
00049         ilm = MIN_LM_EBP;
00050         for (int dcc=MIN_DCCID_EBP; dcc <= MAX_DCCID_EBP; dcc++) {
00051                 LaserMonitoringMap_EB[dcc] = ilm;
00052                 ilm += 2;
00053         }
00054 
00055         // Fill the map (EndCap) for the Laser Monitoring readout numbers :
00056         // Each DCC corresponds to onr LM, but DCC 8 (LM 80 and 81) and DCC 53 (LM 90 and 91)
00057 
00058         ilm = MIN_LM_EEM;
00059         for (int dcc=MIN_DCCID_EEM; dcc <= MAX_DCCID_EEM; dcc++) {
00060                 LaserMonitoringMap_EE[dcc] = ilm;
00061                 ilm += 1;
00062                 if (dcc == 8) ilm += 1;
00063         }
00064         ilm = MIN_LM_EEP;
00065         for (int dcc=MIN_DCCID_EEP; dcc <= MAX_DCCID_EEP; dcc++) {
00066                 LaserMonitoringMap_EE[dcc] = ilm;
00067                 ilm += 1;
00068                 if (dcc == 53) ilm += 1;
00069         }
00070         
00071 }
00072 
00073 
00074 int EcalElectronicsMapping::DCCid(const EBDetId& id) const 
00075 
00076         // SM id, between 1 (phi = -10 deg) and 18 in EB+
00077         // between 19 (phi = -10 deg) and 27 in EB-.
00078         // returns DCCid, currently between 10 and 27 (EB-), 28 and 45 (EB+).
00079         // For the EE case, use getElectronicsId.
00080 {
00081         int dcc = id.ism();      
00082         if (id.zside() < 0) {
00083                 dcc  += DCCID_PHI0_EBM - 19;
00084         }
00085         else {
00086                 dcc  += DCCID_PHI0_EBP -1;
00087         }
00088         return dcc;
00089 }
00090 
00091 
00092 int EcalElectronicsMapping::TCCid(const EBDetId& id) const
00093                                                                                                                      
00094         // SM id, between 1 (phi = -10 deg) and 18 in EB+
00095         // between 19 (phi = -10 deg) and 27 in EB-.
00096         // returns TCCid, currently between 37 and 54 (EB-), 55 and 72 (EB+).
00097         // For the EE case, use getEcalTriggerElectronicsId.
00098 {
00099         int tcc = id.ism();
00100         if (id.zside() < 0) {
00101                 tcc  += TCCID_PHI0_EBM - 19;
00102         }
00103         else {
00104                 tcc  += TCCID_PHI0_EBP -1;
00105         }
00106         return tcc;
00107 }
00108 
00109 
00110 
00111 int EcalElectronicsMapping::iTT(const EcalTrigTowerDetId& id) const
00112 
00113         // returns the index of a Trigger Tower within its TCC.
00114         // This is between 1 and 68 for the Barrel, and between
00115         // 1 and 32 to 34 (t.b.c.) for the EndCap.
00116 
00117 {
00118   if ( id.subDet() == EcalBarrel )
00119     {
00120       int ie = id.ietaAbs() -1;
00121       int ip;
00122       int phi = id.iphi();
00123       phi += 2;
00124       if (phi > 72) phi = phi-72;
00125       if (id.zside() < 0) {
00126         ip = (( phi -1 ) % kEBTowersInPhi ) + 1;
00127       } else {
00128         ip = kEBTowersInPhi - ((phi -1 ) % kEBTowersInPhi );
00129       }
00130                                                                                                                      
00131       return (ie * kEBTowersInPhi) + ip;
00132     }
00133   else if ( id.subDet() == EcalEndcap)   {
00134         int ie = id.ietaAbs();
00135         bool inner = (ie >= iEEEtaMinInner);
00136         if (inner) {
00137                 ie = ie - iEEEtaMinInner;
00138                 ie = ie % kEETowersInEtaPerInnerTCC;
00139         }
00140         else {
00141                 ie = ie - iEEEtaMinOuter;
00142                 ie = ie % kEETowersInEtaPerOuterTCC;
00143         }
00144                                                                                                                      
00145         int ip = id.iphi();
00146         ip = (ip + 1) % (kEETowersInPhiPerQuadrant*4); 
00147                                 // now iphi between 0 and 71,
00148                                 // with iphi=0,1,2,3 in 1st Phi sector
00149         ip = ip % kEETowersInPhiPerTCC;
00150         int itt = kEETowersInPhiPerTCC * ie + ip + 1;
00151         return itt;
00152   }
00153   else {
00154         throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::iTT. " ;
00155         return 0;
00156   }
00157 
00158 }
00159 
00160 
00161 int EcalElectronicsMapping::TCCid(const EcalTrigTowerDetId& id) const  {
00162 
00163   if ( id.subDet() == EcalBarrel )
00164     {
00165         int phi = id.iphi() +2;
00166         if (phi > 72) phi = phi-72;
00167         int tcc = ( phi - 1 ) / kEBTowersInPhi + 1;
00168         if ( id.zside() < 0 ) tcc += 18;      // now id is the SMid
00169                 if (id.zside() < 0) {
00170                         tcc  += TCCID_PHI0_EBM - 19;
00171                 }
00172                 else {
00173                         tcc  += TCCID_PHI0_EBP -1;
00174                 }
00175         return tcc;
00176     }
00177 
00178   else if ( id.subDet() == EcalEndcap )
00179     {
00180         int ie = id.ietaAbs();
00181         bool inner = (ie >= iEEEtaMinInner);
00182         int ip = id.iphi();    // iphi = 1 corresponds to 0 < phi < 5 degrees
00183         ip = (ip + 1) % (kEETowersInPhiPerQuadrant*4);  
00184                                 // now iphi between 0 and 71,
00185                                 // with iphi=0,1,2,3 in 1st Phi sector
00186         int Phiindex = ip / 4;
00187         if (inner) {
00188                 if (id.ieta()> 0) Phiindex += TCCID_PHI0_EEP_IN;
00189                 else Phiindex += TCCID_PHI0_EEM_IN;
00190         }
00191         else {
00192                 if (id.ieta() > 0) Phiindex += TCCID_PHI0_EEP_OUT;
00193                 else Phiindex += TCCID_PHI0_EEM_OUT;
00194         }
00195         return Phiindex;
00196     }
00197   else {
00198         throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::TCCid.";
00199         return 0;
00200   }
00201 }
00202 
00203 
00204 
00205 int EcalElectronicsMapping::DCCid(const EcalTrigTowerDetId& id) const  {
00206 
00207         // This is needed for digitoraw. For a given Trigger Tower,
00208         // one needs to know to which FED it gets written.
00209 
00210   if ( id.subDet() == EcalBarrel )
00211     {
00212         int phi = id.iphi() +2;
00213         if (phi > 72) phi = phi-72;
00214         int dcc = ( phi - 1 ) / kEBTowersInPhi + 1;
00215         if ( id.zside() < 0 ) dcc += 18;      // now id is the SMid
00216                 if (id.zside() < 0) {
00217                         dcc  += DCCID_PHI0_EBM - 19;
00218                 }
00219                 else {
00220                         dcc  += DCCID_PHI0_EBP -1;
00221                 }
00222         return dcc;
00223     }
00224   else if ( id.subDet() == EcalEndcap) 
00225     {                   //FIXME :  yes I need to improve this part of the code...
00226         int tccid = TCCid(id);
00227         int dcc=0;
00228         int offset = 0;
00229         if (tccid >= 73) {
00230                 tccid = tccid-72;
00231                 offset = 45;
00232         }
00233         if (tccid == 24 || tccid == 25 || tccid == 6 || tccid == 7)  dcc=4;
00234         if (tccid == 26 || tccid == 27 || tccid == 8 || tccid == 9)  dcc=5;
00235         if (tccid == 28 || tccid == 29 || tccid == 10 || tccid == 11)  dcc=6;
00236         if (tccid == 30 || tccid == 31 || tccid == 12 || tccid == 13)  dcc=7;
00237         if (tccid == 32 || tccid == 33 || tccid == 14 || tccid == 15)  dcc=8;
00238         if (tccid == 34 || tccid == 35 || tccid == 16 || tccid == 17)  dcc=9;
00239         if (tccid == 36 || tccid == 19 || tccid == 18 || tccid == 1)  dcc=1;
00240         if (tccid == 20 || tccid == 21 || tccid == 2 || tccid == 3)  dcc=2;
00241         if (tccid == 22 || tccid == 23 || tccid == 4 || tccid == 5)  dcc=3;
00242         dcc += offset;
00243         return dcc;
00244     }
00245   else {
00246         throw cms::Exception("InvalidDetId") << " Wrong EcalTrigTowerDetId in EcalElectronicsMapping::DCCid.";
00247         return 0;
00248   }
00249 
00250 }
00251 
00252 EcalTrigTowerDetId EcalElectronicsMapping::getTrigTowerDetId(int TCCid, int iTT) const {
00253         
00254         // needed for unpacking code.
00255 
00256    EcalSubdetector sub = subdet(TCCid, TCCMODE);
00257    int zIndex = zside(TCCid, TCCMODE);
00258 
00259    if (sub == EcalBarrel) {
00260 
00261         int DCCid =0;
00262         int jtower = iTT-1;
00263         if (zIndex > 0) DCCid = TCCid - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
00264         else DCCid = TCCid - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
00265         int SMid = (zIndex > 0) ? DCCid - 27 : DCCid + 9;
00266 
00267         int etaTT = jtower / kTowersInPhi +1;   // between 1 and 17
00268         int phiTT;
00269                                                                                                                      
00270         if (zIndex > 0)
00271            phiTT=(SMid - 1) * kTowersInPhi + (kTowersInPhi -(jtower % kTowersInPhi)) -1;
00272         else
00273            phiTT=(SMid - 19)* kTowersInPhi + jtower % kTowersInPhi;
00274         phiTT ++;
00275         phiTT = phiTT -2;
00276         if (phiTT <= 0) phiTT = 72+phiTT;
00277         EcalTrigTowerDetId tdetid(zIndex, EcalBarrel, etaTT, phiTT,EcalTrigTowerDetId::SUBDETIJMODE);
00278         return tdetid;
00279    }
00280 
00281    else if (sub == EcalEndcap) {
00282 
00283         bool EEminus = (zIndex <0);
00284         bool EEplus  = (zIndex >0);     
00285         if ( (!EEminus) && (!EEplus) )
00286                 throw cms::Exception("InvalidDetId") <<
00287                 "EcalElectronicsMapping:  Cannot create EcalTrigTowerDetId object. " ;
00288         int iz = 0;
00289         int tcc = TCCid;
00290         if (tcc < TCCID_PHI0_EEM_OUT+kTCCinPhi) iz = -1;
00291         else if (tcc >= TCCID_PHI0_EEP_OUT) iz = +1;
00292 
00293         bool inner = false;
00294         if (iz < 0 && tcc >= TCCID_PHI0_EEM_IN && tcc < TCCID_PHI0_EEM_IN+kTCCinPhi) inner=true;
00295         if (iz > 0 && tcc >= TCCID_PHI0_EEP_IN && tcc < TCCID_PHI0_EEP_IN+kTCCinPhi) inner=true;
00296         bool outer = !inner;
00297 
00298         int ieta = (iTT-1) / kEETowersInPhiPerTCC;
00299         int iphi = (iTT-1) % kEETowersInPhiPerTCC;
00300         if (inner) ieta += iEEEtaMinInner;
00301         else ieta += iEEEtaMinOuter;
00302         if (iz < 0) ieta = -ieta;
00303 
00304         int TCC_origin = 0;
00305         if (inner && iz < 0) TCC_origin=TCCID_PHI0_EEM_IN;
00306         if (outer && iz < 0) TCC_origin=TCCID_PHI0_EEM_OUT;
00307         if (inner && iz > 0) TCC_origin=TCCID_PHI0_EEP_IN;
00308         if (outer && iz > 0) TCC_origin=TCCID_PHI0_EEP_OUT;
00309         tcc = tcc - TCC_origin;
00310 
00311         iphi += kEETowersInPhiPerTCC * tcc;
00312         iphi = (iphi -2 + 4*kEETowersInPhiPerQuadrant) % (4*kEETowersInPhiPerQuadrant) + 1;
00313 
00314         int tower_i = abs(ieta);
00315         int tower_j = iphi;
00316         
00317         EcalTrigTowerDetId tdetid(zIndex, EcalEndcap, tower_i, tower_j,EcalTrigTowerDetId::SUBDETIJMODE);
00318         return tdetid;
00319 
00320    }
00321   else {
00322         throw cms::Exception("InvalidDetId") << 
00323                 " Wrong indices in EcalElectronicsMapping::getTrigTowerDetId. TCCid = " << TCCid << " iTT = " << iTT << ".";
00324   }
00325 
00326 
00327 }
00328 
00329 
00330 
00331 
00332 
00333 EcalElectronicsId EcalElectronicsMapping::getElectronicsId(const DetId& id) const {
00334 
00335   EcalSubdetector subdet = EcalSubdetector(id.subdetId());
00336   if (subdet == EcalBarrel) {
00337         const EBDetId ebdetid = EBDetId(id);
00338 
00339         int dcc = DCCid(ebdetid);
00340         bool EBPlus = (zside(dcc,DCCMODE) > 0);
00341         bool EBMinus = !EBPlus;
00342 
00343         EcalTrigTowerDetId trigtower = ebdetid.tower();
00344         // int tower = trigtower.iTT();
00345         int tower = iTT(trigtower);
00346 
00347         int ieta = EBDetId(id).ietaAbs();
00348         int iphi = EBDetId(id).iphi();
00349         int strip(0);
00350         int channel(0);
00351         bool RightTower = rightTower(tower);
00352         if (RightTower) {
00353                 strip = (ieta-1)%5;
00354                 if (strip%2 == 0) {
00355                         if (EBMinus) channel = (iphi-1) %5;
00356                         if (EBPlus) channel = 4 -( (iphi-1) %5 );
00357                 }
00358                 else {
00359                         if (EBMinus) channel = 4 -( (iphi-1) %5 ); 
00360                         if (EBPlus) channel = (iphi-1) %5;
00361                 }
00362         }
00363         else {
00364                 strip = 4 - ( (ieta-1)%5 );
00365                 if (strip%2 == 0) {
00366                         if (EBMinus) channel = 4 -( (iphi-1) %5 );
00367                         if (EBPlus) channel = (iphi-1) %5;
00368                 }
00369                 else {
00370                         if (EBMinus) channel = (iphi-1) %5;
00371                         if (EBPlus) channel = 4 -( (iphi-1) %5 );
00372                 }
00373         }
00374         strip += 1;
00375         channel += 1;
00376         
00377         EcalElectronicsId elid = EcalElectronicsId(dcc,tower,strip,channel);
00378         
00379         return elid;
00380   }
00381   else if (subdet == EcalEndcap) {
00382         EcalElectronicsMap_by_DetId::const_iterator it=get<0>(m_items).find(id);
00383         if(it==get<0>(m_items).end())  
00384           { EcalElectronicsId elid(0);
00385             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
00386             return elid; }
00387         EcalElectronicsId elid = it -> elid;
00388         return elid;
00389   }
00390   else {
00391         throw cms::Exception("InvalidDetId") <<
00392                 " Wrong DetId in EcalElectronicsMapping::getElectronicsId.";
00393   }
00394 
00395 }
00396 
00397 
00398 EcalTriggerElectronicsId EcalElectronicsMapping::getTriggerElectronicsId(const DetId& id) const {
00399   EcalSubdetector subdet = EcalSubdetector(id.subdetId());
00400 
00401   if (subdet == EcalBarrel) {
00402 
00403         const EcalElectronicsId& elid = getElectronicsId(id);
00404         EcalTriggerElectronicsId trelid = getTriggerElectronicsId(elid);
00405         return trelid;
00406   }
00407   else if (subdet == EcalEndcap) {
00408         EcalElectronicsMap_by_DetId::const_iterator it=get<0>(m_items).find(id);
00409         if(it==get<0>(m_items).end())  
00410           { EcalTriggerElectronicsId trelid(0);
00411             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid trig id";
00412             return trelid; }
00413         EcalTriggerElectronicsId trelid = it -> trelid;
00414         return trelid;
00415   }
00416   else {
00417         throw cms::Exception("InvalidDetId") <<
00418                 " Wrong DetId in EcalElectronicsMapping::getTriggerElectronicsId.";
00419   }
00420 }
00421 
00422 
00423 DetId EcalElectronicsMapping::getDetId(const EcalElectronicsId& id) const {
00424   EcalSubdetector subdet = id.subdet();
00425 
00426   if (subdet == EcalBarrel) {
00427         int dcc = id.dccId();
00428         int tower = id.towerId();
00429         int strip = id.stripId();
00430         int channel = id.xtalId();
00431                                                                                                            
00432         int smid = 0;
00433         int iphi = 0;
00434         bool EBPlus = (id.zside() > 0);
00435         bool EBMinus = !EBPlus;
00436 
00437         if (id.zside() < 0) {
00438                 smid = dcc + 19 - DCCID_PHI0_EBM;
00439                 iphi = (smid - 19) * kCrystalsInPhi;
00440                 iphi += 5 * ( (tower-1) % kTowersInPhi );
00441         }
00442         else {
00443                 smid = dcc +1 - DCCID_PHI0_EBP;
00444                 iphi = (smid - 1) * kCrystalsInPhi;
00445                 iphi += 5 * (
00446                         kTowersInPhi - ( (tower-1) % kTowersInPhi ) -1
00447                         );
00448         }
00449         bool RightTower = rightTower(tower);
00450         int ieta = 5 * ((tower-1) / kTowersInPhi) + 1;
00451         if (RightTower) {
00452                 ieta += (strip-1);
00453                 if (strip%2 == 1) {
00454                         if (EBMinus) iphi += (channel-1) +1;
00455                         if (EBPlus) iphi += (4 - (channel-1)) +1;
00456                 }
00457                 else {
00458                         if (EBMinus) iphi += (4 - (channel-1)) +1;
00459                         if (EBPlus) iphi += (channel-1) +1;
00460                 }
00461         }
00462         else {
00463                 ieta += 4 - (strip-1);
00464                 if (strip%2 == 1) {
00465                         if (EBMinus) iphi += (4 - (channel-1)) +1;
00466                         if (EBPlus) iphi += (channel-1) +1;
00467                 }
00468                 else {
00469                         if (EBMinus) iphi += (channel-1) +1;
00470                         if (EBPlus) iphi += (4 - (channel-1)) +1;
00471                 }
00472         }
00473         if (id.zside() < 0) ieta = -ieta;
00474 
00475         EBDetId e(ieta,iphi,EBDetId::ETAPHIMODE);
00476         return e;
00477   }
00478 
00479   else if (subdet == EcalEndcap) {
00480         EcalElectronicsMap_by_ElectronicsId::const_iterator it=get<1>(m_items).find(id);
00481         if(it==(get<1>(m_items).end()))  
00482           { DetId cell(0);
00483             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non DetId";
00484             return cell; }
00485         DetId cell = it -> cell;
00486         return cell;
00487   }
00488   else throw cms::Exception("InvalidDetId") << "Wrong EcalElectronicsId in EcalElectronicsMapping::getDetId." ;
00489 }
00490 
00491 
00492 EcalTriggerElectronicsId EcalElectronicsMapping::getTriggerElectronicsId(const EcalElectronicsId& id) const {
00493 
00494   EcalSubdetector subdet = id.subdet();
00495 
00496   if (subdet == EcalBarrel) {
00497         int strip = id.stripId();
00498         int xtal = id.xtalId();
00499         int tower = id.towerId();
00500         int tcc = id.dccId();
00501         if (id.zside() < 0) {
00502                 tcc  += TCCID_PHI0_EBM - DCCID_PHI0_EBM;
00503         }
00504         else {
00505                 tcc  += TCCID_PHI0_EBP - DCCID_PHI0_EBP;
00506         }
00507         EcalTriggerElectronicsId trelid(tcc,tower,strip,xtal);
00508         return trelid;
00509 
00510   }
00511   else if (subdet == EcalEndcap) {
00512         EcalElectronicsMap_by_ElectronicsId::const_iterator it=get<1>(m_items).find(id);
00513         if(it==get<1>(m_items).end())  
00514           { EcalTriggerElectronicsId trelid(0);
00515             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
00516             return trelid; }
00517         EcalTriggerElectronicsId trelid = it -> trelid;
00518         return trelid;
00519   }
00520   else throw cms::Exception("InvalidDetId") << "Wrong EcalElectronicsId in EcalElectronicsMapping::getTriggerElectronicsId.";
00521 }
00522 
00523 
00524 DetId EcalElectronicsMapping::getDetId(const EcalTriggerElectronicsId& id) const {
00525 
00526   EcalSubdetector subdet = id.subdet();
00527 
00528   if (subdet == EcalBarrel) {
00529         const EcalElectronicsId& elid = getElectronicsId(id); 
00530         DetId cell = getDetId(elid);    
00531         return cell;
00532   }
00533   else if (subdet == EcalEndcap) {
00534         EcalElectronicsMap_by_TriggerElectronicsId::const_iterator it=get<2>(m_items).find(id);
00535         if(it==get<2>(m_items).end())  
00536           { DetId cell(0);
00537             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid DetId";
00538             return cell; }
00539         DetId cell = it -> cell;
00540         return cell;
00541   }
00542   else throw cms::Exception("InvalidDetId") << "Wrong EcalTriggerElectronicsId in EcalElectronicsMapping::getDetId." ;
00543 }
00544 
00545 
00546 
00547 EcalElectronicsId EcalElectronicsMapping::getElectronicsId(const EcalTriggerElectronicsId& id) const {
00548 
00549   EcalSubdetector subdet = id.subdet();
00550 
00551   if (subdet == EcalBarrel) {
00552         int strip = id.pseudoStripId();
00553         int xtal = id.channelId();
00554         int tower = id.ttId();
00555         int dcc = id.tccId();
00556         if (id.zside() < 0) {
00557                 dcc  -= TCCID_PHI0_EBM - DCCID_PHI0_EBM;
00558         }
00559         else {
00560                 dcc  -= TCCID_PHI0_EBP - DCCID_PHI0_EBP;
00561         }
00562         EcalElectronicsId elid(dcc,tower,strip,xtal);
00563         return elid;
00564   }
00565   else if (subdet == EcalEndcap) {
00566         EcalElectronicsMap_by_TriggerElectronicsId::const_iterator it=get<2>(m_items).find(id);
00567         if(it==get<2>(m_items).end())  
00568           { EcalElectronicsId elid(0);
00569             edm::LogError("EcalElectronicsMapping") << "Ecal mapping was asked non valid id";
00570             return elid; }
00571         EcalElectronicsId elid = it -> elid;
00572         return elid;
00573   }
00574   else throw cms::Exception("InvalidDetId") << "Wrong EcalTriggerElectronicsId in EcalElectronicsMapping::getElectronicsId.";
00575 }
00576 
00577 
00578 
00579 
00580 std::vector<DetId> EcalElectronicsMapping::dccConstituents(int dccId) const {
00581 
00582   EcalSubdetector sub = subdet(dccId,DCCMODE);
00583   std::vector<DetId> items;
00584 
00585   if (sub == EcalBarrel) { 
00586         for (int tower=1; tower <= kEBTowersPerSM; tower++) {
00587                 std::vector<DetId> xtals = dccTowerConstituents(dccId,tower);
00588                 int size = xtals.size();
00589                 for (int i=0; i < size; i++) {
00590                         DetId detid = xtals[i];
00591                         items.push_back(detid);
00592                 }
00593         }
00594         return items; 
00595   }
00596   else if (sub == EcalEndcap) {
00597         EcalElectronicsMap_by_DccId::const_iterator lb,ub;
00598         boost::tuples::tie(lb,ub)=get<3>(m_items).equal_range(dccId);
00599         while (lb != ub) {
00600                 DetId cell = lb -> cell;
00601                 items.push_back(cell);
00602                 ++ lb;
00603         }
00604         return items;
00605   }
00606   else throw cms::Exception("InvalidDetId") << "Wrong dccId = " << dccId << " in EcalElectronicsMapping::dccConstituents. ";
00607 }
00608 
00609 
00610 
00611 std::vector<DetId> EcalElectronicsMapping::dccTowerConstituents(int dccId, int tower) const {
00612 
00613   EcalSubdetector sub = subdet(dccId,DCCMODE);
00614   std::vector<DetId> items;
00615 
00616   if (sub == EcalBarrel) {
00617         int iz = zside(dccId, DCCMODE);
00618         int smid = 0;
00619         int iphi = 0;
00620         if (iz < 0) {
00621                 smid = dccId + 19 - DCCID_PHI0_EBM;
00622                 iphi = (smid - 19) * kCrystalsInPhi;
00623                 iphi += 5 * ( (tower-1) % kTowersInPhi );
00624         }
00625         else {
00626                 smid = dccId +1 - DCCID_PHI0_EBP;
00627                 iphi = (smid - 1) * kCrystalsInPhi;
00628                 iphi += 5 * (
00629                         kTowersInPhi - ( (tower-1) % kTowersInPhi ) -1
00630                         );
00631         }
00632         int ieta = 5 * ((tower-1) / kTowersInPhi) + 1;
00633         for (int ip=1; ip <=5; ip++) {
00634          for (int ie=0; ie <=4; ie++) {
00635                 int ieta_xtal = ieta + ie;
00636                 int iphi_xtal = iphi + ip;
00637                 if (iz < 0) ieta_xtal = -ieta_xtal;
00638                 EBDetId ebdetid(ieta_xtal,iphi_xtal,EBDetId::ETAPHIMODE);
00639                 items.push_back(ebdetid);
00640          }
00641         }
00642         return items;
00643   }
00644 
00645   else if (sub == EcalEndcap) {
00646         EcalElectronicsMap_by_DccId_and_TowerId::const_iterator lb,ub;
00647         boost::tuples::tie(lb,ub)=get<4>(m_items).equal_range(boost::make_tuple(int(dccId), int(tower)));
00648         while (lb != ub) {
00649                 DetId cell = lb -> cell;
00650                 items.push_back(cell);
00651                 ++ lb;
00652         }
00653         return items;
00654   }
00655   else throw cms::Exception("InvalidDetId") << 
00656         "Wrong dccId = " << dccId << " tower = " << tower << " in EcalElectronicsMapping::dccTowerConstituents.";
00657 }
00658 
00659 
00660 
00661 std::vector<DetId> EcalElectronicsMapping::stripConstituents(int dccId, int tower, int strip) const {
00662 
00663   EcalSubdetector sub = subdet(dccId,DCCMODE);
00664   std::vector<DetId> items;
00665 
00666   if (sub == EcalBarrel) {
00667 
00668         int iz = zside(dccId, DCCMODE);
00669         bool RightTower = rightTower(tower);
00670         int smid = 0;
00671         int iphi = 0;
00672         if (iz < 0) {
00673                 smid = dccId + 19 - DCCID_PHI0_EBM;
00674                 iphi = (smid - 19) * kCrystalsInPhi;
00675                 iphi += 5 * ( (tower-1) % kTowersInPhi );
00676         }
00677         else {
00678                 smid = dccId +1 - DCCID_PHI0_EBP;
00679                 iphi = (smid - 1) * kCrystalsInPhi;
00680                 iphi += 5 * (
00681                         kTowersInPhi - ( (tower-1) % kTowersInPhi ) -1
00682                         );
00683         }
00684         int ieta = 5 * ((tower-1) / kTowersInPhi) + 1;
00685         if (RightTower) {
00686                 ieta += (strip-1);
00687         }
00688         else {
00689                 ieta += 4 - (strip-1);
00690         }
00691         for (int ip=1; ip <=5; ip++) {
00692                 int ieta_xtal = ieta ;
00693                 int iphi_xtal = iphi + ip;
00694                 if (iz < 0) ieta_xtal = -ieta_xtal;
00695                 EBDetId ebdetid(ieta_xtal,iphi_xtal,EBDetId::ETAPHIMODE);
00696                 items.push_back(ebdetid);
00697         }
00698 
00699         return items;
00700   }
00701   else {
00702         EcalElectronicsMap_by_DccId_TowerId_and_StripId::const_iterator lb,ub;
00703         boost::tuples::tie(lb,ub)=get<5>(m_items).equal_range(boost::make_tuple(int(dccId), int(tower), int(strip)));
00704         while (lb != ub) {
00705                 DetId cell = lb -> cell;
00706                 items.push_back(cell);
00707                 ++ lb;
00708         }
00709         return items;
00710   }
00711   
00712 }
00713 
00714 
00715 std::vector<DetId> EcalElectronicsMapping::tccConstituents(int tccId) const {
00716 
00717   EcalSubdetector sub = subdet(tccId,TCCMODE);
00718   std::vector<DetId> items;
00719 
00720   if (sub == EcalBarrel) {
00721         int iz =  zside(tccId,TCCMODE);
00722         int dccId = tccId;
00723         if (iz > 0) dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
00724         else dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
00725         items = dccConstituents(dccId); 
00726         return items;
00727   }
00728   else {
00729         EcalElectronicsMap_by_TccId::const_iterator lb,ub;
00730         boost::tuples::tie(lb,ub)=get<6>(m_items).equal_range(tccId);
00731         while (lb != ub) {
00732                 DetId cell = lb -> cell;
00733                 items.push_back(cell);
00734                 ++ lb;
00735         }
00736         return items;
00737   }
00738 }
00739 
00740 
00741 
00742 std::vector<DetId> EcalElectronicsMapping::ttConstituents(int tccId, int tt) const {
00743 
00744   EcalSubdetector sub = subdet(tccId,TCCMODE);
00745   std::vector<DetId> items;
00746 
00747   if (sub == EcalBarrel) {
00748         int iz =  zside(tccId,TCCMODE);
00749         int dccId = tccId;
00750         if (iz > 0) dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
00751         else dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
00752         items = dccTowerConstituents(dccId,tt);
00753         return items;
00754   }
00755   else {
00756         EcalElectronicsMap_by_TccId_and_TtId::const_iterator lb,ub;
00757         boost::tuples::tie(lb,ub)=get<7>(m_items).equal_range(boost::make_tuple(int(tccId), int(tt)));
00758         while (lb != ub) {
00759                 DetId cell = lb -> cell;
00760                 items.push_back(cell);
00761                 ++ lb;
00762         }
00763         return items;
00764   }
00765 }
00766 
00767 
00768 std::vector<DetId> EcalElectronicsMapping::pseudoStripConstituents(int tccId, int tt, int pseudostrip) const {
00769 
00770   EcalSubdetector sub = subdet(tccId,TCCMODE);
00771   std::vector<DetId> items;
00772 
00773   if (sub == EcalBarrel) {
00774         int iz =  zside(tccId,TCCMODE);
00775         int dccId = tccId;
00776         if (iz > 0) dccId = dccId - TCCID_PHI0_EBP + DCCID_PHI0_EBP;
00777         else dccId = dccId - TCCID_PHI0_EBM + DCCID_PHI0_EBM;
00778         items = stripConstituents(dccId,tt,pseudostrip);
00779         return items;
00780   }
00781   else {
00782         EcalElectronicsMap_by_TccId_TtId_and_PseudostripId::const_iterator lb,ub;
00783         boost::tuples::tie(lb,ub)=get<8>(m_items).equal_range(boost::make_tuple(int(tccId), int(tt), int(pseudostrip)));
00784         while (lb != ub) {
00785                 DetId cell = lb -> cell;
00786                 items.push_back(cell);
00787                 ++ lb;
00788         }
00789         return items;
00790   }
00791 }
00792 
00793 void EcalElectronicsMapping::assign(const DetId& cell, const EcalElectronicsId& elid, const EcalTriggerElectronicsId& tower) {
00794 
00795         m_items.insert(MapItem(cell, elid, tower));
00796 }
00797 
00798 
00799 std::pair<int, int> EcalElectronicsMapping::getDCCandSC(EcalScDetId id) const {
00800 
00801 // pair.first = DCC id
00802 // pair.second = DCC_channel
00803 // For digi2raw, read the SRflags and write the SR block :
00804 // need to find out, for an EcalScDetId, which is the DCC and the DCC_channel
00805 
00806         std::pair<int,int> ind;
00807         EEDetId dum;
00808         int ix = id.ix();
00809         int iy = id.iy();
00810         int zside = id.zside();
00811         ix = (ix-1)*5 +1;
00812         iy = (iy-1)*5 +1;
00813         ix = 5 * (ix/5) +1;
00814         iy = 5 * (iy/5) +1;
00815         int ix_c = ix;
00816         int iy_c = iy;
00817         if (! dum.validDetId(ix_c,iy_c,zside) ) {
00818             ix_c = ix +4;
00819             iy_c = iy ;
00820             if ( ! dum.validDetId(ix_c,iy_c,zside) ) {
00821              ix_c = ix +4;
00822              iy_c = iy +4;
00823              if ( ! dum.validDetId(ix_c,iy_c,zside) ) {
00824               ix_c = ix;
00825               iy_c = iy +4;
00826              }
00827             }
00828         }
00829         EEDetId eedetid(ix_c,iy_c,zside,EEDetId::XYMODE);
00830         EcalElectronicsId elid = getElectronicsId(eedetid);
00831         int Dccid = elid.dccId();
00832         int DCC_Channel = elid.towerId();
00833         ind.first = Dccid;
00834         ind.second = DCC_Channel;
00835         return ind;
00836 }
00837 
00838 
00839 
00840 std::vector<EcalScDetId> EcalElectronicsMapping::getEcalScDetId(int DCCid, int DCC_Channel, bool ignoreSingleCrystal) const {
00841         //Debug output switch:
00842         const bool debug = false;
00843         
00844         // For unpacking of ST flags.
00845         //result: SCs readout by the DCC channel DCC_channel of DCC DCCid.
00846         //Vector of 1 or 2 elements: most of the time there is only
00847         //one SC read-out by the DCC channel, but for some channels
00848         //there are 2 partial SCs which were grouped.
00849         std::vector<EcalScDetId> scDetIds;
00850 
00851         //There are 4 SCs in each endcap whose one crystal is read out
00852         //by a different DCC channel than the others.
00853         //Number of crystals of the SC read out by the DCC channel:
00854         std::vector<int> nReadoutXtals;
00855         
00856         std::vector<DetId> xtals = dccTowerConstituents(DCCid, DCC_Channel);
00857 
00858         if(debug){
00859                 std::cout << __FILE__ << ":" << __LINE__ << ": " << xtals.size()
00860                           << " crystals read out by channel " <<  DCC_Channel << " of DCC "
00861                           << DCCid << ": ";
00862                 for(size_t i = 0; i < xtals.size(); ++i){
00863                         std::cout << EEDetId(xtals[i]) << " ";
00864                 }
00865                 std::cout << "\n";
00866         }
00867         
00868         if (xtals.size() == 0) throw cms::Exception("InvalidDetId") << 
00869                                        "EcalElectronicsMapping : can not create EcalScDetId for DCC " << DCCid << 
00870                                        " and DCC_Channel " << DCC_Channel << ".";
00871         
00872         for(size_t iXtal = 0; iXtal < xtals.size(); ++iXtal){
00873                 EEDetId eedetid = xtals[iXtal];
00874                 int ix = eedetid.ix();
00875                 int iy = eedetid.iy();
00876                 int iz = eedetid.zside();
00877                 int ix_SC = (ix-1)/5 + 1;
00878                 int iy_SC = (iy-1)/5 + 1;
00879                 //Supercrystal (SC) the crystal belongs to:
00880                 EcalScDetId scdetid(ix_SC,iy_SC,iz);
00881                 size_t iSc = 0;
00882                 //look if the SC was already included:
00883                 while(iSc < scDetIds.size() && scDetIds[iSc] != scdetid) ++iSc;
00884                 if(iSc==scDetIds.size()){//SC not yet included
00885                         scDetIds.push_back(scdetid);
00886                         nReadoutXtals.push_back(1); //crystal counter of the added SC
00887                 } else{//SC already included
00888                         ++nReadoutXtals[iSc];// counting crystals in the SC
00889                 }
00890         }
00891         
00892         if(ignoreSingleCrystal){
00893                 //For simplification, SC read out by two different DCC channels
00894                 //will be associated to the DCC channel reading most of the crystals,
00895                 //the other DCC channel which read only one crystal is discarded.
00896                 //Discards SC with only one crystal read out by the considered,
00897                 //DCC channel:
00898                 assert(scDetIds.size()==nReadoutXtals.size());
00899                 for(size_t iSc = 0; iSc < scDetIds.size(); /*NOOP*/){
00900                         if(nReadoutXtals[iSc]<=1){
00901                                 if(debug) std::cout << "EcalElectronicsMapping::getEcalScDetId: Ignore SC "
00902                                                     << scDetIds[iSc] << " whose only one channel is read out by "
00903                                                   "the DCC channel (DCC " << DCCid << ", ch " << DCC_Channel<< ").\n";
00904                                 scDetIds.erase(scDetIds.begin()+iSc);
00905                                 nReadoutXtals.erase(nReadoutXtals.begin()+iSc);
00906                         } else{
00907                                 ++iSc; //next SC;
00908                         }
00909                 }
00910         }
00911          
00912         return scDetIds;
00913 }
00914 
00915 
00916 
00917 EcalSubdetector EcalElectronicsMapping::subdet(int dcctcc, int mode) const {
00918   if (mode == DCCMODE) {
00919         if ( (dcctcc >= MIN_DCCID_EBM && dcctcc <= MAX_DCCID_EBM) ||
00920              (dcctcc >= MIN_DCCID_EBP && dcctcc <= MAX_DCCID_EBP) ) return EcalBarrel;
00921         else return EcalEndcap;
00922   }
00923   else if (mode == TCCMODE) {
00924         if ( (dcctcc >= MIN_TCCID_EBM && dcctcc <= MAX_TCCID_EBM) ||
00925              (dcctcc >= MIN_TCCID_EBP && dcctcc <= MAX_TCCID_EBP) ) return EcalBarrel;
00926         else return EcalEndcap;
00927   }
00928   else throw cms::Exception("InvalidDetId") << " Wrong mode in EcalElectronicsMapping::subdet " << mode << ".";
00929 }
00930 
00931 
00932 int EcalElectronicsMapping::zside(int dcctcc, int mode) const {
00933   if (mode == DCCMODE) {
00934         if (dcctcc >= MIN_DCCID_EBM && dcctcc <= MAX_DCCID_EBM) return -1;
00935         if (dcctcc >= MIN_DCCID_EBP && dcctcc <= MAX_DCCID_EBP) return +1;
00936         if (dcctcc >= MIN_DCCID_EEM && dcctcc <= MAX_DCCID_EEM) return -1;
00937         if (dcctcc >= MIN_DCCID_EEP && dcctcc <= MAX_DCCID_EEP) return +1; 
00938   }
00939   else if (mode == TCCMODE) {
00940         if (dcctcc >= MIN_TCCID_EBM && dcctcc <= MAX_TCCID_EBM) return -1;
00941         if (dcctcc >= MIN_TCCID_EBP && dcctcc <= MAX_TCCID_EBP) return +1;
00942         if (dcctcc >= MIN_TCCID_EEM && dcctcc <= MAX_TCCID_EEM) return -1;
00943         if (dcctcc >= MIN_TCCID_EEP && dcctcc <= MAX_TCCID_EEP) return +1;
00944   }
00945   else {
00946         throw cms::Exception("InvalidDetId") << " Wrong mode in EcalElectronicsMapping::zside " << mode << ".";
00947   }
00948   return 0;
00949 }
00950 
00951 
00952 
00953 bool EcalElectronicsMapping::rightTower(int tower) const {
00954         // for EB, two types of tower (LVRB top/bottom)
00955 
00956   if ((tower>12 && tower<21) || (tower>28 && tower<37) ||
00957        (tower>44 && tower<53) || (tower>60 && tower<69))
00958     return true;
00959   else
00960     return false;
00961 }
00962 
00963 
00964 int EcalElectronicsMapping::DCCBoundary(int FED)const {
00965 
00966  if (FED >= MIN_DCCID_EEM && FED <= MAX_DCCID_EEM) return MIN_DCCID_EEM;
00967  if (FED >= MIN_DCCID_EBM && FED <= MAX_DCCID_EBM) return MIN_DCCID_EBM;
00968  if (FED >= MIN_DCCID_EBP && FED <= MAX_DCCID_EBP) return MIN_DCCID_EBP;
00969  if (FED >= MIN_DCCID_EEP && FED <= MAX_DCCID_EEP) return MIN_DCCID_EEP;
00970  return -1;
00971 
00972 }
00973 
00974 
00975 std::vector<int> EcalElectronicsMapping::GetListofFEDs(const EcalEtaPhiRegion region) const {
00976   std::vector<int> FEDs;
00977   GetListofFEDs(region, FEDs);
00978   return FEDs;
00979 }
00980 void EcalElectronicsMapping::GetListofFEDs(const EcalEtaPhiRegion region, std::vector<int> & FEDs) const {
00981 
00982         // for regional unpacking.
00983         // get list of FEDs corresponding to a region in (eta,phi)
00984 
00985   //    std::vector<int> FEDs;
00986         double radTodeg = 180. / Geom::pi();
00987 
00988         bool debug = false;
00989 
00990         double etalow = region.etaLow();
00991         double philow = region.phiLow() * radTodeg;
00992         if (debug) std::cout << " etalow philow " << etalow << " " << philow << std::endl;
00993         int FED_LB = GetFED(etalow,philow);     // left, bottom
00994 
00995         double phihigh = region.phiHigh() * radTodeg;
00996         if (debug) std::cout << " etalow phihigh " << etalow << " " << phihigh << std::endl;
00997         int FED_LT = GetFED(etalow,phihigh);    // left, top
00998 
00999         int DCC_BoundaryL = DCCBoundary(FED_LB);
01000         int deltaL = 18;
01001         if (FED_LB < MIN_DCCID_EBM || FED_LB > MAX_DCCID_EBP) deltaL=9;
01002 
01003         if (philow < -170 && phihigh > 170) {
01004                 FED_LB = DCC_BoundaryL;
01005                 FED_LT = DCC_BoundaryL + deltaL -1;
01006         }
01007         if (debug) std::cout << " FED_LB FED_LT " << FED_LB << " " << FED_LT << std::endl;
01008 
01009 
01010         int iL=FED_LB;
01011         bool dummy = true;
01012         int idx = 0;
01013         while (  dummy ) {
01014                 iL = (FED_LB - DCC_BoundaryL + idx ) % deltaL + DCC_BoundaryL;
01015                 FEDs.push_back(iL);
01016                 if (debug) std::cout << "   add fed " << iL << std::endl;
01017                 if ( iL == FED_LT) break;
01018                 idx ++;
01019         }
01020  
01021         double etahigh = region.etaHigh();
01022         int FED_RB = GetFED(etahigh, philow);   // right, bottom
01023         if (FED_RB == FED_LB) return;// FEDs;
01024 
01025         int FED_RT = GetFED(etahigh, phihigh);  // right, top
01026 
01027         if (debug) std::cout << "etahigh philow phihigh " << etahigh << " " << philow << " " << phihigh << std::endl;
01028         int DCC_BoundaryR = DCCBoundary(FED_RB);
01029         int deltaR = 18;
01030         if (FED_RB < MIN_DCCID_EBM || FED_RB > MAX_DCCID_EBP) deltaR=9;
01031 
01032         if (philow < -170 && phihigh > 170) {
01033                 FED_RB = DCC_BoundaryR;
01034                 FED_RT = DCC_BoundaryR + deltaR-1;
01035         }
01036         if (debug) std::cout << " FED_RB FED_RT " << FED_RB << " " << FED_RT << std::endl;
01037 
01038         int iR=FED_RB;
01039         idx = 0;
01040         while ( dummy ) {
01041                 iR = (FED_RB - DCC_BoundaryR + idx) % deltaR + DCC_BoundaryR;
01042                 FEDs.push_back(iR);
01043                 if (debug) std::cout << "   add fed " << iR << std::endl;
01044                 if ( iR == FED_RT) break;
01045                 idx ++;
01046         }
01047 
01048 
01049         if (FED_LB >= MIN_DCCID_EBM && FED_LB <= MAX_DCCID_EBM   &&
01050             FED_RB >= MIN_DCCID_EEP && FED_RB <= MAX_DCCID_EEP) {
01051                 int minR = FED_LB + 18;
01052                 int maxR = FED_LT + 18;
01053                 int iR = minR;
01054                 int idx = 0;
01055                 while ( dummy ) {
01056                         iR = (minR - MIN_DCCID_EBP + idx) % 18 + MIN_DCCID_EBP;
01057                         FEDs.push_back(iR);
01058                         if (debug) std::cout << "   add fed " << iR << std::endl;
01059                         if ( iR == maxR) break;
01060                         idx ++;
01061                 }
01062                 return;// FEDs;
01063         }
01064 
01065         if (FED_LB >= MIN_DCCID_EEM && FED_LB <= MAX_DCCID_EEM &&
01066             FED_RB >= MIN_DCCID_EBP && FED_RB <= MAX_DCCID_EBP) {
01067                 int minL = FED_RB - 18;
01068                 int maxL = FED_RT - 18;
01069                 int iL = minL;
01070                 int idx = 0;
01071                 while ( dummy ) {
01072                         iL = (minL - MIN_DCCID_EBM + idx) % 18 + MIN_DCCID_EBM;
01073                         FEDs.push_back(iL);
01074                         if (debug) std::cout << "   add fed " << iL << std::endl;
01075                         if (iL == maxL) break;
01076                         idx ++;
01077                 }
01078                 return;// FEDs;
01079         } 
01080 
01081         if (FED_LB >= MIN_DCCID_EEM && FED_LB <= MAX_DCCID_EEM &&
01082             FED_RB >= MIN_DCCID_EEP && FED_RB <= MAX_DCCID_EEP) {
01083                 int minL = (FED_LB-1)*2 + MIN_DCCID_EBM;
01084                 if (minL == MIN_DCCID_EBM) minL=MAX_DCCID_EBM;
01085                 else minL = minL -1;
01086                 int maxL = (FED_LT-1)*2 + MIN_DCCID_EBM;
01087                 int iL = minL;
01088                 int idx = 0;
01089                 while (dummy) {
01090                         iL = (minL - MIN_DCCID_EBM + idx) % 18 + MIN_DCCID_EBM;
01091                         FEDs.push_back(iL);
01092                         if (debug) std::cout << "   add fed " << iL << std::endl;
01093                         if (iL == maxL) break;
01094                         idx ++;
01095                 }
01096                 int minR = minL + 18;
01097                 int maxR = maxL + 18;
01098                 int iR = minR;
01099                 idx = 0;
01100                 while (dummy) {
01101                         iR = (minR - MIN_DCCID_EBP + idx) % 18 + MIN_DCCID_EBP;
01102                         FEDs.push_back(iR);
01103                         if (debug) std::cout << "   add fed " << iR << std::endl;
01104                         if (iR == maxR) break;
01105                         idx ++;
01106                 }
01107         }
01108 
01109         return;// FEDs;
01110 
01111 }
01112 
01113 int EcalElectronicsMapping::GetFED(double eta, double phi) const  {
01114 
01115         // for regional unpacking.
01116         // eta is signed, phi is in degrees.
01117 
01118         int DCC_Phi0 = 0;
01119         bool IsBarrel = true;
01120         if (fabs(eta) > 1.479) IsBarrel = false;
01121         bool Positive = (eta > 0);
01122 
01123         if (IsBarrel && Positive) DCC_Phi0 = DCCID_PHI0_EBP;
01124         if (IsBarrel && (!Positive)) DCC_Phi0 = DCCID_PHI0_EBM;
01125         if ((!IsBarrel) && Positive) DCC_Phi0 = MIN_DCCID_EEP;
01126         if ((!IsBarrel) && (!Positive)) DCC_Phi0 = MIN_DCCID_EEM;
01127 
01128         // phi between 0 and 360 deg :
01129         if (phi < 0) phi += 360;
01130         if (phi > 360.) phi = 360. ;
01131         if (phi < 0) phi = 0. ;
01132 
01133         if (IsBarrel) phi = phi - 350;
01134         else phi = phi - 330;
01135         if (phi < 0) phi += 360;
01136         int iphi = -1;
01137         if (IsBarrel) iphi = (int)(phi / 20.);
01138         else iphi = (int)(phi / 40.);
01139 
01140         // std::cout << " in GetFED : phi iphi DCC0 " << phi << " " << iphi << " " << DCC_Phi0 << std::endl;
01141         
01142         int DCC = iphi + DCC_Phi0;
01143         // std::cout << "  eta phi " << eta << " " << " " << phi << " is in FED " << DCC << std::endl;
01144         return DCC;
01145 }
01146 
01147 
01148 int EcalElectronicsMapping::getLMNumber(const DetId& id) const {
01149 
01150 // Laser Monitoring readout number.
01151 
01152   EcalSubdetector subdet = EcalSubdetector(id.subdetId());
01153 
01154   if (subdet == EcalBarrel) {
01155         const EBDetId ebdetid = EBDetId(id);
01156         int dccid = DCCid(ebdetid);
01157         std::map<int, int>::const_iterator it = LaserMonitoringMap_EB.find(dccid);
01158         if (it != LaserMonitoringMap_EB.end() ) {
01159                 int ilm = it -> second;
01160                 int iETA = ebdetid.ietaSM();
01161                 int iPHI = ebdetid.iphiSM();
01162                 if (iPHI > 10 && iETA>5) {ilm ++; } ;
01163                 return ilm;
01164         } 
01165         else throw cms::Exception("InvalidDCCId") << "Wrong DCCId (EB) in EcalElectronicsMapping::getLMNumber.";
01166   }
01167 
01168   else if (subdet == EcalEndcap) {
01169         EcalElectronicsId elid = getElectronicsId(id);
01170         int dccid = elid.dccId();
01171         EEDetId eedetid = EEDetId(id);
01172         std::map<int, int>::const_iterator it = LaserMonitoringMap_EE.find(dccid);
01173         if (it != LaserMonitoringMap_EB.end() ) {
01174                 int ilm = it -> second;
01175                 if (dccid == 8) {
01176                         int ix = eedetid.ix();
01177                         if (ix > 50) ilm += 1;
01178                 }
01179                 if (dccid == 53) {
01180                         int ix = eedetid.ix();
01181                         if (ix > 50) ilm += 1;
01182                 }
01183                 return ilm;
01184         }
01185         else throw cms::Exception("InvalidDCCId") << "Wrong DCCId (EE) in EcalElectronicsMapping::getLMNumber.";
01186   }
01187 
01188   return -1;
01189 }
01190 
01191 
01192 
01193 
01194 
01195 
01196 
01197 
01198 
01199 
01200 
01201