/
githubmirror
/
cmssw
Обзор
Документация
Войти
/
githubmirror
/
cmssw
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
FastSimulation/CaloGeometryTools/src/CaloGeometryHelper.cc
390 строк
13 KB
Kevin Pedro
code checks and format
06 дек 2025, 01:59
06 дек 2025, 01:59
6cee54b
Код
Авторство
О чём код?
#include "FastSimulation/CaloGeometryTools/interface/CaloGeometryHelper.h" //#include "FWCore/ParameterSet/interface/ParameterSet.h" // needed for the debugging #include "Geometry/CaloGeometry/interface/CaloCellGeometry.h" #include "Geometry/EcalAlgo/interface/EcalBarrelGeometry.h" #include "Geometry/EcalAlgo/interface/EcalEndcapGeometry.h" #include "Geometry/HcalTowerAlgo/interface/HcalGeometry.h" #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h" #include "DataFormats/EcalDetId/interface/EBDetId.h" #include "DataFormats/EcalDetId/interface/EEDetId.h" #include "DataFormats/EcalDetId/interface/ESDetId.h" #include "DataFormats/HcalDetId/interface/HcalDetId.h" #include "DataFormats/EcalDetId/interface/EcalSubdetector.h" #include "Geometry/EcalAlgo/interface/EcalPreshowerGeometry.h" #include "FastSimulation/CaloGeometryTools/interface/DistanceToCell.h" #include "FastSimulation/CaloGeometryTools/interface/Crystal.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" #include <algorithm> CaloGeometryHelper::CaloGeometryHelper() : Calorimeter() { neighbourmapcalculated_ = false; psLayer1Z_ = 303; psLayer2Z_ = 307; } CaloGeometryHelper::CaloGeometryHelper(const edm::ParameterSet& fastCalo, const CaloGeometry& pG, const CaloTopology& theTopology, double bField) : Calorimeter(fastCalo, pG, theTopology) { setupHelper(bField); } CaloGeometryHelper::CaloGeometryHelper(const CaloGeometry& pG, const CaloTopology& theTopology, double bField) { setupGeomTopo(pG, theTopology); setupHelper(bField); } void CaloGeometryHelper::setupHelper(double bField) { psLayer1Z_ = 303; psLayer2Z_ = 307; buildCrystalArray(); buildNeighbourArray(); bfield_ = bField; preshowerPresent_ = (getEcalPreshowerGeometry() != nullptr); if (preshowerPresent_) { ESDetId cps1(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80., 80., 303.), 1)); psLayer1Z_ = getEcalPreshowerGeometry()->getGeometry(cps1)->getPosition().z(); ESDetId cps2(getEcalPreshowerGeometry()->getClosestCellInPlane(GlobalPoint(80., 80., 307.), 2)); psLayer2Z_ = getEcalPreshowerGeometry()->getGeometry(cps2)->getPosition().z(); LogDebug("CaloGeometryTools") << " Preshower layer positions " << psLayer1Z_ << " " << psLayer2Z_ << std::endl; } else LogDebug("CaloGeometryTools") << " No preshower present" << std::endl; } CaloGeometryHelper::~CaloGeometryHelper() { ; } DetId CaloGeometryHelper::getClosestCell(const XYZPoint& point, bool ecal, bool central) const { DetId result; if (ecal) { if (central) { result = EcalBarrelGeometry_->getClosestCell(GlobalPoint(point.X(), point.Y(), point.Z())); #ifdef DEBUGGCC if (result.null()) return result; GlobalPoint ip = GlobalPoint(point.X(), point.Y(), point.Z()); GlobalPoint cc = EcalBarrelGeometry_->getGeometry(result)->getPosition(); float deltaeta2 = ip.eta() - cc.eta(); deltaeta2 *= deltaeta2; float deltaphi2 = acos(cos(ip.phi() - cc.phi())); deltaphi2 *= deltaphi2; Histos::instance()->fill("h100", point.eta(), sqrt(deltaeta2 + deltaphi2)); #endif } else { result = EcalEndcapGeometry_->getClosestCell(GlobalPoint(point.X(), point.Y(), point.Z())); #ifdef DEBUGGCC if (result.null()) { return result; } GlobalPoint ip = GlobalPoint(point.X(), point.Y(), point.Z()); GlobalPoint cc = EcalEndcapGeometry_->getGeometry(result)->getPosition(); Histos::instance()->fill("h110", point.eta(), (ip - cc).perp()); #endif } } else { result = static_cast<const HcalGeometry*>(HcalGeometry_) ->getClosestCell(GlobalPoint(point.X(), point.Y(), point.Z()), true); HcalDetId myDetId(result); // special patch for HF (this is already a part of HcalGeometry) if (myDetId.subdetId() == HcalForward) { int mylayer; if (fabs(point.Z()) > 1132.) { mylayer = 2; } else { mylayer = 1; } HcalDetId myDetId2((HcalSubdetector)myDetId.subdetId(), myDetId.ieta(), myDetId.iphi(), mylayer); result = myDetId2; } #ifdef DEBUGGCC if (result.null()) { return result; } GlobalPoint ip = GlobalPoint(point.x(), point.y(), point.z()); GlobalPoint cc = HcalGeometry_->getPosition(result); float deltaeta2 = ip.eta() - cc.eta(); deltaeta2 *= deltaeta2; float deltaphi2 = acos(cos(ip.phi() - cc.phi())); deltaphi2 *= deltaphi2; Histos::instance()->fill("h120", point.eta(), sqrt(deltaeta2 + deltaphi2)); #endif } return result; } void CaloGeometryHelper::getWindow(const DetId& pivot, int s1, int s2, std::vector<DetId>& vec) const { // currently the getWindow method is the same for EcalBarrelTopology and EndcapTopology // (implemented in CaloSubDetectorTopology) // optimized versions are foreseen vec = getEcalTopology(pivot.subdetId())->getWindow(pivot, s1, s2); DistanceToCell distance(getEcalGeometry(pivot.subdetId()), pivot); sort(vec.begin(), vec.end(), distance); } void CaloGeometryHelper::buildCrystal(const DetId& cell, Crystal& xtal) const { if (cell.subdetId() == EcalBarrel) { xtal = Crystal(cell, &barrelCrystals_[EBDetId(cell).hashedIndex()]); return; } if (cell.subdetId() == EcalEndcap) { xtal = Crystal(cell, &endcapCrystals_[EEDetId(cell).hashedIndex()]); return; } } // Build the array of (max)8 neighbors void CaloGeometryHelper::buildNeighbourArray() { static const CaloDirection orderedDir[8] = {SOUTHWEST, SOUTH, SOUTHEAST, WEST, EAST, NORTHWEST, NORTH, NORTHEAST}; const unsigned nbarrel = EBDetId::kSizeForDenseIndexing; // Barrel first. The hashed index runs from 0 to 61199 barrelNeighbours_.resize(nbarrel); //std::cout << " Building the array of neighbours (barrel) " ; const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal, EcalBarrel)); unsigned size = vec.size(); for (unsigned ic = 0; ic < size; ++ic) { // We get the 9 cells in a square. std::vector<DetId> neighbours(EcalBarrelTopology_->getWindow(vec[ic], 3, 3)); // std::cout << " Cell " << EBDetId(vec[ic]) << std::endl; unsigned nneighbours = neighbours.size(); unsigned hashedindex = EBDetId(vec[ic]).hashedIndex(); if (hashedindex >= nbarrel) { LogDebug("CaloGeometryTools") << " Array overflow " << std::endl; } // If there are 9 cells, it is easy, and this order is know: // 6 7 8 // 3 4 5 // 0 1 2 (0 = SOUTHWEST) if (nneighbours == 9) { //barrelNeighbours_[hashedindex].reserve(8); unsigned int nn = 0; for (unsigned in = 0; in < nneighbours; ++in) { // remove the centre if (neighbours[in] != vec[ic]) { barrelNeighbours_[hashedindex][nn] = (neighbours[in]); nn++; } } } else { DetId central(vec[ic]); for (unsigned idir = 0; idir < 8; ++idir) { DetId testid = central; bool status = move(testid, orderedDir[idir], false); if (status) barrelNeighbours_[hashedindex][idir] = testid; } } } // Moved to the endcap const std::vector<DetId>& vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal, EcalEndcap)); size = vece.size(); // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number // of crystals const unsigned nendcap = EEDetId::kSizeForDenseIndexing; endcapNeighbours_.resize(nendcap); for (unsigned ic = 0; ic < size; ++ic) { // We get the 9 cells in a square. std::vector<DetId> neighbours(EcalEndcapTopology_->getWindow(vece[ic], 3, 3)); unsigned nneighbours = neighbours.size(); // remove the centre unsigned hashedindex = EEDetId(vece[ic]).hashedIndex(); if (hashedindex >= nendcap) { LogDebug("CaloGeometryTools") << " Array overflow " << std::endl; } if (nneighbours == 9) { unsigned int nn = 0; for (unsigned in = 0; in < nneighbours; ++in) { // remove the centre if (neighbours[in] != vece[ic]) { endcapNeighbours_[hashedindex][nn] = (neighbours[in]); nn++; } } } else { DetId central(vece[ic]); for (unsigned idir = 0; idir < 8; ++idir) { DetId testid = central; bool status = move(testid, orderedDir[idir], false); if (status) endcapNeighbours_[hashedindex][idir] = testid; } } } neighbourmapcalculated_ = true; } const CaloGeometryHelper::NeiVect& CaloGeometryHelper::getNeighbours(const DetId& detid) const { return (detid.subdetId() == EcalBarrel) ? barrelNeighbours_[EBDetId(detid).hashedIndex()] : endcapNeighbours_[EEDetId(detid).hashedIndex()]; } bool CaloGeometryHelper::move(DetId& cell, const CaloDirection& dir, bool fast) const { DetId originalcell = cell; if (dir == NONE || cell == DetId(0)) return false; // Conversion CaloDirection and index in the table // CaloDirection :NONE,SOUTH,SOUTHEAST,SOUTHWEST,EAST,WEST, NORTHEAST,NORTHWEST,NORTH // Table : SOUTHWEST,SOUTH,SOUTHEAST,WEST,EAST,NORTHWEST,NORTH, NORTHEAST static const int calodirections[9] = {-1, 1, 2, 0, 4, 3, 7, 5, 6}; if (fast && neighbourmapcalculated_) { DetId result = (originalcell.subdetId() == EcalBarrel) ? barrelNeighbours_[EBDetId(originalcell).hashedIndex()][calodirections[dir]] : endcapNeighbours_[EEDetId(originalcell).hashedIndex()][calodirections[dir]]; bool status = !result.null(); cell = result; return status; } if (dir == NORTH || dir == SOUTH || dir == EAST || dir == WEST) { return simplemove(cell, dir); } else { if (dir == NORTHEAST || dir == NORTHWEST || dir == SOUTHEAST || dir == SOUTHWEST) return diagonalmove(cell, dir); } cell = DetId(0); return false; } bool CaloGeometryHelper::simplemove(DetId& cell, const CaloDirection& dir) const { std::vector<DetId> neighbours; if (cell.subdetId() == EcalBarrel) neighbours = EcalBarrelTopology_->getNeighbours(cell, dir); else if (cell.subdetId() == EcalEndcap) neighbours = EcalEndcapTopology_->getNeighbours(cell, dir); if ((!neighbours.empty()) && (!neighbours[0].null())) { cell = neighbours[0]; return true; } else { cell = DetId(0); return false; } } bool CaloGeometryHelper::diagonalmove(DetId& cell, const CaloDirection& dir) const { bool result; // One has to try both paths if (dir == NORTHEAST) { result = simplemove(cell, NORTH); if (result) return simplemove(cell, EAST); else { result = simplemove(cell, EAST); if (result) return simplemove(cell, NORTH); else return false; } } else if (dir == NORTHWEST) { result = simplemove(cell, NORTH); if (result) return simplemove(cell, WEST); else { result = simplemove(cell, WEST); if (result) return simplemove(cell, NORTH); else return false; } } else if (dir == SOUTHEAST) { result = simplemove(cell, SOUTH); if (result) return simplemove(cell, EAST); else { result = simplemove(cell, EAST); if (result) return simplemove(cell, SOUTH); else return false; } } else if (dir == SOUTHWEST) { result = simplemove(cell, SOUTH); if (result) return simplemove(cell, WEST); else { result = simplemove(cell, SOUTH); if (result) return simplemove(cell, WEST); else return false; } } cell = DetId(0); return false; } bool CaloGeometryHelper::borderCrossing(const DetId& c1, const DetId& c2) const { if (c1.subdetId() != c2.subdetId()) return false; if (c1.subdetId() == EcalBarrel) { // there is a crack if the two cells don't belong to the same // module EBDetId cc1(c1); EBDetId cc2(c2); return (cc1.im() != cc2.im() || cc1.ism() != cc2.ism()); } if (c1.subdetId() == EcalEndcap) { // there is a crack if the two cells don't belong to the same // module return (EEDetId(c1).isc() != EEDetId(c2).isc()); } return false; } void CaloGeometryHelper::buildCrystalArray() { const unsigned nbarrel = EBDetId::kSizeForDenseIndexing; // Barrel first. The hashed index runs from 0 to 61199 barrelCrystals_.resize(nbarrel, BaseCrystal()); const std::vector<DetId>& vec(EcalBarrelGeometry_->getValidDetIds(DetId::Ecal, EcalBarrel)); unsigned size = vec.size(); for (unsigned ic = 0; ic < size; ++ic) { unsigned hashedindex = EBDetId(vec[ic]).hashedIndex(); auto geom = EcalBarrelGeometry_->getGeometry(vec[ic]); BaseCrystal xtal(vec[ic]); xtal.setCorners(geom->getCorners(), geom->getPosition()); barrelCrystals_[hashedindex] = xtal; } const std::vector<DetId>& vece(EcalEndcapGeometry_->getValidDetIds(DetId::Ecal, EcalEndcap)); size = vece.size(); // There are some holes in the hashedIndex for the EE. Hence the array is bigger than the number // of crystals const unsigned nendcap = EEDetId::kSizeForDenseIndexing; endcapCrystals_.resize(nendcap, BaseCrystal()); for (unsigned ic = 0; ic < size; ++ic) { unsigned hashedindex = EEDetId(vece[ic]).hashedIndex(); auto geom = EcalEndcapGeometry_->getGeometry(vece[ic]); BaseCrystal xtal(vece[ic]); xtal.setCorners(geom->getCorners(), geom->getPosition()); endcapCrystals_[hashedindex] = xtal; } }