File indexing completed on 2024-04-06 12:31:36
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019 #include "TrackingTools/TrackAssociator/interface/DetIdAssociator.h"
0020 #include "DetIdInfo.h"
0021 #include "FWCore/Utilities/interface/isFinite.h"
0022 #include <map>
0023
0024 DetIdAssociator::DetIdAssociator(const int nPhi, const int nEta, const double etaBinSize)
0025 : nPhi_(nPhi),
0026 nEta_(nEta),
0027 lookupMap_(nPhi_ * nEta_, std::pair<unsigned int, unsigned int>(0, 0)),
0028 theMapIsValid_(false),
0029 etaBinSize_(etaBinSize) {
0030 if (nEta_ <= 0 || nPhi_ <= 0)
0031 throw cms::Exception("FatalError") << "incorrect look-up map size. Cannot initialize such a map.";
0032 maxEta_ = etaBinSize_ * nEta_ / 2;
0033 minTheta_ = 2 * atan(exp(-maxEta_));
0034 }
0035
0036 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction, const int iN) const {
0037 unsigned int n = 0;
0038 if (iN > 0)
0039 n = iN;
0040 return getDetIdsCloseToAPoint(direction, n, n, n, n);
0041 }
0042
0043 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction,
0044 const unsigned int iNEtaPlus,
0045 const unsigned int iNEtaMinus,
0046 const unsigned int iNPhiPlus,
0047 const unsigned int iNPhiMinus) const {
0048 std::set<DetId> set;
0049 check_setup();
0050 if (!theMapIsValid_)
0051 throw cms::Exception("FatalError") << "map is not valid.";
0052 LogTrace("TrackAssociator") << "(iNEtaPlus, iNEtaMinus, iNPhiPlus, iNPhiMinus): " << iNEtaPlus << ", " << iNEtaMinus
0053 << ", " << iNPhiPlus << ", " << iNPhiMinus;
0054 LogTrace("TrackAssociator") << "point (eta,phi): " << direction.eta() << "," << direction.phi();
0055 int ieta = iEta(direction);
0056 int iphi = iPhi(direction);
0057 LogTrace("TrackAssociator") << "(ieta,iphi): " << ieta << "," << iphi << "\n";
0058 if (ieta >= 0 && ieta < nEta_ && iphi >= 0 && iphi < nPhi_) {
0059 fillSet(set, ieta, iphi);
0060
0061
0062 if (iNEtaPlus + iNEtaMinus + iNPhiPlus + iNPhiMinus > 0) {
0063 LogTrace("TrackAssociator") << "Add neighbors (ieta,iphi): " << ieta << "," << iphi;
0064
0065 int maxIEta = ieta + iNEtaPlus;
0066 int minIEta = ieta - iNEtaMinus;
0067 if (maxIEta >= nEta_)
0068 maxIEta = nEta_ - 1;
0069 if (minIEta < 0)
0070 minIEta = 0;
0071
0072 int maxIPhi = iphi + iNPhiPlus;
0073 int minIPhi = iphi - iNPhiMinus;
0074 if (maxIPhi - minIPhi >= nPhi_) {
0075 minIPhi = 0;
0076 maxIPhi = nPhi_ - 1;
0077 }
0078 if (minIPhi < 0) {
0079 minIPhi += nPhi_;
0080 maxIPhi += nPhi_;
0081 }
0082 LogTrace("TrackAssociator") << "\tieta (min,max): " << minIEta << "," << maxIEta;
0083 LogTrace("TrackAssociator") << "\tiphi (min,max): " << minIPhi << "," << maxIPhi << "\n";
0084
0085 for (int i = minIEta; i <= maxIEta; i++)
0086 for (int j = minIPhi; j <= maxIPhi; j++) {
0087 if (i == ieta && j == iphi)
0088 continue;
0089 fillSet(set, i, j % nPhi_);
0090 }
0091 }
0092 }
0093 return set;
0094 }
0095
0096 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& point, const double d) const {
0097 return getDetIdsCloseToAPoint(point, d, d, d, d);
0098 }
0099
0100 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& point,
0101 const double dThetaPlus,
0102 const double dThetaMinus,
0103 const double dPhiPlus,
0104 const double dPhiMinus) const {
0105 LogTrace("TrackAssociator") << "(dThetaPlus,dThetaMinus,dPhiPlus,dPhiMinus): " << dThetaPlus << ", " << dThetaMinus
0106 << ", " << dPhiPlus << ", " << dPhiMinus;
0107 unsigned int n = 0;
0108 if (dThetaPlus < 0 || dThetaMinus < 0 || dPhiPlus < 0 || dPhiMinus < 0)
0109 return getDetIdsCloseToAPoint(point, n, n, n, n);
0110
0111 double maxTheta = point.theta() + dThetaPlus;
0112 if (maxTheta > M_PI - minTheta_)
0113 maxTheta = M_PI - minTheta_;
0114 double minTheta = point.theta() - dThetaMinus;
0115 if (minTheta < minTheta_)
0116 minTheta = minTheta_;
0117 if (maxTheta < minTheta_ || minTheta > M_PI - minTheta_)
0118 return std::set<DetId>();
0119
0120
0121
0122 double minEta = -log(tan(maxTheta / 2));
0123 double maxEta = -log(tan(minTheta / 2));
0124 unsigned int iNEtaPlus = abs(int((maxEta - point.eta()) / etaBinSize_));
0125 unsigned int iNEtaMinus = abs(int((point.eta() - minEta) / etaBinSize_));
0126 unsigned int iNPhiPlus = abs(int(dPhiPlus / (2 * M_PI) * nPhi_));
0127 unsigned int iNPhiMinus = abs(int(dPhiMinus / (2 * M_PI) * nPhi_));
0128
0129 return getDetIdsCloseToAPoint(point, iNEtaPlus + 1, iNEtaMinus + 1, iNPhiPlus + 1, iNPhiMinus + 1);
0130 }
0131
0132 int DetIdAssociator::iEta(const GlobalPoint& point) const { return int(point.eta() / etaBinSize_ + nEta_ / 2); }
0133
0134 int DetIdAssociator::iPhi(const GlobalPoint& point) const {
0135 return int((double(point.phi()) + M_PI) / (2 * M_PI) * nPhi_);
0136 }
0137
0138 void DetIdAssociator::buildMap() {
0139
0140
0141
0142 check_setup();
0143 LogTrace("TrackAssociator") << "building map for " << name() << "\n";
0144
0145 if (nEta_ <= 0 || nPhi_ <= 0)
0146 throw cms::Exception("FatalError") << "incorrect look-up map size. Cannot build such a map.";
0147 std::vector<GlobalPoint> pointBuffer;
0148 std::vector<DetId> detIdBuffer;
0149 unsigned int numberOfSubDetectors = getNumberOfSubdetectors();
0150 unsigned totalNumberOfElementsInTheContainer(0);
0151 for (unsigned int step = 0; step < 2; ++step) {
0152 unsigned int numberOfDetIdsOutsideEtaRange = 0;
0153 unsigned int numberOfDetIdsActive = 0;
0154 LogTrace("TrackAssociator") << "Step: " << step;
0155 for (unsigned int subDetectorIndex = 0; subDetectorIndex < numberOfSubDetectors; ++subDetectorIndex) {
0156 getValidDetIds(subDetectorIndex, detIdBuffer);
0157
0158 std::vector<DetId> const& validIds = std::move(detIdBuffer);
0159 LogTrace("TrackAssociator") << "Number of valid DetIds for subdetector: " << subDetectorIndex << " is "
0160 << validIds.size();
0161 for (std::vector<DetId>::const_iterator id_itr = validIds.begin(); id_itr != validIds.end(); id_itr++) {
0162 std::pair<const_iterator, const_iterator> points = getDetIdPoints(*id_itr, pointBuffer);
0163 LogTrace("TrackAssociatorVerbose") << "Found " << points.second - points.first
0164 << " global points to describe geometry of DetId: " << id_itr->rawId();
0165 int etaMax(-1);
0166 int etaMin(-1);
0167 int phiMax(-1);
0168 int phiMin(-1);
0169
0170 for (std::vector<GlobalPoint>::const_iterator iter = points.first; iter != points.second; iter++) {
0171 LogTrace("TrackAssociatorVerbose")
0172 << "\tpoint (rho,phi,z): " << iter->perp() << ", " << iter->phi() << ", " << iter->z();
0173
0174 if (edm::isNotFinite(iter->mag()) || iter->mag() > 1e5) {
0175 edm::LogWarning("TrackAssociator")
0176 << "Critical error! Bad detector unit geometry:\n\tDetId:" << id_itr->rawId()
0177 << "\t mag(): " << iter->mag() << "\n"
0178 << DetIdInfo::info(*id_itr, nullptr) << "\nSkipped the element";
0179 continue;
0180 }
0181 volume_.addActivePoint(*iter);
0182 int ieta = iEta(*iter);
0183 int iphi = iPhi(*iter);
0184 if (ieta < 0 || ieta >= nEta_) {
0185 LogTrace("TrackAssociator") << "Out of range: DetId:" << id_itr->rawId() << "\t (ieta,iphi): " << ieta
0186 << "," << iphi << "\n"
0187 << "Point: " << *iter << "\t(eta,phi): " << (*iter).eta() << ","
0188 << (*iter).phi() << "\n center: " << getPosition(*id_itr);
0189 continue;
0190 }
0191 if (phiMin < 0) {
0192
0193 etaMin = ieta;
0194 etaMax = ieta;
0195 phiMin = iphi;
0196 phiMax = iphi;
0197 } else {
0198
0199 int deltaMin = abs(phiMin - iphi);
0200 int deltaMax = abs(phiMax - iphi);
0201
0202 if (deltaMin > nPhi_ / 2 && phiMin < nPhi_ / 2)
0203 phiMin += nPhi_;
0204 if (deltaMax > nPhi_ / 2) {
0205 if (phiMax < nPhi_ / 2)
0206 phiMax += nPhi_;
0207 else
0208 iphi += nPhi_;
0209 }
0210 assert(iphi >= 0);
0211 if (etaMin > ieta)
0212 etaMin = ieta;
0213 if (etaMax < ieta)
0214 etaMax = ieta;
0215 if (phiMin > iphi)
0216 phiMin = iphi;
0217 if (phiMax < iphi)
0218 phiMax = iphi;
0219 }
0220 }
0221 if (etaMax < 0 || phiMax < 0 || etaMin >= nEta_ || phiMin >= nPhi_) {
0222 LogTrace("TrackAssociatorVerbose")
0223 << "Out of range or no geometry: DetId:" << id_itr->rawId() << "\n\teta (min,max): " << etaMin << ","
0224 << etaMax << "\n\tphi (min,max): " << phiMin << "," << phiMax << "\nTower id: " << id_itr->rawId()
0225 << "\n";
0226 numberOfDetIdsOutsideEtaRange++;
0227 continue;
0228 }
0229 numberOfDetIdsActive++;
0230
0231 LogTrace("TrackAssociatorVerbose") << "DetId (ieta_min,ieta_max,iphi_min,iphi_max): " << id_itr->rawId() << ", "
0232 << etaMin << ", " << etaMax << ", " << phiMin << ", " << phiMax;
0233 for (int ieta = etaMin; ieta <= etaMax; ieta++)
0234 for (int iphi = phiMin; iphi <= phiMax; iphi++)
0235 if (step == 0) {
0236 lookupMap_.at(index(ieta, iphi % nPhi_)).second++;
0237 totalNumberOfElementsInTheContainer++;
0238 } else {
0239 container_.at(lookupMap_.at(index(ieta, iphi % nPhi_)).first) = *id_itr;
0240 lookupMap_.at(index(ieta, iphi % nPhi_)).first--;
0241 totalNumberOfElementsInTheContainer--;
0242 }
0243 }
0244 }
0245 LogTrace("TrackAssociator") << "Number of elements outside the allowed range ( |eta|>" << nEta_ / 2 * etaBinSize_
0246 << "): " << numberOfDetIdsOutsideEtaRange << "\n";
0247 LogTrace("TrackAssociator") << "Number of active DetId's mapped: " << numberOfDetIdsActive << "\n";
0248 if (step == 0) {
0249
0250 container_.resize(totalNumberOfElementsInTheContainer);
0251
0252 unsigned int index(0);
0253 for (std::vector<std::pair<unsigned int, unsigned int> >::iterator bin = lookupMap_.begin();
0254 bin != lookupMap_.end();
0255 ++bin) {
0256 if (bin->second == 0)
0257 continue;
0258 index += bin->second;
0259 bin->first = index - 1;
0260 }
0261 }
0262 }
0263 if (totalNumberOfElementsInTheContainer != 0)
0264 throw cms::Exception("FatalError")
0265 << "Look-up map filled incorrectly. Structural problem. Get in touch with the developer.";
0266 volume_.determinInnerDimensions();
0267 edm::LogVerbatim("TrackAssociator") << "Fiducial volume for " << name()
0268 << " (minR, maxR, minZ, maxZ): " << volume_.minR() << ", " << volume_.maxR()
0269 << ", " << volume_.minZ() << ", " << volume_.maxZ();
0270 theMapIsValid_ = true;
0271 }
0272
0273 std::set<DetId> DetIdAssociator::getDetIdsInACone(const std::set<DetId>& inset,
0274 const std::vector<GlobalPoint>& trajectory,
0275 const double dR) const {
0276 if (selectAllInACone(dR))
0277 return inset;
0278 check_setup();
0279 std::set<DetId> outset;
0280 for (std::set<DetId>::const_iterator id_iter = inset.begin(); id_iter != inset.end(); id_iter++)
0281 for (std::vector<GlobalPoint>::const_iterator point_iter = trajectory.begin(); point_iter != trajectory.end();
0282 point_iter++)
0283 if (nearElement(*point_iter, *id_iter, dR)) {
0284 outset.insert(*id_iter);
0285 break;
0286 }
0287 return outset;
0288 }
0289
0290 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
0291 const std::vector<GlobalPoint>& trajectory) const {
0292 check_setup();
0293 std::vector<DetId> output;
0294 std::set<DetId> ids(inset);
0295 for (unsigned int i = 0; i + 1 < trajectory.size(); ++i) {
0296 std::set<DetId>::const_iterator id_iter = ids.begin();
0297 while (id_iter != ids.end()) {
0298 if (crossedElement(trajectory[i], trajectory[i + 1], *id_iter)) {
0299 output.push_back(*id_iter);
0300 ids.erase(id_iter++);
0301 } else
0302 id_iter++;
0303 }
0304 }
0305 return output;
0306 }
0307
0308 std::vector<DetId> DetIdAssociator::getCrossedDetIds(const std::set<DetId>& inset,
0309 const std::vector<SteppingHelixStateInfo>& trajectory,
0310 const double tolerance) const {
0311 check_setup();
0312 std::vector<DetId> output;
0313 std::set<DetId> ids(inset);
0314 for (unsigned int i = 0; i + 1 < trajectory.size(); ++i) {
0315 std::set<DetId>::const_iterator id_iter = ids.begin();
0316 while (id_iter != ids.end()) {
0317 if (crossedElement(trajectory[i].position(), trajectory[i + 1].position(), *id_iter, tolerance, &trajectory[i])) {
0318 output.push_back(*id_iter);
0319 ids.erase(id_iter++);
0320 } else
0321 id_iter++;
0322 }
0323 }
0324 return output;
0325 }
0326
0327 void DetIdAssociator::dumpMapContent(int ieta, int iphi) const {
0328 if (!(ieta >= 0 && ieta < nEta_ && iphi >= 0)) {
0329 edm::LogWarning("TrackAssociator") << "ieta or iphi is out of range. Skipped.";
0330 return;
0331 }
0332
0333 std::vector<GlobalPoint> pointBuffer;
0334 std::set<DetId> set;
0335 fillSet(set, ieta, iphi % nPhi_);
0336 LogTrace("TrackAssociator") << "Map content for cell (ieta,iphi): " << ieta << ", " << iphi % nPhi_;
0337 for (std::set<DetId>::const_iterator itr = set.begin(); itr != set.end(); itr++) {
0338 LogTrace("TrackAssociator") << "\tDetId " << itr->rawId() << ", geometry (x,y,z,rho,eta,phi):";
0339 std::pair<const_iterator, const_iterator> points = getDetIdPoints(*itr, pointBuffer);
0340 for (std::vector<GlobalPoint>::const_iterator point = points.first; point != points.second; point++)
0341 LogTrace("TrackAssociator") << "\t\t" << point->x() << ", " << point->y() << ", " << point->z() << ", "
0342 << point->perp() << ", " << point->eta() << ", " << point->phi();
0343 }
0344 }
0345
0346 void DetIdAssociator::dumpMapContent(int ieta_min, int ieta_max, int iphi_min, int iphi_max) const {
0347 for (int i = ieta_min; i <= ieta_max; i++)
0348 for (int j = iphi_min; j <= iphi_max; j++)
0349 dumpMapContent(i, j);
0350 }
0351
0352 const FiducialVolume& DetIdAssociator::volume() const {
0353 if (!theMapIsValid_)
0354 throw cms::Exception("FatalError") << "map is not valid.";
0355 return volume_;
0356 }
0357
0358 std::set<DetId> DetIdAssociator::getDetIdsCloseToAPoint(const GlobalPoint& direction, const MapRange& mapRange) const {
0359 return getDetIdsCloseToAPoint(
0360 direction, mapRange.dThetaPlus, mapRange.dThetaMinus, mapRange.dPhiPlus, mapRange.dPhiMinus);
0361 }
0362
0363 bool DetIdAssociator::nearElement(const GlobalPoint& point, const DetId& id, const double distance) const {
0364 GlobalPoint center = getPosition(id);
0365 double deltaPhi(fabs(point.phi() - center.phi()));
0366 if (deltaPhi > M_PI)
0367 deltaPhi = fabs(deltaPhi - M_PI * 2.);
0368 return (point.eta() - center.eta()) * (point.eta() - center.eta()) + deltaPhi * deltaPhi < distance * distance;
0369 }
0370
0371 void DetIdAssociator::check_setup() const {
0372 if (nEta_ == 0)
0373 throw cms::Exception("FatalError") << "Number of eta bins is not set.\n";
0374 if (nPhi_ == 0)
0375 throw cms::Exception("FatalError") << "Number of phi bins is not set.\n";
0376
0377 if (etaBinSize_ == 0)
0378 throw cms::Exception("FatalError") << "Eta bin size is not set.\n";
0379 }
0380
0381 void DetIdAssociator::fillSet(std::set<DetId>& set, unsigned int iEta, unsigned int iPhi) const {
0382 unsigned int i = index(iEta, iPhi);
0383 unsigned int i0 = lookupMap_.at(i).first;
0384 unsigned int size = lookupMap_.at(i).second;
0385 for (i = i0; i < i0 + size; ++i)
0386 set.insert(container_.at(i));
0387 }
0388
0389 #include "FWCore/PluginManager/interface/ModuleDef.h"
0390 #include "FWCore/Framework/interface/MakerMacros.h"
0391
0392 #include "FWCore/Utilities/interface/typelookup.h"
0393 TYPELOOKUP_DATA_REG(DetIdAssociator);
0394
0395