00001 #ifndef ECALBOUNDARYINFOCALCULATOR_H_
00002 #define ECALBOUNDARYINFOCALCULATOR_H_
00003 #include <memory>
00004 #include "Geometry/CaloEventSetup/interface/CaloTopologyRecord.h"
00005 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
00006 #include "Geometry/CaloTopology/interface/CaloTopology.h"
00007 #include "RecoCaloTools/Navigation/interface/EcalBarrelNavigator.h"
00008 #include "RecoCaloTools/Navigation/interface/EcalEndcapNavigator.h"
00009 #include "RecoCaloTools/Navigation/interface/EcalPreshowerNavigator.h"
00010 #include "RecoCaloTools/Navigation/interface/CaloTowerNavigator.h"
00011 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
00012 #include "DataFormats/EcalDetId/interface/EBDetId.h"
00013 #include "DataFormats/EcalDetId/interface/EEDetId.h"
00014 #include "DataFormats/EcalDetId/interface/ESDetId.h"
00015 #include "DataFormats/EcalRecHit/interface/EcalRecHitCollections.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "DataFormats/METReco/interface/BoundaryInformation.h"
00018
00019
00020 enum CdOrientation {
00021 north, east, south, west, none
00022 };
00023
00024 template<class EcalDetId> class EcalBoundaryInfoCalculator {
00025
00026 public:
00027
00028 EcalBoundaryInfoCalculator();
00029 ~EcalBoundaryInfoCalculator();
00030
00031 BoundaryInformation boundaryRecHits(const edm::Handle<EcalRecHitCollection>&, const EcalRecHit*,
00032 const edm::ESHandle<CaloTopology> theCaloTopology, const edm::ESHandle<EcalChannelStatus> ecalStatus,
00033 const edm::ESHandle<CaloGeometry> geometry);
00034
00035 BoundaryInformation gapRecHits(const edm::Handle<EcalRecHitCollection>&, const EcalRecHit*, const edm::ESHandle<
00036 CaloTopology> theCaloTopology, const edm::ESHandle<EcalChannelStatus> ecalStatus, const edm::ESHandle<
00037 CaloGeometry> geometry);
00038
00039 bool checkRecHitHasDeadNeighbour(const EcalRecHit hit, const edm::ESHandle<EcalChannelStatus> ecalStatus, std::vector<
00040 int> &stati) {
00041
00042 stati.clear();
00043 EcalDetId hitdetid = EcalDetId(hit.id());
00044
00045 if (hitdetid.subdet() == EcalBarrel) {
00046
00047 EBDetId ebhitdetid = (EBDetId) hitdetid;
00048
00049 int hitIeta = ebhitdetid.ieta();
00050 int hitIphi = ebhitdetid.iphi();
00051
00052 for (int ieta = -1; ieta <= 1; ieta++) {
00053 for (int iphi = -1; iphi <= 1; iphi++) {
00054 if ((iphi == 0 && ieta == 0) || iphi * ieta != 0)
00055
00056 continue;
00057 int neighbourIeta = hitIeta + ieta;
00058 int neighbourIphi = hitIphi + iphi;
00059 if (!EBDetId::validDetId(neighbourIeta, neighbourIphi)) {
00060 if (neighbourIphi < 1)
00061 neighbourIphi += 360;
00062 if (neighbourIphi > 360)
00063 neighbourIphi -= 360;
00064 if (neighbourIeta == 0) {
00065 neighbourIeta += ieta;
00066 }
00067 }
00068
00069 if (EBDetId::validDetId(neighbourIeta, neighbourIphi)) {
00070
00071 const EBDetId detid = EBDetId(neighbourIeta, neighbourIphi, EBDetId::ETAPHIMODE);
00072 EcalChannelStatus::const_iterator chit = ecalStatus->find(detid);
00073 int status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00074
00075 if (status > 0) {
00076 bool present = false;
00077 for (std::vector<int>::const_iterator s = stati.begin(); s != stati.end(); ++s) {
00078 if (*s == status) {
00079 present = true;
00080 break;
00081 }
00082 }
00083 if (!present)
00084 stati.push_back(status);
00085 }
00086 }
00087 }
00088 }
00089
00090 } else if (hitdetid.subdet() == EcalEndcap) {
00091
00092 EEDetId eehitdetid = (EEDetId) hitdetid;
00093 int hitIx = eehitdetid.ix();
00094 int hitIy = eehitdetid.iy();
00095 int hitIz = eehitdetid.zside();
00096
00097 for (int ix = -1; ix <= 1; ix++) {
00098 for (int iy = -1; iy <= 1; iy++) {
00099 if ((ix == 0 && iy == 0) || ix * iy != 0)
00100
00101 continue;
00102 int neighbourIx = hitIx + ix;
00103 int neighbourIy = hitIy + iy;
00104
00105 if (EEDetId::validDetId(neighbourIx, neighbourIy, hitIz)) {
00106
00107 const EEDetId detid = EEDetId(neighbourIx, neighbourIy, hitIz, EEDetId::XYMODE);
00108 EcalChannelStatus::const_iterator chit = ecalStatus->find(detid);
00109 int status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00110
00111 if (status > 0) {
00112 bool present = false;
00113 for (std::vector<int>::const_iterator s = stati.begin(); s != stati.end(); ++s) {
00114 if (*s == status) {
00115 present = true;
00116 break;
00117 }
00118 }
00119 if (!present)
00120 stati.push_back(status);
00121 }
00122 }
00123 }
00124 }
00125
00126 } else {
00127 std::cout << "ERROR - RecHit belongs to wrong sub detector" << std::endl;
00128 }
00129
00130 if (stati.size() > 0)
00131 return true;
00132 return false;
00133
00134 }
00135
00136 bool checkRecHitHasInvalidNeighbour(const EcalRecHit hit, const edm::ESHandle<EcalChannelStatus> ecalStatus) {
00138
00139 EcalDetId hitdetid = EcalDetId(hit.id());
00140
00141 if (hitdetid.subdet() == EcalBarrel) {
00142
00143 EBDetId ebhitdetid = (EBDetId) hitdetid;
00144
00145 int hitIeta = ebhitdetid.ieta();
00146 int hitIphi = ebhitdetid.iphi();
00147
00148 for (int ieta = -1; ieta <= 1; ieta++) {
00149 for (int iphi = -1; iphi <= 1; iphi++) {
00150 if ((iphi == 0 && ieta == 0) || iphi * ieta != 0)
00151
00152 continue;
00153 int neighbourIeta = hitIeta + ieta;
00154 int neighbourIphi = hitIphi + iphi;
00155 if (!EBDetId::validDetId(neighbourIeta, neighbourIphi)) {
00156 if (neighbourIphi < 1)
00157 neighbourIphi += 360;
00158 if (neighbourIphi > 360)
00159 neighbourIphi -= 360;
00160 if (neighbourIeta == 0) {
00161 neighbourIeta += ieta;
00162 }
00163 }
00164
00165 if (!EBDetId::validDetId(neighbourIeta, neighbourIphi)) {
00166 return true;
00167 }
00168 }
00169 }
00170
00171 } else if (hitdetid.subdet() == EcalEndcap) {
00172
00173 EEDetId eehitdetid = (EEDetId) hitdetid;
00174 int hitIx = eehitdetid.ix();
00175 int hitIy = eehitdetid.iy();
00176 int hitIz = eehitdetid.zside();
00177
00178 for (int ix = -1; ix <= 1; ix++) {
00179 for (int iy = -1; iy <= 1; iy++) {
00180 if ((ix == 0 && iy == 0) || ix * iy != 0)
00181
00182 continue;
00183 int neighbourIx = hitIx + ix;
00184 int neighbourIy = hitIy + iy;
00185
00186 if (!EEDetId::validDetId(neighbourIx, neighbourIy, hitIz)) {
00187 return true;
00188 }
00189 }
00190 }
00191
00192 } else {
00193 std::cout << "ERROR - RecHit belongs to wrong sub detector" << std::endl;
00194 }
00195
00196 return false;
00197 }
00198
00199 void setDebugMode() {
00200 std::cout << "set Debug Mode!" << std::endl;
00201 debug = true;
00202 }
00203
00204 private:
00205
00206 EcalDetId makeStepInDirection(CdOrientation direction, CaloNavigator<EcalDetId> * theNavi) {
00207 EcalDetId next;
00208 switch (direction) {
00209 case north: {
00210
00211 next = theNavi->north();
00212 break;
00213 }
00214 case east: {
00215
00216 next = theNavi->east();
00217 break;
00218 }
00219 case south: {
00220
00221 next = theNavi->south();
00222 break;
00223 }
00224 case west: {
00225
00226 next = theNavi->west();
00227 break;
00228 }
00229 default:
00230 break;
00231 }
00232 return next;
00233 }
00234
00235 CdOrientation goBackOneCell(CdOrientation currDirection, EcalDetId prev) {
00236 std::map<CdOrientation, CdOrientation>::iterator oIt = oppositeDirs.find(currDirection);
00237 CdOrientation oppDirection=none;
00238 if (oIt != oppositeDirs.end()) {
00239 oppDirection = oIt->second;
00240 theEcalNav->setHome(prev);
00241 }
00242 EcalDetId currDetId = theEcalNav->pos();
00243
00244 return oppDirection;
00245 }
00246
00247 CdOrientation turnRight(CdOrientation currDirection, bool reverseOrientation) {
00248
00249 std::map<CdOrientation, CdOrientation> turnMap = nextDirs;
00250 if (reverseOrientation)
00251 turnMap = prevDirs;
00252 std::map<CdOrientation, CdOrientation>::iterator nIt = turnMap.find(currDirection);
00253 CdOrientation nextDirection=none;
00254 if (nIt != turnMap.end())
00255 nextDirection = (*nIt).second;
00256 else
00257 std::cout << "ERROR - no Next Direction found!?!?" << std::endl;
00258 return nextDirection;
00259 }
00260
00261 CdOrientation turnLeft(CdOrientation currDirection, bool reverseOrientation) {
00262
00263 std::map<CdOrientation, CdOrientation> turnMap = prevDirs;
00264 if (reverseOrientation)
00265 turnMap = nextDirs;
00266 std::map<CdOrientation, CdOrientation>::iterator nIt = turnMap.find(currDirection);
00267 CdOrientation nextDirection=none;
00268 if (nIt != turnMap.end())
00269 nextDirection = (*nIt).second;
00270 else
00271 std::cout << "ERROR - no Next Direction found!?!?" << std::endl;
00272 return nextDirection;
00273 }
00274
00275 void initializeEcalNavigator(DetId startE, const edm::ESHandle<CaloTopology> theCaloTopology,
00276 EcalSubdetector ecalSubDet) {
00277 if (ecalSubDet == EcalBarrel) {
00278 if (theEcalNav != 0) {
00279 delete theEcalNav;
00280 theEcalNav = 0;
00281 }
00282 theEcalNav = new CaloNavigator<EcalDetId> ((EBDetId) startE, (theCaloTopology->getSubdetectorTopology(
00283 DetId::Ecal, ecalSubDet)));
00284 } else if (ecalSubDet == EcalEndcap) {
00285 if (theEcalNav != 0) {
00286 delete theEcalNav;
00287 theEcalNav = 0;
00288 }
00289 theEcalNav = new CaloNavigator<EcalDetId> ((EEDetId) startE, (theCaloTopology->getSubdetectorTopology(
00290 DetId::Ecal, ecalSubDet)));
00291 } else {
00292 std::cout << "initializeEcalNavigator not implemented for subDet: " << ecalSubDet << std::endl;
00293 }
00294
00295 }
00296
00297 std::map<CdOrientation, CdOrientation> nextDirs;
00298 std::map<CdOrientation, CdOrientation> prevDirs;
00299 std::map<CdOrientation, CdOrientation> oppositeDirs;
00300 CaloNavigator<EcalDetId> * theEcalNav;
00301 bool debug;
00302
00303 };
00304
00305 template<class EcalDetId> EcalBoundaryInfoCalculator<EcalDetId>::EcalBoundaryInfoCalculator() {
00306
00307 nextDirs.clear();
00308 nextDirs[north] = east;
00309 nextDirs[east] = south;
00310 nextDirs[south] = west;
00311 nextDirs[west] = north;
00312
00313 prevDirs.clear();
00314 prevDirs[north] = west;
00315 prevDirs[east] = north;
00316 prevDirs[south] = east;
00317 prevDirs[west] = south;
00318
00319 oppositeDirs.clear();
00320 oppositeDirs[north] = south;
00321 oppositeDirs[south] = north;
00322 oppositeDirs[east] = west;
00323 oppositeDirs[west] = east;
00324
00325 theEcalNav = 0;
00326 debug = false;
00327
00328 }
00329
00330 template<class EcalDetId> EcalBoundaryInfoCalculator<EcalDetId>::~EcalBoundaryInfoCalculator() {
00331 delete theEcalNav;
00332 }
00333
00334 template<class EcalDetId> BoundaryInformation EcalBoundaryInfoCalculator<EcalDetId>::boundaryRecHits(const edm::Handle<
00335 EcalRecHitCollection>& RecHits, const EcalRecHit* hit, const edm::ESHandle<CaloTopology> theCaloTopology,
00336 edm::ESHandle<EcalChannelStatus> ecalStatus, edm::ESHandle<CaloGeometry> geometry) {
00337
00338
00339 std::vector<EcalRecHit> boundaryRecHits;
00340 std::vector<DetId> boundaryDetIds;
00341 std::vector<int> stati;
00342
00343 double boundaryEnergy = 0;
00344 double boundaryET = 0;
00345 int beCellCounter = 0;
00346 bool nextToBorder = false;
00347
00348 boundaryRecHits.push_back(*hit);
00349 ++beCellCounter;
00350 boundaryEnergy += hit->energy();
00351 EcalDetId hitdetid = (EcalDetId) hit->id();
00352 boundaryDetIds.push_back(hitdetid);
00353 const CaloSubdetectorGeometry* subGeom = geometry->getSubdetectorGeometry(hitdetid);
00354 const CaloCellGeometry* cellGeom = subGeom->getGeometry(hitdetid);
00355 double eta = cellGeom->getPosition().eta();
00356 boundaryET += hit->energy() / cosh(eta);
00357
00358 if (debug) {
00359 std::cout << "Find Boundary RecHits..." << std::endl;
00360
00361 if (hitdetid.subdet() == EcalBarrel) {
00362 std::cout << "Starting at : (" << ((EBDetId) hitdetid).ieta() << "," << ((EBDetId) hitdetid).iphi() << ")"
00363 << std::endl;
00364
00365 } else if (hitdetid.subdet() == EcalEndcap) {
00366 std::cout << "Starting at : (" << ((EEDetId) hitdetid).ix() << "," << ((EEDetId) hitdetid).iy() << ")"
00367 << std::endl;
00368 }
00369 }
00370
00371
00372 initializeEcalNavigator(hitdetid, theCaloTopology, EcalDetId::subdet());
00373 CdOrientation currDirection = north;
00374 bool reverseOrientation = false;
00375
00376 EcalDetId next(0);
00377 EcalDetId start = hitdetid;
00378 EcalDetId current = start;
00379 int current_status = 0;
00380
00381
00382 bool startAlgo = false;
00383 int noDirs = 0;
00384 while (!startAlgo) {
00385 next = makeStepInDirection(currDirection, theEcalNav);
00386 theEcalNav->setHome(current);
00387 theEcalNav->home();
00388 EcalChannelStatus::const_iterator chit = ecalStatus->find(next);
00389 int status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00390 if (status > 0) {
00391 stati.push_back(status);
00392 startAlgo = true;
00393 break;
00394 }
00395 currDirection = turnLeft(currDirection, reverseOrientation);
00396 ++noDirs;
00397 if (noDirs > 4) {
00398
00399 std::cout << "No starting direction can be found: This should never happen if RecHit has a dead neighbour!" << std::endl;
00400 throw "ERROR";
00401 break;
00402 }
00403 }
00404
00405
00406 currDirection = turnRight(currDirection, reverseOrientation);
00407
00408
00409 bool nextIsStart = false;
00410 bool atBorder = false;
00411
00412 while (!nextIsStart) {
00413
00414 bool nextStepFound = false;
00415 int status = 0;
00416 noDirs = 0;
00417 while (!nextStepFound) {
00418 next = makeStepInDirection(currDirection, theEcalNav);
00419 theEcalNav->setHome(current);
00420 theEcalNav->home();
00421 EcalChannelStatus::const_iterator chit = ecalStatus->find(next);
00422 status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00423 if (status > 0) {
00424
00425 bool present = false;
00426 for (std::vector<int>::const_iterator s = stati.begin(); s != stati.end(); ++s) {
00427 if (*s == status) {
00428 present = true;
00429 break;
00430 }
00431 }
00432 if (!present)
00433 stati.push_back(status);
00434
00435 if (atBorder) {
00436 nextStepFound = true;
00437 } else {
00438 currDirection = turnRight(currDirection, reverseOrientation);
00439 }
00440 } else if (next == EcalDetId(0)) {
00441
00442 currDirection = turnLeft(currDirection, reverseOrientation);
00443 atBorder = true;
00444 } else if (status == 0) {
00445 nextStepFound = true;
00446 }
00447 ++noDirs;
00448 if (noDirs > 4) {
00449 std::cout << "No valid next direction can be found: This should never happen!" << std::endl;
00450 throw "ERROR";
00451 break;
00452 }
00453 }
00454
00455
00456 next = makeStepInDirection(currDirection, theEcalNav);
00457
00458 if (next == start) {
00459 nextIsStart = true;
00460 if (debug)
00461 std::cout << "Boundary path reached starting position!" << std::endl;
00462 }
00463
00464 if (debug)
00465 std::cout << "Next step: " << (EcalDetId) next << " Status: " << status << " Start: " << (EcalDetId) start << std::endl;
00466
00467
00468 if ((!atBorder || status == 0) && !nextIsStart) {
00469 boundaryDetIds.push_back(next);
00470 if (RecHits->find(next) != RecHits->end() && status == 0) {
00471 EcalRecHit nexthit = *RecHits->find(next);
00472 ++beCellCounter;
00473 boundaryRecHits.push_back(nexthit);
00474 boundaryEnergy += nexthit.energy();
00475 cellGeom = subGeom->getGeometry(hitdetid);
00476 eta = cellGeom->getPosition().eta();
00477 boundaryET += nexthit.energy() / cosh(eta);
00478 }
00479 }
00480
00481 if (current_status == 0 && status == 0 && atBorder) {
00482
00483 currDirection = turnRight(currDirection, reverseOrientation);
00484 } else {
00485
00486 if (status == 0 && atBorder) {
00487 atBorder = false;
00488 currDirection = turnLeft(currDirection, reverseOrientation);
00489 }
00490 if (status == 0) {
00491
00492 currDirection = turnLeft(currDirection, reverseOrientation);
00493 } else {
00494
00495 currDirection = turnRight(currDirection, reverseOrientation);
00496 }
00497 }
00498
00499
00500 current = next;
00501 current_status = status;
00502
00503 }
00504
00505 if (debug) {
00506 std::cout << "<<<<<<<<<<<<<<< Final Boundary object <<<<<<<<<<<<<<<" << std::endl;
00507 std::cout << "no of neighbouring RecHits: " << boundaryRecHits.size() << std::endl;
00508 std::cout << "no of neighbouring DetIds: " << boundaryDetIds.size() << std::endl;
00509 std::cout << "boundary energy: " << boundaryEnergy << std::endl;
00510 std::cout << "boundary ET: " << boundaryET << std::endl;
00511 std::cout << "no of cells contributing to boundary energy: " << beCellCounter << std::endl;
00512 std::cout << "Channel stati: ";
00513 for (std::vector<int>::iterator it = stati.begin(); it != stati.end(); ++it) {
00514 std::cout << *it << " ";
00515 }
00516 std::cout << std::endl;
00517 }
00518
00519 BoundaryInformation boundInfo;
00520 boundInfo.subdet = hitdetid.subdet();
00521 boundInfo.detIds = boundaryDetIds;
00522 boundInfo.recHits = boundaryRecHits;
00523 boundInfo.boundaryEnergy = boundaryEnergy;
00524 boundInfo.boundaryET = boundaryET;
00525 boundInfo.nextToBorder = nextToBorder;
00526 boundInfo.channelStatus = stati;
00527
00528 if (theEcalNav != 0) {
00529 delete theEcalNav;
00530 theEcalNav = 0;
00531 }
00532 return boundInfo;
00533 }
00534
00535 template<class EcalDetId> BoundaryInformation EcalBoundaryInfoCalculator<EcalDetId>::gapRecHits(const edm::Handle<
00536 EcalRecHitCollection>& RecHits, const EcalRecHit* hit, const edm::ESHandle<CaloTopology> theCaloTopology,
00537 edm::ESHandle<EcalChannelStatus> ecalStatus, edm::ESHandle<CaloGeometry> geometry) {
00538
00539
00540 std::vector<EcalRecHit> gapRecHits;
00541 std::vector<DetId> gapDetIds;
00542
00543 double gapEnergy = 0;
00544 double gapET = 0;
00545 int gapCellCounter = 0;
00546 bool nextToBorder = false;
00547
00548 gapRecHits.push_back(*hit);
00549 ++gapCellCounter;
00550 gapEnergy += hit->energy();
00551 EcalDetId hitdetid = (EcalDetId) hit->id();
00552 gapDetIds.push_back(hitdetid);
00553 const CaloSubdetectorGeometry* subGeom = geometry->getSubdetectorGeometry(hitdetid);
00554 const CaloCellGeometry* cellGeom = subGeom->getGeometry(hitdetid);
00555 double eta = cellGeom->getPosition().eta();
00556 gapET += hit->energy() / cosh(eta);
00557
00558 if (debug) {
00559 std::cout << "Find Border RecHits..." << std::endl;
00560
00561 if (hitdetid.subdet() == EcalBarrel) {
00562 std::cout << "Starting at : (" << ((EBDetId) hitdetid).ieta() << "," << ((EBDetId) hitdetid).iphi() << ")"
00563 << std::endl;
00564
00565 } else if (hitdetid.subdet() == EcalEndcap) {
00566 std::cout << "Starting at : (" << ((EEDetId) hitdetid).ix() << "," << ((EEDetId) hitdetid).iy() << ")"
00567 << std::endl;
00568 }
00569 }
00570
00571
00572 initializeEcalNavigator(hitdetid, theCaloTopology, EcalDetId::subdet());
00573 CdOrientation currDirection = north;
00574 bool reverseOrientation = false;
00575
00576 EcalDetId next(0);
00577 EcalDetId start = hitdetid;
00578 EcalDetId current = start;
00579
00580
00581 bool startAlgo = false;
00582 int noDirs = 0;
00583 while (!startAlgo) {
00584 next = makeStepInDirection(currDirection, theEcalNav);
00585 theEcalNav->setHome(start);
00586 theEcalNav->home();
00587 if (next == EcalDetId(0)) {
00588 startAlgo = true;
00589 nextToBorder = true;
00590 break;
00591 }
00592 currDirection = turnLeft(currDirection, reverseOrientation);
00593 ++noDirs;
00594 if (noDirs > 4) {
00595
00596 std::cout << "No starting direction can be found: This should never happen if RecHit is at border!" << std::endl;
00597 throw "ERROR";
00598 break;
00599 }
00600 }
00601
00603 CdOrientation startDirection = currDirection;
00604 currDirection = turnLeft(currDirection, reverseOrientation);
00605
00606
00607 bool endIsFound = false;
00608 bool startIsEnd = false;
00609
00610 while (!endIsFound) {
00611
00612 bool nextStepFound = false;
00613 int status = 0;
00614 noDirs = 0;
00615 while (!nextStepFound) {
00616 next = makeStepInDirection(currDirection, theEcalNav);
00617 theEcalNav->setHome(current);
00618 theEcalNav->home();
00619 EcalChannelStatus::const_iterator chit = ecalStatus->find(next);
00620 status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00621 if (status > 0) {
00622
00623 endIsFound = true;
00624 break;
00625 } else if (next == EcalDetId(0)) {
00626
00627 currDirection = turnLeft(currDirection, reverseOrientation);
00628 } else if (status == 0) {
00629 if (RecHits->find(next) != RecHits->end()) {
00630 nextStepFound = true;
00631 } else {
00632 endIsFound = true;
00633 break;
00634 }
00635 }
00636 ++noDirs;
00637 if (noDirs > 4) {
00638 std::cout << "No valid next direction can be found: This should never happen!" << std::endl;
00639 throw "ERROR";
00640 break;
00641 }
00642 }
00643
00644
00645 next = makeStepInDirection(currDirection, theEcalNav);
00646 current = next;
00647
00648 if (next == start) {
00649 startIsEnd = true;
00650 endIsFound = true;
00651 if (debug)
00652 std::cout << "Path along gap reached starting position!" << std::endl;
00653 }
00654
00655 if (debug) {
00656 std::cout << "Next step: " << (EcalDetId) next << " Status: " << status << " Start: " << (EcalDetId) start << std::endl;
00657 if (endIsFound)
00658 std::cout << "End of gap cluster is found going left" << std::endl;
00659 }
00660
00661
00662 if (!endIsFound) {
00663 gapDetIds.push_back(next);
00664 if (RecHits->find(next) != RecHits->end()) {
00665 EcalRecHit nexthit = *RecHits->find(next);
00666 ++gapCellCounter;
00667 gapRecHits.push_back(nexthit);
00668 gapEnergy += nexthit.energy();
00669 cellGeom = subGeom->getGeometry(next);
00670 eta = cellGeom->getPosition().eta();
00671 gapET += nexthit.energy() / cosh(eta);
00672 }
00673 }
00674
00675
00676 currDirection = turnRight(currDirection, reverseOrientation);
00677
00678 }
00679
00681 theEcalNav->setHome(start);
00682 theEcalNav->home();
00683 current = start;
00684 currDirection = startDirection;
00685 currDirection = turnRight(currDirection, reverseOrientation);
00686
00687
00688 endIsFound = false;
00689
00690 if (!startIsEnd) {
00691
00692 while (!endIsFound) {
00693
00694 bool nextStepFound = false;
00695 int status = 0;
00696 noDirs = 0;
00697 while (!nextStepFound) {
00698 next = makeStepInDirection(currDirection, theEcalNav);
00699 theEcalNav->setHome(current);
00700 theEcalNav->home();
00701 EcalChannelStatus::const_iterator chit = ecalStatus->find(next);
00702 status = (chit != ecalStatus->end()) ? chit->getStatusCode() & 0x1F : -1;
00703 if (status > 0) {
00704
00705 endIsFound = true;
00706 break;
00707 } else if (next == EcalDetId(0)) {
00708
00709 currDirection = turnRight(currDirection, reverseOrientation);
00710 } else if (status == 0) {
00711 if (RecHits->find(next) != RecHits->end()) {
00712 nextStepFound = true;
00713 } else {
00714 endIsFound = true;
00715 break;
00716 }
00717 }
00718 ++noDirs;
00719 if (noDirs > 4) {
00720 std::cout << "No valid next direction can be found: This should never happen!" << std::endl;
00721 throw "ERROR";
00722 break;
00723 }
00724 }
00725
00726
00727 next = makeStepInDirection(currDirection, theEcalNav);
00728 current = next;
00729
00730 if (debug) {
00731 std::cout << "Next step: " << (EcalDetId) next << " Status: " << status << " Start: " << (EcalDetId) start
00732 << std::endl;
00733 if (endIsFound)
00734 std::cout << "End of gap cluster is found going right" << std::endl;
00735 }
00736
00737
00738 if (!endIsFound) {
00739 gapDetIds.push_back(next);
00740 if (RecHits->find(next) != RecHits->end()) {
00741 EcalRecHit nexthit = *RecHits->find(next);
00742 ++gapCellCounter;
00743 gapRecHits.push_back(nexthit);
00744 gapEnergy += nexthit.energy();
00745 cellGeom = subGeom->getGeometry(next);
00746 eta = cellGeom->getPosition().eta();
00747 gapET += nexthit.energy() / cosh(eta);
00748 }
00749 }
00750
00751
00752 currDirection = turnLeft(currDirection, reverseOrientation);
00753
00754 }
00755 }
00756
00757 if (debug) {
00758 std::cout << "<<<<<<<<<<<<<<< Final Gap object <<<<<<<<<<<<<<<" << std::endl;
00759 std::cout << "No of RecHits along gap: " << gapRecHits.size() << std::endl;
00760 std::cout << "No of DetIds along gap: " << gapDetIds.size() << std::endl;
00761 std::cout << "Gap energy: " << gapEnergy << std::endl;
00762 std::cout << "Gap ET: " << gapET << std::endl;
00763 }
00764
00765 BoundaryInformation gapInfo;
00766 gapInfo.subdet = hitdetid.subdet();
00767 gapInfo.detIds = gapDetIds;
00768 gapInfo.recHits = gapRecHits;
00769 gapInfo.boundaryEnergy = gapEnergy;
00770 gapInfo.boundaryET = gapET;
00771 gapInfo.nextToBorder = nextToBorder;
00772 std::vector<int> stati;
00773 gapInfo.channelStatus = stati;
00774
00775 if (theEcalNav != 0) {
00776 delete theEcalNav;
00777 theEcalNav = 0;
00778 }
00779 return gapInfo;
00780 }
00781
00782 #endif