00001 #include "RecoMuon/MuonIdentification/interface/MuonHOAcceptance.h"
00002
00003 #include <iostream>
00004 #include <algorithm>
00005 #include <cmath>
00006
00007
00008 #include "TMultiGraph.h"
00009 #include "TGraph.h"
00010
00011 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00012
00013 #include "CondFormats/HcalObjects/interface/HcalChannelQuality.h"
00014 #include "CondFormats/DataRecord/interface/HcalChannelQualityRcd.h"
00015
00016 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSeverityLevelComputer.h"
00017 #include "RecoLocalCalo/HcalRecAlgos/interface/HcalSeverityLevelComputerRcd.h"
00018
00019 #include "FWCore/Framework/interface/ESHandle.h"
00020
00021 std::vector<uint32_t> MuonHOAcceptance::deadIds;
00022 std::vector<MuonHOAcceptance::deadRegion> MuonHOAcceptance::deadRegions;
00023 std::vector<uint32_t> MuonHOAcceptance::SiPMIds;
00024 std::vector<MuonHOAcceptance::deadRegion> MuonHOAcceptance::SiPMRegions;
00025 bool MuonHOAcceptance::inited = false;
00026 int const MuonHOAcceptance::etaBounds = 5;
00027 double const MuonHOAcceptance::etaMin[etaBounds] =
00028
00029 {-1.2544, -0.8542, -0.3017, 0.3425, 0.8796};
00030 double const MuonHOAcceptance::etaMax[etaBounds] =
00031
00032 {-0.8796, -0.3425, 0.3017, 0.8542, 1.2544};
00033 double const MuonHOAcceptance::twopi = 2.*3.14159265358979323846;
00034 int const MuonHOAcceptance::phiSectors = 12;
00035 double const MuonHOAcceptance::phiMinR0[phiSectors] = {-0.16172,
00036 0.3618786,
00037 0.8854773,
00038 1.409076116,
00039 1.932674892,
00040 2.456273667,
00041 2.979872443,
00042 3.503471219,
00043 4.027069994,
00044 4.55066877,
00045 5.074267545,
00046 5.597866321 };
00047 double const MuonHOAcceptance::phiMaxR0[phiSectors] = { 0.317395374,
00048 0.84099415,
00049 1.364592925,
00050 1.888191701,
00051 2.411790477,
00052 2.935389252,
00053 3.458988028,
00054 3.982586803,
00055 4.506185579,
00056 5.029784355,
00057 5.55338313,
00058 6.076981906 };
00059 double const MuonHOAcceptance::phiMinR12[phiSectors] = {-0.166264081,
00060 0.357334694,
00061 0.88093347,
00062 1.404532245,
00063 1.928131021,
00064 2.451729797,
00065 2.975328572,
00066 3.498927348,
00067 4.022526123,
00068 4.546124899,
00069 5.069723674,
00070 5.59332245 };
00071 double const MuonHOAcceptance::phiMaxR12[phiSectors] = { 0.34398862,
00072 0.867587396,
00073 1.391186172,
00074 1.914784947,
00075 2.438383723,
00076 2.961982498,
00077 3.485581274,
00078 4.00918005,
00079 4.532778825,
00080 5.056377601,
00081 5.579976376,
00082 6.103575152 };
00083
00084 bool MuonHOAcceptance::isChannelDead(uint32_t id) {
00085 if (!inited) return false;
00086 std::vector<uint32_t>::const_iterator found =
00087 std::find(deadIds.begin(), deadIds.end(), id);
00088 if ((found != deadIds.end()) && (*found == id)) return true;
00089 else return false;
00090 }
00091
00092 bool MuonHOAcceptance::isChannelSiPM(uint32_t id) {
00093 if (!inited) return false;
00094 std::vector<uint32_t>::const_iterator found =
00095 std::find(SiPMIds.begin(), SiPMIds.end(), id);
00096 if ((found != SiPMIds.end()) && (*found == id)) return true;
00097 else return false;
00098 }
00099
00100 bool MuonHOAcceptance::inGeomAccept(double eta, double phi,
00101 double delta_eta, double delta_phi)
00102 {
00103 for (int ieta = 0; ieta<etaBounds; ++ieta) {
00104 if ( (eta > etaMin[ieta]+delta_eta) &&
00105 (eta < etaMax[ieta]-delta_eta) ) {
00106 for (int iphi = 0; iphi<phiSectors; ++iphi) {
00107 double const * mins = ((ieta == 2) ? phiMinR0 : phiMinR12);
00108 double const * maxes = ((ieta == 2) ? phiMaxR0 : phiMaxR12);
00109 while (phi < mins[0])
00110 phi += twopi;
00111 while (phi > mins[0]+twopi)
00112 phi -= twopi;
00113 if ( ( phi > mins[iphi] + delta_phi ) &&
00114 ( phi < maxes[iphi] - delta_phi ) ) {
00115 return true;
00116 }
00117 }
00118 return false;
00119 }
00120 }
00121 return false;
00122 }
00123
00124 bool MuonHOAcceptance::inNotDeadGeom(double eta, double phi,
00125 double delta_eta, double delta_phi) {
00126 if (!inited) return true;
00127 int ieta = int(eta/0.087) + ((eta>0) ? 1 : -1);
00128 double const * mins = ((std::abs(ieta) > 4) ? phiMinR12 : phiMinR0);
00129 while (phi < mins[0])
00130 phi += twopi;
00131 while (phi > mins[0]+twopi)
00132 phi -= twopi;
00133 std::vector<deadRegion>::const_iterator region;
00134 for (region = deadRegions.begin(); region != deadRegions.end(); ++region) {
00135 if ( (phi < region->phiMax + delta_phi) &&
00136 (phi > region->phiMin - delta_phi) &&
00137 (eta < region->etaMax + delta_eta) &&
00138 (eta > region->etaMin - delta_eta) )
00139 return false;
00140 }
00141 return true;
00142 }
00143
00144 bool MuonHOAcceptance::inSiPMGeom(double eta, double phi,
00145 double delta_eta, double delta_phi) {
00146 if (!inited) return false;
00147 int ieta = int(eta/0.087) + ((eta>0) ? 1 : -1);
00148 double const * mins = ((std::abs(ieta) > 4) ? phiMinR12 : phiMinR0);
00149 while (phi < mins[0])
00150 phi += twopi;
00151 while (phi > mins[0]+twopi)
00152 phi -= twopi;
00153 std::vector<deadRegion>::const_iterator region;
00154 for (region = SiPMRegions.begin(); region != SiPMRegions.end(); ++region) {
00155 if ( (phi < region->phiMax - delta_phi) &&
00156 (phi > region->phiMin + delta_phi) &&
00157 (eta < region->etaMax - delta_eta) &&
00158 (eta > region->etaMin + delta_eta) ) {
00159 return true;
00160 }
00161 }
00162 return false;
00163 }
00164
00165 void MuonHOAcceptance::initIds(edm::EventSetup const& eSetup) {
00166 deadIds.clear();
00167
00168 edm::ESHandle<HcalChannelQuality> p;
00169 eSetup.get<HcalChannelQualityRcd>().get(p);
00170 HcalChannelQuality *myqual = new HcalChannelQuality(*p.product());
00171
00172 edm::ESHandle<HcalSeverityLevelComputer> mycomputer;
00173 eSetup.get<HcalSeverityLevelComputerRcd>().get(mycomputer);
00174 const HcalSeverityLevelComputer *mySeverity = mycomputer.product();
00175
00176
00177
00178 int ieta, iphi;
00179
00180
00181
00182
00183
00184
00185 for (ieta=-15; ieta <= 15; ieta++) {
00186 if (ieta != 0) {
00187 for (iphi = 1; iphi <= 72; iphi++) {
00188
00189
00190
00191 HcalDetId did(HcalOuter,ieta,iphi,4);
00192 const HcalChannelStatus *mystatus = myqual->getValues(did.rawId());
00193 if (mySeverity->dropChannel(mystatus->getValue())) {
00194 deadIds.push_back(did.rawId());
00195
00196 }
00197
00198 if ( (ieta>=5) && (ieta<=10) && (iphi >= 47) && (iphi <= 58) ) {
00199 SiPMIds.push_back(did.rawId());
00200 }
00201
00202 if ( (ieta>=11) && (ieta<=15) && (iphi >= 59) && (iphi <= 70) ) {
00203 SiPMIds.push_back(did.rawId());
00204 }
00205 }
00206 }
00207 }
00208 std::sort(deadIds.begin(), deadIds.end());
00209 std::sort(SiPMIds.begin(), SiPMIds.end());
00210
00211
00212 buildDeadAreas();
00213 buildSiPMAreas();
00214 inited = true;
00215 delete myqual;
00216 }
00217
00218 void MuonHOAcceptance::buildDeadAreas() {
00219 std::vector<uint32_t>::iterator did;
00220 std::list<deadIdRegion> didregions;
00221 for (did = deadIds.begin(); did != deadIds.end(); ++did) {
00222 HcalDetId tmpId(*did);
00223 didregions.push_back( deadIdRegion( tmpId.ieta(), tmpId.ieta(),
00224 tmpId.iphi(), tmpId.iphi() ) );
00225 }
00226
00227
00228 mergeRegionLists(didregions);
00229 convertRegions(didregions, deadRegions);
00230 }
00231
00232 void MuonHOAcceptance::buildSiPMAreas() {
00233 std::vector<uint32_t>::iterator sid;
00234 std::list<deadIdRegion> idregions;
00235
00236 for (sid = SiPMIds.begin(); sid != SiPMIds.end(); ++sid) {
00237 HcalDetId tmpId(*sid);
00238 idregions.push_back( deadIdRegion( tmpId.ieta(), tmpId.ieta(),
00239 tmpId.iphi(), tmpId.iphi() ) );
00240 }
00241
00242 mergeRegionLists(idregions);
00243 convertRegions(idregions,SiPMRegions);
00244 }
00245
00246 void MuonHOAcceptance::mergeRegionLists (std::list<deadIdRegion>& didregions) {
00247 std::list<deadIdRegion>::iterator curr;
00248 std::list<deadIdRegion> list2;
00249 unsigned int startSize;
00250 do {
00251 startSize = didregions.size();
00252
00253
00254
00255 curr = didregions.begin();
00256 while (curr != didregions.end()) {
00257 deadIdRegion merger(*curr);
00258 curr = didregions.erase(curr);
00259 while (curr != didregions.end()) {
00260 if ( (merger.sameEta(*curr)) && (merger.adjacentPhi(*curr)) ) {
00261 merger.merge(*curr);
00262 curr = didregions.erase(curr);
00263 } else ++curr;
00264 }
00265 list2.push_back(merger);
00266 curr = didregions.begin();
00267 }
00268
00269
00270 curr = list2.begin();
00271 while (curr != list2.end()) {
00272 deadIdRegion merger(*curr);
00273 curr = list2.erase(curr);
00274 while (curr != list2.end()) {
00275 if ( (merger.samePhi(*curr)) && (merger.adjacentEta(*curr)) ) {
00276 merger.merge(*curr);
00277 curr = list2.erase(curr);
00278 } else ++curr;
00279 }
00280 didregions.push_back(merger);
00281 curr = list2.begin();
00282 }
00283 } while (startSize > didregions.size());
00284 }
00285
00286 void MuonHOAcceptance::convertRegions(std::list<deadIdRegion> const& idregions,
00287 std::vector<deadRegion>& regions) {
00288 double e1, e2;
00289 double eMin,eMax,pMin,pMax;
00290 static double const etaStep = 0.087;
00291 static double const phiStep = twopi/72.;
00292 double const offset = 2.;
00293 double const * mins;
00294 double const * maxes;
00295 std::list<deadIdRegion>::const_iterator curr;
00296 double zero;
00297 for (curr = idregions.begin(); curr != idregions.end(); ++curr) {
00298
00299
00300
00301 if (curr->etaMin == -4) {
00302 eMin = etaMax[1];
00303 } else if (curr->etaMin == 5) {
00304 eMin = etaMin[3];
00305 } else {
00306 e1 = (std::abs(curr->etaMin)-1)*etaStep*
00307 (-(curr->etaMin<0) + (curr->etaMin>0));
00308 e2 = std::abs(curr->etaMin)*etaStep*
00309 (-(curr->etaMin<0) + (curr->etaMin>0));
00310 eMin = std::min(e1,e2);
00311 }
00312 if (curr->etaMax == 4) {
00313 eMax = etaMin[3];
00314 } else if (curr->etaMax == -5) {
00315 eMax = etaMax[1];
00316 } else {
00317 e1 = (std::abs(curr->etaMax)-1)*etaStep*
00318 (-(curr->etaMax<0) + (curr->etaMax>0));
00319 e2 = std::abs(curr->etaMax)*etaStep*
00320 (-(curr->etaMax<0) + (curr->etaMax>0));
00321 eMax = std::max(e1,e2);
00322 }
00323 mins = ((std::abs(curr->etaMin)>4) ? phiMinR12 : phiMinR0);
00324 maxes = ((std::abs(curr->etaMin)>4) ? phiMaxR12 : phiMaxR0);
00325 zero = (mins[0] + maxes[phiSectors-1] - twopi)/2.;
00326 pMin = (curr->phiMin-1)*phiStep + zero + phiStep*offset;
00327 pMax = curr->phiMax*phiStep + zero + phiStep*offset;
00328 while (pMax < mins[0])
00329 pMax += twopi;
00330 while (pMax > mins[0]+twopi)
00331 pMax -= twopi;
00332 while (pMin < mins[0])
00333 pMin += twopi;
00334 while (pMin > mins[0]+twopi)
00335 pMin -= twopi;
00336
00337 regions.push_back( deadRegion(eMin, eMax, pMin, pMax) );
00338
00339
00340
00341 }
00342 }
00343
00344 TMultiGraph * MuonHOAcceptance::graphRegions(std::vector<deadRegion> const& regions) {
00345 TMultiGraph * bounds = new TMultiGraph("bounds", "bounds");
00346 std::vector<deadRegion>::const_iterator region;
00347 TGraph * gr;
00348 for (region = regions.begin(); region != regions.end(); ++region) {
00349
00350
00351 double pMin = region->phiMin;
00352 while (pMin > twopi/2.) pMin -= twopi;
00353 double pMax = region->phiMax;
00354 while (pMax > twopi/2.) pMax -= twopi;
00355
00356 if (pMin < pMax) {
00357 gr = new TGraph(5);
00358 gr->SetLineColor(kRed);
00359 gr->SetPoint(0, region->etaMin, pMin);
00360 gr->SetPoint(1, region->etaMin, pMax);
00361 gr->SetPoint(2, region->etaMax, pMax);
00362 gr->SetPoint(3, region->etaMax, pMin);
00363 gr->SetPoint(4, region->etaMin, pMin);
00364 bounds->Add(gr, "l");
00365 } else {
00366 gr = new TGraph(5);
00367 gr->SetLineColor(kRed);
00368 gr->SetPoint(0, region->etaMin, pMin);
00369 gr->SetPoint(1, region->etaMin, twopi/2.);
00370 gr->SetPoint(2, region->etaMax, twopi/2.);
00371 gr->SetPoint(3, region->etaMax, pMin);
00372 gr->SetPoint(4, region->etaMin, pMin);
00373 bounds->Add(gr, "l");
00374 gr = new TGraph(5);
00375 gr->SetLineColor(kRed);
00376 gr->SetPoint(0, region->etaMin, -twopi/2.);
00377 gr->SetPoint(1, region->etaMin, pMax);
00378 gr->SetPoint(2, region->etaMax, pMax);
00379 gr->SetPoint(3, region->etaMax, -twopi/2.);
00380 gr->SetPoint(4, region->etaMin, -twopi/2.);
00381 bounds->Add(gr, "l");
00382 }
00383 }
00384 return bounds;
00385 }
00386
00387 void MuonHOAcceptance::deadIdRegion::merge (deadIdRegion const& other) {
00388 etaMin = std::min(etaMin, other.etaMin);
00389 etaMax = std::max(etaMax, other.etaMax);
00390 phiMin = std::min(phiMin, other.phiMin);
00391 phiMax = std::max(phiMax, other.phiMax);
00392 }