File indexing completed on 2024-04-06 12:26:08
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "RecoLocalMuon/DTSegment/src/DTMeantimerPatternReco.h"
0010
0011
0012 #include "FWCore/Framework/interface/ESHandle.h"
0013 #include "FWCore/Framework/interface/EventSetup.h"
0014 #include "FWCore/Framework/interface/ConsumesCollector.h"
0015 #include "DataFormats/Common/interface/OwnVector.h"
0016 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
0017 #include "Geometry/Records/interface/MuonGeometryRecord.h"
0018 #include "Geometry/DTGeometry/interface/DTGeometry.h"
0019 #include "Geometry/DTGeometry/interface/DTLayer.h"
0020 #include "Geometry/DTGeometry/interface/DTSuperLayer.h"
0021 #include "DataFormats/DTRecHit/interface/DTSLRecSegment2D.h"
0022 #include "RecoLocalMuon/DTSegment/src/DTSegmentUpdator.h"
0023 #include "RecoLocalMuon/DTSegment/src/DTSegmentCleaner.h"
0024 #include "RecoLocalMuon/DTSegment/src/DTHitPairForFit.h"
0025 #include "RecoLocalMuon/DTSegment/src/DTSegmentCand.h"
0026 #include "RecoLocalMuon/DTSegment/src/DTLinearFit.h"
0027
0028
0029 #include <iterator>
0030 using namespace std;
0031 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0032
0033
0034
0035 typedef std::vector<std::shared_ptr<DTHitPairForFit>> hitCont;
0036 typedef hitCont::const_iterator hitIter;
0037
0038
0039 DTMeantimerPatternReco::DTMeantimerPatternReco(const edm::ParameterSet& pset, edm::ConsumesCollector cc)
0040 : DTRecSegment2DBaseAlgo(pset),
0041 theFitter(new DTLinearFit()),
0042 theAlgoName("DTMeantimerPatternReco"),
0043 theDTGeometryToken(cc.esConsumes()) {
0044 theMaxAllowedHits = pset.getParameter<unsigned int>("MaxAllowedHits");
0045 theAlphaMaxTheta = pset.getParameter<double>("AlphaMaxTheta");
0046 theAlphaMaxPhi = pset.getParameter<double>("AlphaMaxPhi");
0047 theMaxChi2 = pset.getParameter<double>("MaxChi2");
0048 debug = pset.getUntrackedParameter<bool>("debug");
0049 theUpdator = new DTSegmentUpdator(pset, cc);
0050 theCleaner = new DTSegmentCleaner(pset);
0051 }
0052
0053
0054 DTMeantimerPatternReco::~DTMeantimerPatternReco() {
0055 delete theUpdator;
0056 delete theCleaner;
0057 delete theFitter;
0058 }
0059
0060
0061 edm::OwnVector<DTSLRecSegment2D> DTMeantimerPatternReco::reconstruct(const DTSuperLayer* sl,
0062 const std::vector<DTRecHit1DPair>& pairs) {
0063 edm::OwnVector<DTSLRecSegment2D> result;
0064 std::vector<std::shared_ptr<DTHitPairForFit>> hitsForFit = initHits(sl, pairs);
0065
0066 vector<DTSegmentCand*> candidates = buildSegments(sl, hitsForFit);
0067
0068 vector<DTSegmentCand*>::const_iterator cand = candidates.begin();
0069 while (cand < candidates.end()) {
0070 DTSLRecSegment2D* segment = (**cand);
0071 theUpdator->update(segment, true);
0072
0073 if (debug)
0074 cout << "Reconstructed 2D segments " << *segment << endl;
0075 result.push_back(segment);
0076
0077 delete *(cand++);
0078 }
0079
0080 return result;
0081 }
0082
0083 void DTMeantimerPatternReco::setES(const edm::EventSetup& setup) {
0084
0085 theDTGeometry = setup.getHandle(theDTGeometryToken);
0086 theUpdator->setES(setup);
0087 }
0088
0089 vector<std::shared_ptr<DTHitPairForFit>> DTMeantimerPatternReco::initHits(const DTSuperLayer* sl,
0090 const std::vector<DTRecHit1DPair>& hits) {
0091 hitCont result;
0092 for (vector<DTRecHit1DPair>::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0093 result.push_back(std::make_shared<DTHitPairForFit>(*hit, *sl, theDTGeometry));
0094 }
0095 return result;
0096 }
0097
0098 vector<DTSegmentCand*> DTMeantimerPatternReco::buildSegments(
0099 const DTSuperLayer* sl, const std::vector<std::shared_ptr<DTHitPairForFit>>& hits) {
0100 vector<DTSegmentCand*> result;
0101 DTEnums::DTCellSide codes[2] = {DTEnums::Left, DTEnums::Right};
0102
0103 if (debug) {
0104 cout << "buildSegments: " << sl->id() << " nHits " << hits.size() << endl;
0105 for (hitIter hit = hits.begin(); hit != hits.end(); ++hit)
0106 cout << **hit << " wire: " << (*hit)->id() << " DigiTime: " << (*hit)->digiTime() << endl;
0107 }
0108
0109 if (hits.size() > theMaxAllowedHits) {
0110 if (debug) {
0111 cout << "Warning: this SuperLayer " << sl->id() << " has too many hits : " << hits.size() << " max allowed is "
0112 << theMaxAllowedHits << endl;
0113 cout << "Skipping segment reconstruction... " << endl;
0114 }
0115 return result;
0116 }
0117
0118 GlobalPoint IP;
0119 float DAlphaMax;
0120 if ((sl->id()).superlayer() == 2)
0121 DAlphaMax = theAlphaMaxTheta;
0122 else
0123 DAlphaMax = theAlphaMaxPhi;
0124
0125
0126
0127 for (hitCont::const_iterator firstHit = hits.begin(); firstHit != hits.end(); ++firstHit) {
0128 for (hitCont::const_reverse_iterator lastHit = hits.rbegin(); (*lastHit) != (*firstHit); ++lastHit) {
0129
0130 if (!geometryFilter((*firstHit)->id(), (*lastHit)->id()))
0131 continue;
0132
0133
0134 hitCont hitsForFit;
0135 for (hitCont::const_iterator tmpHit = firstHit + 1; (*tmpHit) != (*lastHit); tmpHit++)
0136 if ((geometryFilter((*tmpHit)->id(), (*lastHit)->id())) && (geometryFilter((*tmpHit)->id(), (*firstHit)->id())))
0137 hitsForFit.push_back(*tmpHit);
0138
0139 for (int firstLR = 0; firstLR < 2; ++firstLR) {
0140 for (int lastLR = 0; lastLR < 2; ++lastLR) {
0141
0142
0143 GlobalPoint gposFirst = sl->toGlobal((*firstHit)->localPosition(codes[firstLR]));
0144 GlobalPoint gposLast = sl->toGlobal((*lastHit)->localPosition(codes[lastLR]));
0145 GlobalVector gvec = gposLast - gposFirst;
0146 GlobalVector gvecIP = gposLast - IP;
0147
0148
0149 float DAlpha = fabs(gvec.theta() - gvecIP.theta());
0150 if (DAlpha > DAlphaMax)
0151 continue;
0152
0153
0154
0155
0156
0157
0158
0159 DTSegmentCand::AssPointCont pointSet;
0160 auto segCand = std::make_unique<DTSegmentCand>(pointSet, sl);
0161 segCand->add(*firstHit, codes[firstLR]);
0162 segCand->add(*lastHit, codes[lastLR]);
0163
0164
0165 maxfound = 3;
0166 addHits(segCand.get(), hitsForFit, result);
0167 }
0168 }
0169 }
0170 }
0171
0172
0173 if (debug) {
0174 cout << "Result (before cleaning): " << result.size() << endl;
0175 for (vector<DTSegmentCand*>::const_iterator seg = result.begin(); seg != result.end(); ++seg)
0176 cout << *(*seg) << endl;
0177 }
0178
0179 result = theCleaner->clean(result);
0180
0181 if (debug) {
0182 cout << "Result (after cleaning): " << result.size() << endl;
0183 for (vector<DTSegmentCand*>::const_iterator seg = result.begin(); seg != result.end(); ++seg)
0184 cout << *(*seg) << endl;
0185 }
0186
0187 return result;
0188 }
0189
0190 void DTMeantimerPatternReco::addHits(DTSegmentCand* segCand,
0191 const vector<std::shared_ptr<DTHitPairForFit>>& hits,
0192 vector<DTSegmentCand*>& result) {
0193 double chi2l, chi2r, t0l, t0r;
0194 bool foundSomething = false;
0195
0196 if (debug)
0197 cout << " DTMeantimerPatternReco::addHit " << endl
0198 << " Picked " << segCand->nHits() << " hits, " << hits.size() << " left." << endl;
0199
0200 if (segCand->nHits() + hits.size() < maxfound)
0201 return;
0202
0203
0204 for (hitCont::const_iterator hit = hits.begin(); hit != hits.end(); ++hit) {
0205
0206
0207
0208
0209
0210 DTSegmentCand::AssPoint lhit(*hit, DTEnums::Left);
0211 DTSegmentCand::AssPoint rhit(*hit, DTEnums::Right);
0212
0213 segCand->add(lhit);
0214 bool left_ok = (fitWithT0(segCand, false) ? true : false);
0215 chi2l = segCand->chi2();
0216 t0l = segCand->t0();
0217 segCand->removeHit(lhit);
0218
0219 segCand->add(rhit);
0220 bool right_ok = (fitWithT0(segCand, false) ? true : false);
0221 chi2r = segCand->chi2();
0222 t0r = segCand->t0();
0223 segCand->removeHit(rhit);
0224
0225 if (debug) {
0226 int nHits = segCand->nHits() + 1;
0227 cout << " Left: t0= " << t0l << " chi2/nHits= " << chi2l << "/" << nHits << " ok: " << left_ok << endl;
0228 cout << " Right: t0= " << t0r << " chi2/nHits= " << chi2r << "/" << nHits << " ok: " << right_ok << endl;
0229 }
0230
0231 if (!left_ok && !right_ok)
0232 continue;
0233
0234 foundSomething = true;
0235
0236
0237 hitCont hitsForFit;
0238 for (hitCont::const_iterator tmpHit = hit + 1; tmpHit != hits.end(); tmpHit++)
0239 if (geometryFilter((*tmpHit)->id(), (*hit)->id()))
0240 hitsForFit.push_back(*tmpHit);
0241
0242 reverse(hitsForFit.begin(), hitsForFit.end());
0243
0244
0245 if (segCand->nHits() > 3 && left_ok && right_ok) {
0246 if (chi2l < chi2r - 0.1)
0247 right_ok = false;
0248 else if (chi2r < chi2l - 0.1)
0249 left_ok = false;
0250 }
0251
0252 if (left_ok) {
0253 segCand->add(lhit);
0254 addHits(segCand, hitsForFit, result);
0255 segCand->removeHit(lhit);
0256 }
0257
0258 if (right_ok) {
0259 segCand->add(rhit);
0260 addHits(segCand, hitsForFit, result);
0261 segCand->removeHit(rhit);
0262 }
0263 }
0264
0265 if (foundSomething)
0266 return;
0267
0268
0269
0270 if (segCand->nHits() < maxfound)
0271 return;
0272
0273
0274 bool seg_ok = (fitWithT0(segCand, debug) ? true : false);
0275 if (!seg_ok)
0276 return;
0277
0278 if (!segCand->good()) {
0279
0280 return;
0281 }
0282
0283 if (segCand->nHits() > maxfound)
0284 maxfound = segCand->nHits();
0285 if (debug)
0286 cout << endl << " Seg t0= " << segCand->t0() << endl << *segCand << endl;
0287
0288 if (checkDoubleCandidates(result, segCand)) {
0289 result.push_back(new DTSegmentCand(*segCand));
0290 if (debug)
0291 cout << " Result is now " << result.size() << endl;
0292 } else {
0293 if (debug)
0294 cout << " Exists - skipping" << endl;
0295 }
0296 }
0297
0298 bool DTMeantimerPatternReco::geometryFilter(const DTWireId first, const DTWireId second) const {
0299
0300
0301 const int layerLowerCut[4] = {0, -1, -2, -2};
0302 const int layerUpperCut[4] = {0, 2, 2, 3};
0303
0304
0305
0306
0307 if (first.layerId().superlayerId().superLayer() != second.layerId().superlayerId().superLayer())
0308 return true;
0309
0310 int deltaLayer = abs(first.layerId().layer() - second.layerId().layer());
0311
0312
0313 if (!deltaLayer)
0314 return false;
0315
0316
0317 if (deltaLayer > 3) {
0318 cout << "*** WARNING! DT Layer numbers differ by more than 3! for hits: " << endl;
0319 cout << " " << first << endl;
0320 cout << " " << second << endl;
0321 return false;
0322 }
0323
0324
0325 int deltaWire = first.wire() - second.wire();
0326 if (second.layerId().layer() % 2 == 0)
0327 deltaWire = -deltaWire;
0328 if ((deltaWire <= layerLowerCut[deltaLayer]) || (deltaWire >= layerUpperCut[deltaLayer]))
0329 return false;
0330
0331 return true;
0332 }
0333
0334 DTSegmentCand* DTMeantimerPatternReco::fitWithT0(DTSegmentCand* seg, const bool fitdebug) {
0335
0336 theUpdator->fit(seg, true, fitdebug);
0337 double chi2 = seg->chi2();
0338
0339
0340
0341
0342 if (chi2 == -1.)
0343 return nullptr;
0344
0345
0346 if (seg->nHits() == 3)
0347 return seg;
0348
0349
0350 if (seg->t0() == 0) {
0351 if (chi2 < 100.)
0352 return seg;
0353 else
0354 return nullptr;
0355 }
0356
0357
0358 if ((chi2 / (seg->nHits() - 3) < theMaxChi2))
0359 return seg;
0360 else
0361 return nullptr;
0362 }
0363
0364 bool DTMeantimerPatternReco::checkDoubleCandidates(vector<DTSegmentCand*>& cands, DTSegmentCand* seg) {
0365 for (vector<DTSegmentCand*>::iterator cand = cands.begin(); cand != cands.end(); ++cand) {
0366 if (*(*cand) == *seg)
0367 return false;
0368 if (((*cand)->nHits() >= seg->nHits()) && ((*cand)->chi2ndof() < seg->chi2ndof()))
0369 if ((*cand)->nSharedHitPairs(*seg) > int(seg->nHits() - 2))
0370 return false;
0371 }
0372 return true;
0373 }
0374
0375 void DTMeantimerPatternReco::printPattern(vector<DTSegmentCand::AssPoint>& assHits, const DTHitPairForFit* hit) {
0376 char mark[26] = {". . . . . . . . . . . . "};
0377 int wire[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
0378
0379 for (vector<DTSegmentCand::AssPoint>::const_iterator assHit = assHits.begin(); assHit != assHits.end(); ++assHit) {
0380 int lay =
0381 (((*assHit).first)->id().superlayerId().superLayer() - 1) * 4 + ((*assHit).first)->id().layerId().layer() - 1;
0382 wire[lay] = ((*assHit).first)->id().wire();
0383 if ((*assHit).second == DTEnums::Left)
0384 mark[lay * 2] = 'L';
0385 else
0386 mark[lay * 2] = 'R';
0387 }
0388
0389 int lay = ((*hit).id().superlayerId().superLayer() - 1) * 4 + (*hit).id().layerId().layer() - 1;
0390 wire[lay] = (*hit).id().wire();
0391 mark[lay * 2] = '*';
0392
0393 cout << " " << mark << endl << " ";
0394 for (int i = 0; i < 12; i++)
0395 if (wire[i])
0396 cout << setw(2) << wire[i];
0397 else
0398 cout << " ";
0399 cout << endl;
0400 }