File indexing completed on 2024-04-06 12:27:07
0001 #include "RecoMuon/MuonSeedGenerator/src/MuonCSCSeedFromRecHits.h"
0002 #include "RecoMuon/MuonSeedGenerator/src/MuonSeedPtExtractor.h"
0003 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0004 #include "DataFormats/MuonDetId/interface/ME0DetId.h"
0005 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
0006 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
0007 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
0008 #include "DataFormats/Math/interface/deltaPhi.h"
0009 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0011 #include "Geometry/CSCGeometry/interface/CSCChamberSpecs.h"
0012 #include "Geometry/CSCGeometry/interface/CSCChamber.h"
0013 #include <iomanip>
0014
0015 MuonCSCSeedFromRecHits::MuonCSCSeedFromRecHits() : MuonSeedFromRecHits() {}
0016
0017 TrajectorySeed MuonCSCSeedFromRecHits::seed() const {
0018 TrajectorySeed result;
0019 if (theRhits.size() == 1) {
0020
0021 makeDefaultSeed(result);
0022 return result;
0023 }
0024
0025
0026 MuonRecHitContainer station1Hits, station2Hits, station3Hits, station4Hits;
0027 for (MuonRecHitContainer::const_iterator iter = theRhits.begin(), end = theRhits.end(); iter != end; ++iter) {
0028 int station = CSCDetId((*iter)->geographicalId().rawId()).station();
0029 if ((*iter)->isME0()) {
0030 station = 1;
0031 }
0032
0033 if (station == 1) {
0034 station1Hits.push_back(*iter);
0035 } else if (station == 2) {
0036 station2Hits.push_back(*iter);
0037 } else if (station == 3) {
0038 station3Hits.push_back(*iter);
0039 } else if (station == 4) {
0040 station4Hits.push_back(*iter);
0041 }
0042 }
0043
0044
0045
0046
0047
0048
0049 MuonRecHitContainer* betterSecondHits = &station2Hits;
0050 MuonRecHitContainer* notAsGoodSecondHits = &station3Hits;
0051 if (!station2Hits.empty() && !station3Hits.empty()) {
0052
0053 if (segmentQuality(station3Hits[0]) < segmentQuality(station2Hits[0])) {
0054 betterSecondHits = &station3Hits;
0055 notAsGoodSecondHits = &station2Hits;
0056 }
0057 }
0058
0059
0060 if (makeSeed(station1Hits, *betterSecondHits, result)) {
0061 return result;
0062 }
0063 if (makeSeed(station1Hits, *notAsGoodSecondHits, result)) {
0064 return result;
0065 }
0066 if (makeSeed(station2Hits, station3Hits, result)) {
0067 return result;
0068 }
0069 if (makeSeed(station1Hits, station4Hits, result)) {
0070 return result;
0071 }
0072
0073
0074 makeDefaultSeed(result);
0075 return result;
0076 }
0077
0078 bool MuonCSCSeedFromRecHits::makeSeed(const MuonRecHitContainer& hits1,
0079 const MuonRecHitContainer& hits2,
0080 TrajectorySeed& seed) const {
0081 for (MuonRecHitContainer::const_iterator itr1 = hits1.begin(), end1 = hits1.end(); itr1 != end1; ++itr1) {
0082 CSCDetId cscId1((*itr1)->geographicalId().rawId());
0083
0084
0085 for (MuonRecHitContainer::const_iterator itr2 = hits2.begin(), end2 = hits2.end(); itr2 != end2; ++itr2) {
0086 CSCDetId cscId2((*itr2)->geographicalId().rawId());
0087
0088
0089
0090 std::vector<double> pts = thePtExtractor->pT_extract(*itr1, *itr2);
0091
0092 double pt = pts[0];
0093 double sigmapt = pts[1];
0094 double minpt = 3.;
0095
0096
0097 if (fabs(pt) > minpt) {
0098 double maxpt = 2000.;
0099 if (pt > maxpt) {
0100 pt = maxpt;
0101 sigmapt = maxpt;
0102 }
0103 if (pt < -maxpt) {
0104 pt = -maxpt;
0105 sigmapt = maxpt;
0106 }
0107
0108
0109 ConstMuonRecHitPointer bestSeg = bestEndcapHit(theRhits);
0110 seed = createSeed(pt, sigmapt, bestSeg);
0111
0112
0113 return true;
0114 }
0115 }
0116 }
0117
0118
0119
0120 return false;
0121 }
0122
0123
0124 int MuonCSCSeedFromRecHits::segmentQuality(ConstMuonRecHitPointer segment) const {
0125 int Nchi2 = 0;
0126 int quality = 0;
0127 int nhits = segment->recHits().size();
0128 if (segment->chi2() / (nhits * 2. - 4.) > 3.)
0129 Nchi2 = 1;
0130 if (segment->chi2() / (nhits * 2. - 4.) > 9.)
0131 Nchi2 = 2;
0132
0133 if (nhits > 4)
0134 quality = 1 + Nchi2;
0135 if (nhits == 4)
0136 quality = 3 + Nchi2;
0137 if (nhits == 3)
0138 quality = 5 + Nchi2;
0139
0140 float dPhiGloDir = fabs(deltaPhi(segment->globalPosition().barePhi(), segment->globalDirection().barePhi()));
0141
0142 if (dPhiGloDir > .2)
0143 ++quality;
0144
0145 if (segment->isCSC() and CSCDetId(segment->geographicalId()).ring() == 4) {
0146 const auto chamber = dynamic_cast<const CSCChamber*>(segment->det());
0147 if (chamber->specs()->gangedStrips())
0148 ++quality;
0149 }
0150
0151 return quality;
0152 }
0153
0154 MuonCSCSeedFromRecHits::ConstMuonRecHitPointer MuonCSCSeedFromRecHits::bestEndcapHit(
0155 const MuonRecHitContainer& endcapHits) const {
0156 MuonRecHitPointer me1 = nullptr, meit = nullptr;
0157 float dPhiGloDir = .0;
0158 float bestdPhiGloDir = M_PI;
0159 int quality1 = 0, quality = 0;
0160
0161 for (MuonRecHitContainer::const_iterator iter = endcapHits.begin(); iter != endcapHits.end(); iter++) {
0162 if (!(*iter)->isCSC() && !(*iter)->isME0())
0163 continue;
0164
0165
0166
0167 meit = *iter;
0168
0169 quality = segmentQuality(meit);
0170
0171 dPhiGloDir = fabs(deltaPhi(meit->globalPosition().barePhi(), meit->globalDirection().barePhi()));
0172
0173 if (!me1) {
0174 me1 = meit;
0175 quality1 = quality;
0176 bestdPhiGloDir = dPhiGloDir;
0177 }
0178
0179 if (me1) {
0180 if (!me1->isValid()) {
0181 me1 = meit;
0182 quality1 = quality;
0183 bestdPhiGloDir = dPhiGloDir;
0184 }
0185
0186 if (me1->isValid() && quality < quality1) {
0187 me1 = meit;
0188 quality1 = quality;
0189 bestdPhiGloDir = dPhiGloDir;
0190 }
0191
0192 if (me1->isValid() && bestdPhiGloDir > .03) {
0193 if (dPhiGloDir < bestdPhiGloDir - .01 && quality == quality1) {
0194 me1 = meit;
0195 quality1 = quality;
0196 bestdPhiGloDir = dPhiGloDir;
0197 }
0198 }
0199 }
0200
0201 }
0202
0203 return me1;
0204 }
0205
0206 void MuonCSCSeedFromRecHits::makeDefaultSeed(TrajectorySeed& seed) const {
0207
0208 ConstMuonRecHitPointer me1 = bestEndcapHit(theRhits);
0209
0210
0211 if (me1 && me1->isValid()) {
0212
0213 createDefaultEndcapSeed(me1, seed);
0214 }
0215 }
0216
0217 bool MuonCSCSeedFromRecHits::createDefaultEndcapSeed(ConstMuonRecHitPointer last, TrajectorySeed& seed) const {
0218
0219 std::vector<double> momentum = thePtExtractor->pT_extract(last, last);
0220 seed = createSeed(momentum[0], momentum[1], last);
0221 return true;
0222 }
0223
0224 void MuonCSCSeedFromRecHits::analyze() const {
0225 for (MuonRecHitContainer::const_iterator iter = theRhits.begin(); iter != theRhits.end(); iter++) {
0226 if (!(*iter)->isCSC())
0227 continue;
0228 for (MuonRecHitContainer::const_iterator iter2 = iter + 1; iter2 != theRhits.end(); ++iter2) {
0229 if (!(*iter2)->isCSC())
0230 continue;
0231
0232 CSCDetId cscId1((*iter)->geographicalId().rawId());
0233 CSCDetId cscId2((*iter2)->geographicalId().rawId());
0234 double dphi = deltaPhi((**iter).globalPosition().barePhi(), (**iter2).globalPosition().barePhi());
0235
0236 int type1 = cscId1.iChamberType();
0237 int type2 = cscId2.iChamberType();
0238
0239
0240 if (type1 < type2) {
0241 std::cout << "HITPAIRA," << type1 << type2 << "," << dphi << "," << (**iter).globalPosition().eta()
0242 << std::endl;
0243 }
0244 if (type2 < type1) {
0245 std::cout << "HITPAIRB," << type2 << type1 << "," << -dphi << "," << (**iter2).globalPosition().eta()
0246 << std::endl;
0247 }
0248 if (type1 == type2) {
0249 std::cout << "HITPAIRSAMESTATION," << type1 << cscId1.ring() << cscId2.ring() << "," << dphi << ","
0250 << (**iter).globalPosition().eta() << std::endl;
0251 }
0252 }
0253 }
0254 }