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