File indexing completed on 2024-04-06 12:26:14
0001
0002
0003
0004
0005
0006
0007
0008 #include "ME0SegmentAlgorithm.h"
0009 #include "MuonSegFit.h"
0010
0011 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0012 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0013 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0014 #include "DataFormats/Math/interface/deltaPhi.h"
0015 #include "CommonTools/Statistics/interface/ChiSquaredProbability.h"
0016
0017 #include <algorithm>
0018 #include <cmath>
0019 #include <iostream>
0020 #include <string>
0021
0022
0023
0024
0025 ME0SegmentAlgorithm::ME0SegmentAlgorithm(const edm::ParameterSet& ps)
0026 : ME0SegmentAlgorithmBase(ps), myName("ME0SegmentAlgorithm") {
0027 debug = ps.getUntrackedParameter<bool>("ME0Debug");
0028 minHitsPerSegment = ps.getParameter<unsigned int>("minHitsPerSegment");
0029 preClustering = ps.getParameter<bool>("preClustering");
0030 dXclusBoxMax = ps.getParameter<double>("dXclusBoxMax");
0031 dYclusBoxMax = ps.getParameter<double>("dYclusBoxMax");
0032 preClustering_useChaining = ps.getParameter<bool>("preClusteringUseChaining");
0033 dPhiChainBoxMax = ps.getParameter<double>("dPhiChainBoxMax");
0034 dEtaChainBoxMax = ps.getParameter<double>("dEtaChainBoxMax");
0035 dTimeChainBoxMax = ps.getParameter<double>("dTimeChainBoxMax");
0036 maxRecHitsInCluster = ps.getParameter<int>("maxRecHitsInCluster");
0037
0038 edm::LogVerbatim("ME0SegmentAlgorithm")
0039 << "[ME0SegmentAlgorithm::ctor] Parameters to build segments :: "
0040 << "preClustering = " << preClustering << " preClustering_useChaining = " << preClustering_useChaining
0041 << " dPhiChainBoxMax = " << dPhiChainBoxMax << " dEtaChainBoxMax = " << dEtaChainBoxMax
0042 << " dTimeChainBoxMax = " << dTimeChainBoxMax << " minHitsPerSegment = " << minHitsPerSegment
0043 << " maxRecHitsInCluster = " << maxRecHitsInCluster;
0044 }
0045
0046
0047
0048
0049 ME0SegmentAlgorithm::~ME0SegmentAlgorithm() {}
0050
0051 std::vector<ME0Segment> ME0SegmentAlgorithm::run(const ME0Chamber* chamber, const HitAndPositionContainer& rechits) {
0052 #ifdef EDM_ML_DEBUG
0053 ME0DetId chId(chamber->id());
0054 edm::LogVerbatim("ME0SegAlgoMM") << "[ME0SegmentAlgorithm::run] build segments in chamber " << chId
0055 << " which contains " << rechits.size() << " rechits";
0056 for (auto rh = rechits.begin(); rh != rechits.end(); ++rh) {
0057 auto me0id = rh->rh->me0Id();
0058 auto rhLP = rh->lp;
0059 edm::LogVerbatim("ME0SegmentAlgorithm")
0060 << "[RecHit :: Loc x = " << std::showpos << std::setw(9) << rhLP.x() << " Loc y = " << std::showpos
0061 << std::setw(9) << rhLP.y() << " Time = " << std::showpos << rh->rh->tof() << " -- " << me0id.rawId() << " = "
0062 << me0id << " ]";
0063 }
0064 #endif
0065
0066
0067 std::vector<ME0Segment> segments_temp;
0068 std::vector<ME0Segment> segments;
0069 ProtoSegments rechits_clusters;
0070
0071 if (preClustering) {
0072
0073 if (preClustering_useChaining) {
0074
0075
0076 rechits_clusters = this->chainHits(chamber, rechits);
0077 } else {
0078
0079 rechits_clusters = this->clusterHits(rechits);
0080 }
0081
0082 for (auto sub_rechits = rechits_clusters.begin(); sub_rechits != rechits_clusters.end(); ++sub_rechits) {
0083
0084 segments_temp.clear();
0085
0086 this->buildSegments(chamber, (*sub_rechits), segments_temp);
0087
0088 segments.insert(segments.end(), segments_temp.begin(), segments_temp.end());
0089 }
0090 return segments;
0091 } else {
0092 HitAndPositionPtrContainer ptrRH;
0093 ptrRH.reserve(rechits.size());
0094 for (const auto& rh : rechits)
0095 ptrRH.push_back(&rh);
0096 this->buildSegments(chamber, ptrRH, segments);
0097 return segments;
0098 }
0099 }
0100
0101
0102 ME0SegmentAlgorithm::ProtoSegments ME0SegmentAlgorithm::clusterHits(const HitAndPositionContainer& rechits) {
0103 ProtoSegments rechits_clusters;
0104
0105 float dXclus_box = 0.0;
0106 float dYclus_box = 0.0;
0107
0108 ProtoSegments seeds;
0109 seeds.reserve(rechits.size());
0110
0111 std::vector<float> running_meanX;
0112 running_meanX.reserve(rechits.size());
0113 std::vector<float> running_meanY;
0114 running_meanY.reserve(rechits.size());
0115
0116 std::vector<float> seed_minX;
0117 seed_minX.reserve(rechits.size());
0118 std::vector<float> seed_maxX;
0119 seed_maxX.reserve(rechits.size());
0120 std::vector<float> seed_minY;
0121 seed_minY.reserve(rechits.size());
0122 std::vector<float> seed_maxY;
0123 seed_maxY.reserve(rechits.size());
0124
0125
0126
0127
0128 for (unsigned int i = 0; i < rechits.size(); ++i) {
0129 seeds.push_back(HitAndPositionPtrContainer(1, &rechits[i]));
0130
0131
0132
0133
0134 running_meanX.push_back(rechits[i].lp.x());
0135 running_meanY.push_back(rechits[i].lp.y());
0136
0137
0138 seed_minX.push_back(rechits[i].lp.x());
0139 seed_maxX.push_back(rechits[i].lp.x());
0140 seed_minY.push_back(rechits[i].lp.y());
0141 seed_maxY.push_back(rechits[i].lp.y());
0142 }
0143
0144
0145
0146 for (size_t NNN = 0; NNN < seeds.size(); ++NNN) {
0147 for (size_t MMM = NNN + 1; MMM < seeds.size(); ++MMM) {
0148 if (running_meanX[MMM] == running_max || running_meanX[NNN] == running_max) {
0149 LogDebug("ME0SegmentAlgorithm") << "[ME0SegmentAlgorithm::clusterHits]: ALARM! Skipping used seeds, this "
0150 "should not happen - inform developers!";
0151 continue;
0152 }
0153
0154
0155
0156
0157
0158 if (running_meanX[NNN] > running_meanX[MMM])
0159 dXclus_box = seed_minX[NNN] - seed_maxX[MMM];
0160 else
0161 dXclus_box = seed_minX[MMM] - seed_maxX[NNN];
0162 if (running_meanY[NNN] > running_meanY[MMM])
0163 dYclus_box = seed_minY[NNN] - seed_maxY[MMM];
0164 else
0165 dYclus_box = seed_minY[MMM] - seed_maxY[NNN];
0166
0167 if (dXclus_box < dXclusBoxMax && dYclus_box < dYclusBoxMax) {
0168
0169
0170
0171
0172 if (seeds[NNN].size() + seeds[MMM].size() != 0) {
0173 running_meanX[MMM] = (running_meanX[NNN] * seeds[NNN].size() + running_meanX[MMM] * seeds[MMM].size()) /
0174 (seeds[NNN].size() + seeds[MMM].size());
0175 running_meanY[MMM] = (running_meanY[NNN] * seeds[NNN].size() + running_meanY[MMM] * seeds[MMM].size()) /
0176 (seeds[NNN].size() + seeds[MMM].size());
0177 }
0178
0179
0180 if (seed_minX[NNN] < seed_minX[MMM])
0181 seed_minX[MMM] = seed_minX[NNN];
0182 if (seed_maxX[NNN] > seed_maxX[MMM])
0183 seed_maxX[MMM] = seed_maxX[NNN];
0184 if (seed_minY[NNN] < seed_minY[MMM])
0185 seed_minY[MMM] = seed_minY[NNN];
0186 if (seed_maxY[NNN] > seed_maxY[MMM])
0187 seed_maxY[MMM] = seed_maxY[NNN];
0188
0189
0190 seeds[MMM].insert(seeds[MMM].end(), seeds[NNN].begin(), seeds[NNN].end());
0191
0192
0193 running_meanX[NNN] = running_max;
0194 running_meanY[NNN] = running_max;
0195
0196
0197 break;
0198 }
0199 }
0200 }
0201
0202
0203
0204
0205 for (size_t NNN = 0; NNN < seeds.size(); ++NNN) {
0206 if (running_meanX[NNN] == running_max)
0207 continue;
0208 rechits_clusters.push_back(seeds[NNN]);
0209 }
0210
0211 return rechits_clusters;
0212 }
0213
0214 ME0SegmentAlgorithm::ProtoSegments ME0SegmentAlgorithm::chainHits(const ME0Chamber* chamber,
0215 const HitAndPositionContainer& rechits) {
0216 ProtoSegments rechits_chains;
0217 ProtoSegments seeds;
0218 seeds.reserve(rechits.size());
0219 std::vector<bool> usedCluster(rechits.size(), false);
0220
0221
0222
0223
0224 for (unsigned int i = 0; i < rechits.size(); ++i) {
0225 if (std::abs(rechits[i].rh->tof()) > dTimeChainBoxMax)
0226 continue;
0227 seeds.push_back(HitAndPositionPtrContainer(1, &rechits[i]));
0228 }
0229
0230
0231 for (size_t NNN = 0; NNN < seeds.size(); ++NNN) {
0232 for (size_t MMM = NNN + 1; MMM < seeds.size(); ++MMM) {
0233 if (usedCluster[MMM] || usedCluster[NNN]) {
0234 continue;
0235 }
0236
0237
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247 bool goodToMerge = isGoodToMerge(chamber, seeds[NNN], seeds[MMM]);
0248 if (goodToMerge) {
0249
0250
0251
0252
0253 seeds[MMM].insert(seeds[MMM].end(), seeds[NNN].begin(), seeds[NNN].end());
0254
0255
0256 usedCluster[NNN] = true;
0257
0258
0259 break;
0260 }
0261 }
0262 }
0263
0264
0265
0266
0267
0268 for (size_t NNN = 0; NNN < seeds.size(); ++NNN) {
0269 if (usedCluster[NNN])
0270 continue;
0271 rechits_chains.push_back(seeds[NNN]);
0272 }
0273
0274
0275
0276 return rechits_chains;
0277 }
0278
0279 bool ME0SegmentAlgorithm::isGoodToMerge(const ME0Chamber* chamber,
0280 const HitAndPositionPtrContainer& newChain,
0281 const HitAndPositionPtrContainer& oldChain) {
0282 for (size_t iRH_new = 0; iRH_new < newChain.size(); ++iRH_new) {
0283 GlobalPoint pos_new = newChain[iRH_new]->gp;
0284
0285 for (size_t iRH_old = 0; iRH_old < oldChain.size(); ++iRH_old) {
0286 GlobalPoint pos_old = oldChain[iRH_old]->gp;
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296 if (std::abs(reco::deltaPhi(float(pos_new.phi()), float(pos_old.phi()))) >= dPhiChainBoxMax)
0297 continue;
0298 if (std::abs(pos_new.eta() - pos_old.eta()) >= dEtaChainBoxMax)
0299 continue;
0300
0301 if (std::abs(int(newChain[iRH_new]->layer) - int(oldChain[iRH_old]->layer)) >= (chamber->id().nlayers() - 1))
0302 continue;
0303
0304
0305 if (std::abs(newChain[iRH_new]->rh->tof() - oldChain[iRH_old]->rh->tof()) >= dTimeChainBoxMax)
0306 continue;
0307
0308 return true;
0309 }
0310 }
0311 return false;
0312 }
0313
0314 void ME0SegmentAlgorithm::buildSegments(const ME0Chamber* chamber,
0315 const HitAndPositionPtrContainer& rechits,
0316 std::vector<ME0Segment>& me0segs) {
0317 if (rechits.size() < minHitsPerSegment)
0318 return;
0319
0320 #ifdef EDM_ML_DEBUG
0321 edm::LogVerbatim("ME0SegmentAlgorithm")
0322 << "[ME0SegmentAlgorithm::buildSegments] will now try to fit a ME0Segment from collection of " << rechits.size()
0323 << " ME0 RecHits";
0324 for (auto rh = rechits.begin(); rh != rechits.end(); ++rh) {
0325 auto me0id = (*rh)->rh->me0Id();
0326 auto rhLP = (*rh)->lp;
0327 edm::LogVerbatim("ME0SegmentAlgorithm")
0328 << "[RecHit :: Loc x = " << std::showpos << std::setw(9) << rhLP.x() << " Loc y = " << std::showpos
0329 << std::setw(9) << rhLP.y() << " Time = " << std::showpos << (*rh)->rh->tof() << " -- " << me0id.rawId()
0330 << " = " << me0id << " ]";
0331 }
0332 #endif
0333
0334 MuonSegFit::MuonRecHitContainer muonRecHits;
0335 std::vector<const ME0RecHit*> bareRHs;
0336
0337
0338 for (auto rh = rechits.begin(); rh != rechits.end(); rh++) {
0339 bareRHs.push_back((*rh)->rh);
0340
0341 ME0RecHit* newRH = (*rh)->rh->clone();
0342 newRH->setPosition((*rh)->lp);
0343
0344 MuonSegFit::MuonRecHitPtr trkRecHit(newRH);
0345 muonRecHits.push_back(trkRecHit);
0346 }
0347
0348
0349 sfit_ = std::make_unique<MuonSegFit>(muonRecHits);
0350 bool goodfit = sfit_->fit();
0351 edm::LogVerbatim("ME0SegmentAlgorithm") << "[ME0SegmentAlgorithm::buildSegments] ME0Segment fit done";
0352
0353
0354 if (!goodfit) {
0355 for (auto rh : muonRecHits)
0356 rh.reset();
0357 return;
0358 }
0359
0360
0361 LocalPoint protoIntercept = sfit_->intercept();
0362 LocalVector protoDirection = sfit_->localdir();
0363 AlgebraicSymMatrix protoErrors = sfit_->covarianceMatrix();
0364 double protoChi2 = sfit_->chi2();
0365
0366 float averageTime = 0.;
0367 for (auto rh = rechits.begin(); rh != rechits.end(); ++rh) {
0368 averageTime += (*rh)->rh->tof();
0369 }
0370 if (!rechits.empty())
0371 averageTime = averageTime / (rechits.size());
0372 float timeUncrt = 0.;
0373 for (auto rh = rechits.begin(); rh != rechits.end(); ++rh) {
0374 timeUncrt += pow((*rh)->rh->tof() - averageTime, 2);
0375 }
0376
0377 if (rechits.size() > 1)
0378 timeUncrt = timeUncrt / (rechits.size() - 1);
0379 timeUncrt = sqrt(timeUncrt);
0380
0381 const float dPhi = chamber->computeDeltaPhi(protoIntercept, protoDirection);
0382
0383
0384 edm::LogVerbatim("ME0SegmentAlgorithm")
0385 << "[ME0SegmentAlgorithm::buildSegments] will now try to make ME0Segment from collection of " << rechits.size()
0386 << " ME0 RecHits";
0387 ME0Segment tmp(bareRHs, protoIntercept, protoDirection, protoErrors, protoChi2, averageTime, timeUncrt, dPhi);
0388
0389 edm::LogVerbatim("ME0SegmentAlgorithm") << "[ME0SegmentAlgorithm::buildSegments] ME0Segment made";
0390 edm::LogVerbatim("ME0SegmentAlgorithm") << "[ME0SegmentAlgorithm::buildSegments] " << tmp;
0391
0392 for (auto rh : muonRecHits)
0393 rh.reset();
0394 me0segs.push_back(tmp);
0395 return;
0396 }