CMS 3D CMS Logo

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