File indexing completed on 2024-04-06 12:27:08
0001
0002
0003
0004
0005
0006
0007
0008 #include "RecoMuon/MuonSeedGenerator/src/MuonSeedCreator.h"
0009
0010 #include "RecoMuon/TransientTrackingRecHit/interface/MuonTransientTrackingRecHit.h"
0011
0012 #include "RecoMuon/TrackingTools/interface/MuonPatternRecoDumper.h"
0013
0014 #include "MagneticField/Engine/interface/MagneticField.h"
0015 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
0016
0017 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
0018 #include "TrackingTools/DetLayers/interface/DetLayer.h"
0019
0020 #include "DataFormats/TrajectoryState/interface/PTrajectoryStateOnDet.h"
0021 #include "DataFormats/Common/interface/OwnVector.h"
0022 #include "DataFormats/MuonDetId/interface/DTChamberId.h"
0023 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
0024 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
0025
0026 #include "FWCore/Framework/interface/EventSetup.h"
0027 #include "FWCore/Framework/interface/ESHandle.h"
0028 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0029
0030 #include "gsl/gsl_statistics.h"
0031
0032
0033
0034
0035 MuonSeedCreator::MuonSeedCreator(const edm::ParameterSet& pset) {
0036 theMinMomentum = pset.getParameter<double>("minimumSeedPt");
0037 theMaxMomentum = pset.getParameter<double>("maximumSeedPt");
0038 defaultMomentum = pset.getParameter<double>("defaultSeedPt");
0039 debug = pset.getParameter<bool>("DebugMuonSeed");
0040 sysError = pset.getParameter<double>("SeedPtSystematics");
0041
0042 DT12 = pset.getParameter<std::vector<double> >("DT_12");
0043 DT13 = pset.getParameter<std::vector<double> >("DT_13");
0044 DT14 = pset.getParameter<std::vector<double> >("DT_14");
0045 DT23 = pset.getParameter<std::vector<double> >("DT_23");
0046 DT24 = pset.getParameter<std::vector<double> >("DT_24");
0047 DT34 = pset.getParameter<std::vector<double> >("DT_34");
0048
0049 CSC01 = pset.getParameter<std::vector<double> >("CSC_01");
0050 CSC12 = pset.getParameter<std::vector<double> >("CSC_12");
0051 CSC02 = pset.getParameter<std::vector<double> >("CSC_02");
0052 CSC13 = pset.getParameter<std::vector<double> >("CSC_13");
0053 CSC03 = pset.getParameter<std::vector<double> >("CSC_03");
0054 CSC14 = pset.getParameter<std::vector<double> >("CSC_14");
0055 CSC23 = pset.getParameter<std::vector<double> >("CSC_23");
0056 CSC24 = pset.getParameter<std::vector<double> >("CSC_24");
0057 CSC34 = pset.getParameter<std::vector<double> >("CSC_34");
0058
0059 OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
0060 OL1222 = pset.getParameter<std::vector<double> >("OL_1222");
0061 OL1232 = pset.getParameter<std::vector<double> >("OL_1232");
0062 OL1213 = pset.getParameter<std::vector<double> >("OL_1213");
0063 OL2222 = pset.getParameter<std::vector<double> >("OL_1222");
0064
0065 SME11 = pset.getParameter<std::vector<double> >("SME_11");
0066 SME12 = pset.getParameter<std::vector<double> >("SME_12");
0067 SME13 = pset.getParameter<std::vector<double> >("SME_13");
0068 SME21 = pset.getParameter<std::vector<double> >("SME_21");
0069 SME22 = pset.getParameter<std::vector<double> >("SME_22");
0070 SME31 = pset.getParameter<std::vector<double> >("SME_31");
0071 SME32 = pset.getParameter<std::vector<double> >("SME_32");
0072 SME41 = pset.getParameter<std::vector<double> >("SME_41");
0073
0074 SMB10 = pset.getParameter<std::vector<double> >("SMB_10");
0075 SMB11 = pset.getParameter<std::vector<double> >("SMB_11");
0076 SMB12 = pset.getParameter<std::vector<double> >("SMB_12");
0077 SMB20 = pset.getParameter<std::vector<double> >("SMB_20");
0078 SMB21 = pset.getParameter<std::vector<double> >("SMB_21");
0079 SMB22 = pset.getParameter<std::vector<double> >("SMB_22");
0080 SMB30 = pset.getParameter<std::vector<double> >("SMB_30");
0081 SMB31 = pset.getParameter<std::vector<double> >("SMB_31");
0082 SMB32 = pset.getParameter<std::vector<double> >("SMB_32");
0083
0084
0085 CSC01_1 = pset.getParameter<std::vector<double> >("CSC_01_1_scale");
0086 CSC12_1 = pset.getParameter<std::vector<double> >("CSC_12_1_scale");
0087 CSC12_2 = pset.getParameter<std::vector<double> >("CSC_12_2_scale");
0088 CSC12_3 = pset.getParameter<std::vector<double> >("CSC_12_3_scale");
0089 CSC13_2 = pset.getParameter<std::vector<double> >("CSC_13_2_scale");
0090 CSC13_3 = pset.getParameter<std::vector<double> >("CSC_13_3_scale");
0091 CSC14_3 = pset.getParameter<std::vector<double> >("CSC_14_3_scale");
0092 CSC23_1 = pset.getParameter<std::vector<double> >("CSC_23_1_scale");
0093 CSC23_2 = pset.getParameter<std::vector<double> >("CSC_23_2_scale");
0094 CSC24_1 = pset.getParameter<std::vector<double> >("CSC_24_1_scale");
0095 CSC34_1 = pset.getParameter<std::vector<double> >("CSC_34_1_scale");
0096
0097 DT12_1 = pset.getParameter<std::vector<double> >("DT_12_1_scale");
0098 DT12_2 = pset.getParameter<std::vector<double> >("DT_12_2_scale");
0099 DT13_1 = pset.getParameter<std::vector<double> >("DT_13_1_scale");
0100 DT13_2 = pset.getParameter<std::vector<double> >("DT_13_2_scale");
0101 DT14_1 = pset.getParameter<std::vector<double> >("DT_14_1_scale");
0102 DT14_2 = pset.getParameter<std::vector<double> >("DT_14_2_scale");
0103 DT23_1 = pset.getParameter<std::vector<double> >("DT_23_1_scale");
0104 DT23_2 = pset.getParameter<std::vector<double> >("DT_23_2_scale");
0105 DT24_1 = pset.getParameter<std::vector<double> >("DT_24_1_scale");
0106 DT24_2 = pset.getParameter<std::vector<double> >("DT_24_2_scale");
0107 DT34_1 = pset.getParameter<std::vector<double> >("DT_34_1_scale");
0108 DT34_2 = pset.getParameter<std::vector<double> >("DT_34_2_scale");
0109
0110 OL_1213 = pset.getParameter<std::vector<double> >("OL_1213_0_scale");
0111 OL_1222 = pset.getParameter<std::vector<double> >("OL_1222_0_scale");
0112 OL_1232 = pset.getParameter<std::vector<double> >("OL_1232_0_scale");
0113 OL_2213 = pset.getParameter<std::vector<double> >("OL_2213_0_scale");
0114 OL_2222 = pset.getParameter<std::vector<double> >("OL_2222_0_scale");
0115
0116 SMB_10S = pset.getParameter<std::vector<double> >("SMB_10_0_scale");
0117 SMB_11S = pset.getParameter<std::vector<double> >("SMB_11_0_scale");
0118 SMB_12S = pset.getParameter<std::vector<double> >("SMB_12_0_scale");
0119 SMB_20S = pset.getParameter<std::vector<double> >("SMB_20_0_scale");
0120 SMB_21S = pset.getParameter<std::vector<double> >("SMB_21_0_scale");
0121 SMB_22S = pset.getParameter<std::vector<double> >("SMB_22_0_scale");
0122 SMB_30S = pset.getParameter<std::vector<double> >("SMB_30_0_scale");
0123 SMB_31S = pset.getParameter<std::vector<double> >("SMB_31_0_scale");
0124 SMB_32S = pset.getParameter<std::vector<double> >("SMB_32_0_scale");
0125
0126 SME_11S = pset.getParameter<std::vector<double> >("SME_11_0_scale");
0127 SME_12S = pset.getParameter<std::vector<double> >("SME_12_0_scale");
0128 SME_13S = pset.getParameter<std::vector<double> >("SME_13_0_scale");
0129 SME_21S = pset.getParameter<std::vector<double> >("SME_21_0_scale");
0130 SME_22S = pset.getParameter<std::vector<double> >("SME_22_0_scale");
0131 }
0132
0133
0134
0135
0136 MuonSeedCreator::~MuonSeedCreator() {}
0137
0138
0139
0140
0141
0142
0143
0144
0145 TrajectorySeed MuonSeedCreator::createSeed(
0146 int type, const SegmentContainer& seg, const std::vector<int>& layers, int NShowers, int NShowerSegments) {
0147
0148 int last = 0;
0149
0150 double ptmean = theMinMomentum;
0151 double sptmean = theMinMomentum;
0152
0153 AlgebraicVector t(4);
0154 AlgebraicSymMatrix mat(5, 0);
0155 LocalPoint segPos;
0156
0157
0158 if (type == 1)
0159 estimatePtCSC(seg, layers, ptmean, sptmean);
0160 if (type == 2)
0161 estimatePtOverlap(seg, layers, ptmean, sptmean);
0162 if (type == 3)
0163 estimatePtDT(seg, layers, ptmean, sptmean);
0164 if (type == 4)
0165 estimatePtSingle(seg, layers, ptmean, sptmean);
0166
0167 if (type == 5)
0168 estimatePtCSC(seg, layers, ptmean, sptmean);
0169
0170
0171 if (NShowers > 0)
0172 estimatePtShowering(NShowers, NShowerSegments, ptmean, sptmean);
0173
0174
0175
0176 double charge = 1.0;
0177 if (ptmean < 0.)
0178 charge = -1.0;
0179 if ((charge * ptmean) < theMinMomentum) {
0180 ptmean = theMinMomentum * charge;
0181 sptmean = theMinMomentum;
0182 } else if ((charge * ptmean) > theMaxMomentum) {
0183 ptmean = theMaxMomentum * charge;
0184 sptmean = theMaxMomentum * 0.25;
0185 }
0186
0187 LocalTrajectoryParameters param;
0188
0189 double p_err = 0.0;
0190
0191 int best_seg = 0;
0192 double chi2_dof = 9999.0;
0193 unsigned int ini_seg = 0;
0194
0195 if (type == 5)
0196 ini_seg = 1;
0197 for (size_t i = ini_seg; i < seg.size(); i++) {
0198 double dof = static_cast<double>(seg[i]->degreesOfFreedom());
0199 if (chi2_dof < (seg[i]->chi2() / dof))
0200 continue;
0201 chi2_dof = seg[i]->chi2() / dof;
0202 best_seg = static_cast<int>(i);
0203 }
0204
0205 if (type == 1 || type == 5 || type == 4) {
0206
0207
0208 last = best_seg;
0209
0210 GlobalVector mom = seg[last]->globalPosition() - GlobalPoint();
0211 segPos = seg[last]->localPosition();
0212
0213
0214 GlobalVector polar(GlobalVector::Spherical(mom.theta(), seg[last]->globalDirection().phi(), 1.));
0215
0216
0217 polar *= fabs(ptmean) / polar.perp();
0218
0219 LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
0220 int chargeI = static_cast<int>(charge);
0221 LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
0222 param = param1;
0223 p_err = (sptmean * sptmean) / (polar.mag() * polar.mag() * ptmean * ptmean);
0224 mat = seg[last]->parametersError().similarityT(seg[last]->projectionMatrix());
0225 mat[0][0] = p_err;
0226 if (type == 5) {
0227 mat[0][0] = mat[0][0] / fabs(tan(mom.theta()));
0228 mat[1][1] = mat[1][1] / fabs(tan(mom.theta()));
0229 mat[3][3] = 2.25 * mat[3][3];
0230 mat[4][4] = 2.25 * mat[4][4];
0231 }
0232 if (type == 4) {
0233 mat[0][0] = mat[0][0] / fabs(tan(mom.theta()));
0234 mat[1][1] = mat[1][1] / fabs(tan(mom.theta()));
0235 mat[2][2] = 2.25 * mat[2][2];
0236 mat[3][3] = 2.25 * mat[3][3];
0237 mat[4][4] = 2.25 * mat[4][4];
0238 }
0239 double dh = fabs(seg[last]->globalPosition().eta()) - 1.6;
0240 if (fabs(dh) < 0.1 && type == 1) {
0241 mat[1][1] = 4. * mat[1][1];
0242 mat[2][2] = 4. * mat[2][2];
0243 mat[3][3] = 9. * mat[3][3];
0244 mat[4][4] = 9. * mat[4][4];
0245 }
0246
0247
0248
0249
0250
0251
0252 } else {
0253
0254
0255 last = 0;
0256 segPos = seg[last]->localPosition();
0257 GlobalVector mom = seg[last]->globalPosition() - GlobalPoint();
0258
0259 GlobalVector polar(GlobalVector::Spherical(mom.theta(), seg[last]->globalDirection().phi(), 1.));
0260
0261
0262
0263
0264
0265
0266
0267 polar *= fabs(ptmean) / polar.perp();
0268
0269 LocalVector segDirFromPos = seg[last]->det()->toLocal(polar);
0270 int chargeI = static_cast<int>(charge);
0271 LocalTrajectoryParameters param1(segPos, segDirFromPos, chargeI);
0272 param = param1;
0273 p_err = (sptmean * sptmean) / (polar.mag() * polar.mag() * ptmean * ptmean);
0274 mat = seg[last]->parametersError().similarityT(seg[last]->projectionMatrix());
0275
0276 mat[0][0] = p_err;
0277 }
0278
0279 if (debug) {
0280 GlobalPoint gp = seg[last]->globalPosition();
0281 float Geta = gp.eta();
0282
0283 std::cout << "Type " << type << " Nsegments " << layers.size() << " ";
0284 std::cout << "pt " << ptmean << " errpt " << sptmean << " eta " << Geta << " charge " << charge << std::endl;
0285 }
0286
0287
0288
0289
0290
0291
0292
0293 LocalTrajectoryError error(asSMatrix<5>(mat));
0294
0295
0296 TrajectoryStateOnSurface tsos(param, error, seg[last]->det()->surface(), &*BField);
0297
0298
0299 DetId id = seg[last]->geographicalId();
0300
0301
0302
0303 PTrajectoryStateOnDet seedTSOS = trajectoryStateTransform::persistentState(tsos, id.rawId());
0304
0305 edm::OwnVector<TrackingRecHit> container;
0306 for (unsigned l = 0; l < seg.size(); l++) {
0307 container.push_back(seg[l]->hit()->clone());
0308
0309 }
0310
0311 TrajectorySeed theSeed(seedTSOS, container, alongMomentum);
0312 return theSeed;
0313 }
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324 void MuonSeedCreator::estimatePtCSC(const SegmentContainer& seg,
0325 const std::vector<int>& layers,
0326 double& thePt,
0327 double& theSpt) {
0328 unsigned size = seg.size();
0329 if (size < 2)
0330 return;
0331
0332
0333
0334
0335
0336
0337
0338 std::vector<double> ptEstimate;
0339 std::vector<double> sptEstimate;
0340
0341 thePt = defaultMomentum;
0342 theSpt = defaultMomentum;
0343
0344 double pt = 0.;
0345 double spt = 0.;
0346 GlobalPoint segPos[2];
0347
0348 int layer0 = layers[0];
0349 segPos[0] = seg[0]->globalPosition();
0350 float eta = fabs(segPos[0].eta());
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364
0365
0366 unsigned idx1 = size;
0367 if (size > 1) {
0368 while (idx1 > 1) {
0369 idx1--;
0370 int layer1 = layers[idx1];
0371 if (layer0 == layer1)
0372 continue;
0373 segPos[1] = seg[idx1]->globalPosition();
0374
0375 double dphi = segPos[0].phi() - segPos[1].phi();
0376
0377 double temp_dphi = dphi;
0378
0379 double sign = 1.0;
0380 if (temp_dphi < 0.) {
0381 temp_dphi = -1.0 * temp_dphi;
0382 sign = -1.0;
0383 }
0384
0385
0386 if (temp_dphi < 0.0001) {
0387 temp_dphi = 0.0001;
0388 pt = theMaxMomentum;
0389 spt = theMaxMomentum * 0.25;
0390 ptEstimate.push_back(pt * sign);
0391 sptEstimate.push_back(spt);
0392 }
0393
0394 if (layer0 == 0 && temp_dphi >= 0.0001) {
0395
0396 if (layer1 == 1) {
0397
0398 pt = getPt(CSC01, eta, temp_dphi)[0];
0399 spt = getPt(CSC01, eta, temp_dphi)[1];
0400 }
0401
0402 else if (layer1 == 2) {
0403
0404 pt = getPt(CSC02, eta, temp_dphi)[0];
0405 spt = getPt(CSC02, eta, temp_dphi)[1];
0406 }
0407
0408 else if (layer1 == 3) {
0409
0410 pt = getPt(CSC03, eta, temp_dphi)[0];
0411 spt = getPt(CSC03, eta, temp_dphi)[1];
0412 }
0413
0414 else {
0415
0416 pt = getPt(CSC14, eta, temp_dphi)[0];
0417 spt = getPt(CSC14, eta, temp_dphi)[1];
0418 }
0419 ptEstimate.push_back(pt * sign);
0420 sptEstimate.push_back(spt);
0421 }
0422
0423
0424 if (layer0 == 1) {
0425
0426 if (layer1 == 2) {
0427
0428
0429 pt = getPt(CSC12, eta, temp_dphi)[0];
0430 spt = getPt(CSC12, eta, temp_dphi)[1];
0431 }
0432
0433 else if (layer1 == 3) {
0434 temp_dphi = scaledPhi(temp_dphi, CSC13_2[3]);
0435 pt = getPt(CSC13, eta, temp_dphi)[0];
0436 spt = getPt(CSC13, eta, temp_dphi)[1];
0437 }
0438
0439 else {
0440 temp_dphi = scaledPhi(temp_dphi, CSC14_3[3]);
0441 pt = getPt(CSC14, eta, temp_dphi)[0];
0442 spt = getPt(CSC14, eta, temp_dphi)[1];
0443 }
0444 ptEstimate.push_back(pt * sign);
0445 sptEstimate.push_back(spt);
0446 }
0447
0448
0449 if (layer0 == 2 && temp_dphi > 0.0001) {
0450
0451 if (layer1 == 4) {
0452 temp_dphi = scaledPhi(temp_dphi, CSC24_1[3]);
0453 pt = getPt(CSC24, eta, temp_dphi)[0];
0454 spt = getPt(CSC24, eta, temp_dphi)[1];
0455 }
0456
0457 else {
0458
0459 if (eta <= 1.7) {
0460 temp_dphi = scaledPhi(temp_dphi, CSC23_1[3]);
0461 }
0462 if (eta > 1.7) {
0463 temp_dphi = scaledPhi(temp_dphi, CSC23_2[3]);
0464 }
0465 pt = getPt(CSC23, eta, temp_dphi)[0];
0466 spt = getPt(CSC23, eta, temp_dphi)[1];
0467 }
0468 ptEstimate.push_back(pt * sign);
0469 sptEstimate.push_back(spt);
0470 }
0471
0472
0473 if (layer0 == 3 && temp_dphi > 0.0001) {
0474 temp_dphi = scaledPhi(temp_dphi, CSC34_1[3]);
0475 pt = getPt(CSC34, eta, temp_dphi)[0];
0476 spt = getPt(CSC34, eta, temp_dphi)[1];
0477 ptEstimate.push_back(pt * sign);
0478 sptEstimate.push_back(spt);
0479 }
0480 }
0481 }
0482
0483
0484 if (!ptEstimate.empty())
0485 weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
0486 }
0487
0488
0489
0490
0491
0492
0493
0494 void MuonSeedCreator::estimatePtDT(const SegmentContainer& seg,
0495 const std::vector<int>& layers,
0496 double& thePt,
0497 double& theSpt) {
0498 unsigned size = seg.size();
0499 if (size < 2)
0500 return;
0501
0502 std::vector<double> ptEstimate;
0503 std::vector<double> sptEstimate;
0504
0505 thePt = defaultMomentum;
0506 theSpt = defaultMomentum;
0507
0508 double pt = 0.;
0509 double spt = 0.;
0510 GlobalPoint segPos[2];
0511
0512 int layer0 = layers[0];
0513 segPos[0] = seg[0]->globalPosition();
0514 float eta = fabs(segPos[0].eta());
0515
0516
0517
0518
0519
0520
0521
0522
0523 for (unsigned idx1 = 1; idx1 < size; ++idx1) {
0524 int layer1 = layers[idx1];
0525 segPos[1] = seg[idx1]->globalPosition();
0526
0527
0528
0529
0530 double dphi = segPos[0].phi() - segPos[1].phi();
0531 double temp_dphi = dphi;
0532
0533
0534
0535 double sign = 1.0;
0536 if (temp_dphi < 0.) {
0537 temp_dphi = -temp_dphi;
0538 sign = -1.0;
0539 }
0540
0541 if (temp_dphi < 0.0001) {
0542 temp_dphi = 0.0001;
0543 pt = theMaxMomentum;
0544 spt = theMaxMomentum * 0.25;
0545 ptEstimate.push_back(pt * sign);
0546 sptEstimate.push_back(spt);
0547 }
0548
0549
0550 if (layer0 == -1 && temp_dphi > 0.0001) {
0551
0552 if (layer1 == -2) {
0553 if (eta <= 0.7) {
0554 temp_dphi = scaledPhi(temp_dphi, DT12_1[3]);
0555 }
0556 if (eta > 0.7) {
0557 temp_dphi = scaledPhi(temp_dphi, DT12_2[3]);
0558 }
0559 pt = getPt(DT12, eta, temp_dphi)[0];
0560 spt = getPt(DT12, eta, temp_dphi)[1];
0561 }
0562
0563 else if (layer1 == -3) {
0564 if (eta <= 0.6) {
0565 temp_dphi = scaledPhi(temp_dphi, DT13_1[3]);
0566 }
0567 if (eta > 0.6) {
0568 temp_dphi = scaledPhi(temp_dphi, DT13_2[3]);
0569 }
0570 pt = getPt(DT13, eta, temp_dphi)[0];
0571 spt = getPt(DT13, eta, temp_dphi)[1];
0572 }
0573
0574 else {
0575 if (eta <= 0.52) {
0576 temp_dphi = scaledPhi(temp_dphi, DT14_1[3]);
0577 }
0578 if (eta > 0.52) {
0579 temp_dphi = scaledPhi(temp_dphi, DT14_2[3]);
0580 }
0581 pt = getPt(DT14, eta, temp_dphi)[0];
0582 spt = getPt(DT14, eta, temp_dphi)[1];
0583 }
0584 ptEstimate.push_back(pt * sign);
0585 sptEstimate.push_back(spt);
0586 }
0587
0588
0589 if (layer0 == -2 && temp_dphi > 0.0001) {
0590
0591 if (layer1 == -3) {
0592 if (eta <= 0.6) {
0593 temp_dphi = scaledPhi(temp_dphi, DT23_1[3]);
0594 }
0595 if (eta > 0.6) {
0596 temp_dphi = scaledPhi(temp_dphi, DT23_2[3]);
0597 }
0598 pt = getPt(DT23, eta, temp_dphi)[0];
0599 spt = getPt(DT23, eta, temp_dphi)[1];
0600 }
0601
0602 else {
0603 if (eta <= 0.52) {
0604 temp_dphi = scaledPhi(temp_dphi, DT24_1[3]);
0605 }
0606 if (eta > 0.52) {
0607 temp_dphi = scaledPhi(temp_dphi, DT24_2[3]);
0608 }
0609 pt = getPt(DT24, eta, temp_dphi)[0];
0610 spt = getPt(DT24, eta, temp_dphi)[1];
0611 }
0612 ptEstimate.push_back(pt * sign);
0613 sptEstimate.push_back(spt);
0614 }
0615
0616
0617 if (layer0 == -3 && temp_dphi > 0.0001) {
0618
0619
0620 if (eta <= 0.51) {
0621 temp_dphi = scaledPhi(temp_dphi, DT34_1[3]);
0622 }
0623 if (eta > 0.51) {
0624 temp_dphi = scaledPhi(temp_dphi, DT34_2[3]);
0625 }
0626 pt = getPt(DT34, eta, temp_dphi)[0];
0627 spt = getPt(DT34, eta, temp_dphi)[1];
0628 ptEstimate.push_back(pt * sign);
0629 sptEstimate.push_back(spt);
0630 }
0631 }
0632
0633
0634
0635 if (!ptEstimate.empty())
0636 weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
0637 }
0638
0639
0640
0641
0642
0643 void MuonSeedCreator::estimatePtOverlap(const SegmentContainer& seg,
0644 const std::vector<int>& layers,
0645 double& thePt,
0646 double& theSpt) {
0647 int size = layers.size();
0648
0649 thePt = defaultMomentum;
0650 theSpt = defaultMomentum;
0651
0652 SegmentContainer segCSC;
0653 std::vector<int> layersCSC;
0654 SegmentContainer segDT;
0655 std::vector<int> layersDT;
0656
0657
0658 for (unsigned j = 0; j < layers.size(); ++j) {
0659 if (layers[j] > -1) {
0660 segCSC.push_back(seg[j]);
0661 layersCSC.push_back(layers[j]);
0662 } else {
0663 segDT.push_back(seg[j]);
0664 layersDT.push_back(layers[j]);
0665 }
0666 }
0667
0668 std::vector<double> ptEstimate;
0669 std::vector<double> sptEstimate;
0670
0671 GlobalPoint segPos[2];
0672 int layer0 = layers[0];
0673 segPos[0] = seg[0]->globalPosition();
0674 float eta = fabs(segPos[0].eta());
0675
0676
0677 if (!segDT.empty() && !segCSC.empty()) {
0678 int layer1 = layers[size - 1];
0679 segPos[1] = seg[size - 1]->globalPosition();
0680
0681 double dphi = segPos[0].phi() - segPos[1].phi();
0682 double temp_dphi = dphi;
0683
0684
0685
0686 double sign = 1.0;
0687 if (temp_dphi < 0.) {
0688 temp_dphi = -temp_dphi;
0689 sign = -1.0;
0690 }
0691
0692 if (temp_dphi < 0.0001) {
0693 temp_dphi = 0.0001;
0694 thePt = theMaxMomentum;
0695 theSpt = theMaxMomentum * 0.25;
0696 ptEstimate.push_back(thePt * sign);
0697 sptEstimate.push_back(theSpt);
0698 }
0699
0700
0701 if (layer0 == -1 && temp_dphi > 0.0001) {
0702
0703 if (layer1 == 1) {
0704 temp_dphi = scaledPhi(temp_dphi, OL_1213[3]);
0705 thePt = getPt(OL1213, eta, temp_dphi)[0];
0706 theSpt = getPt(OL1213, eta, temp_dphi)[1];
0707 }
0708
0709 else if (layer1 == 2) {
0710 temp_dphi = scaledPhi(temp_dphi, OL_1222[3]);
0711 thePt = getPt(OL1222, eta, temp_dphi)[0];
0712 theSpt = getPt(OL1222, eta, temp_dphi)[1];
0713 }
0714
0715 else {
0716 temp_dphi = scaledPhi(temp_dphi, OL_1232[3]);
0717 thePt = getPt(OL1232, eta, temp_dphi)[0];
0718 theSpt = getPt(OL1232, eta, temp_dphi)[1];
0719 }
0720 ptEstimate.push_back(thePt * sign);
0721 sptEstimate.push_back(theSpt);
0722 }
0723
0724 if (layer0 == -2 && temp_dphi > 0.0001) {
0725
0726 if (layer1 == 1) {
0727 temp_dphi = scaledPhi(temp_dphi, OL_2213[3]);
0728 thePt = getPt(OL2213, eta, temp_dphi)[0];
0729 theSpt = getPt(OL2213, eta, temp_dphi)[1];
0730 ptEstimate.push_back(thePt * sign);
0731 sptEstimate.push_back(theSpt);
0732 }
0733
0734 if (layer1 == 2) {
0735 temp_dphi = scaledPhi(temp_dphi, OL_2222[3]);
0736 thePt = getPt(OL2222, eta, temp_dphi)[0];
0737 theSpt = getPt(OL2222, eta, temp_dphi)[1];
0738 }
0739 }
0740 }
0741
0742 if (segDT.size() > 1) {
0743 estimatePtDT(segDT, layersDT, thePt, theSpt);
0744 ptEstimate.push_back(thePt);
0745 sptEstimate.push_back(theSpt);
0746 }
0747
0748
0749
0750
0751
0752
0753
0754
0755
0756
0757
0758
0759
0760
0761
0762
0763
0764
0765 if (!ptEstimate.empty())
0766 weightedPt(ptEstimate, sptEstimate, thePt, theSpt);
0767 }
0768
0769
0770
0771
0772
0773 void MuonSeedCreator::estimatePtSingle(const SegmentContainer& seg,
0774 const std::vector<int>& layers,
0775 double& thePt,
0776 double& theSpt) {
0777 thePt = defaultMomentum;
0778 theSpt = defaultMomentum;
0779
0780 GlobalPoint segPos = seg[0]->globalPosition();
0781 double eta = segPos.eta();
0782 GlobalVector gv = seg[0]->globalDirection();
0783
0784
0785
0786 double cosDpsi = (gv.x() * segPos.x() + gv.y() * segPos.y());
0787 cosDpsi /= sqrt(segPos.x() * segPos.x() + segPos.y() * segPos.y());
0788 cosDpsi /= sqrt(gv.x() * gv.x() + gv.y() * gv.y());
0789
0790 double axb = (segPos.x() * gv.y()) - (segPos.y() * gv.x());
0791 double sign = (axb < 0.) ? 1.0 : -1.0;
0792
0793 double dpsi = fabs(acos(cosDpsi));
0794 if (dpsi > 1.570796) {
0795 dpsi = 3.141592 - dpsi;
0796 sign = -1. * sign;
0797 }
0798 if (fabs(dpsi) < 0.00005) {
0799 dpsi = 0.00005;
0800 }
0801
0802
0803 if (layers[0] == -1) {
0804
0805 if (fabs(eta) < 0.3) {
0806 dpsi = scaledPhi(dpsi, SMB_10S[3]);
0807 thePt = getPt(SMB10, eta, dpsi)[0];
0808 theSpt = getPt(SMB10, eta, dpsi)[1];
0809 }
0810
0811 if (fabs(eta) >= 0.3 && fabs(eta) < 0.82) {
0812 dpsi = scaledPhi(dpsi, SMB_11S[3]);
0813 thePt = getPt(SMB11, eta, dpsi)[0];
0814 theSpt = getPt(SMB11, eta, dpsi)[1];
0815 }
0816
0817 if (fabs(eta) >= 0.82 && fabs(eta) < 1.2) {
0818 dpsi = scaledPhi(dpsi, SMB_12S[3]);
0819 thePt = getPt(SMB12, eta, dpsi)[0];
0820 theSpt = getPt(SMB12, eta, dpsi)[1];
0821 }
0822 }
0823 if (layers[0] == 1) {
0824
0825 if (fabs(eta) > 0.92 && fabs(eta) < 1.16) {
0826 dpsi = scaledPhi(dpsi, SME_13S[3]);
0827 thePt = getPt(SME13, eta, dpsi)[0];
0828 theSpt = getPt(SME13, eta, dpsi)[1];
0829 }
0830
0831 if (fabs(eta) >= 1.16 && fabs(eta) <= 1.6) {
0832 dpsi = scaledPhi(dpsi, SME_12S[3]);
0833 thePt = getPt(SME12, eta, dpsi)[0];
0834 theSpt = getPt(SME12, eta, dpsi)[1];
0835 }
0836 }
0837 if (layers[0] == 0) {
0838
0839 if (fabs(eta) > 1.6) {
0840 dpsi = scaledPhi(dpsi, SMB_11S[3]);
0841 thePt = getPt(SME11, eta, dpsi)[0];
0842 theSpt = getPt(SME11, eta, dpsi)[1];
0843 }
0844 }
0845
0846 if (layers[0] == -2) {
0847
0848 if (fabs(eta) < 0.25) {
0849 dpsi = scaledPhi(dpsi, SMB_20S[3]);
0850 thePt = getPt(SMB20, eta, dpsi)[0];
0851 theSpt = getPt(SMB20, eta, dpsi)[1];
0852 }
0853
0854 if (fabs(eta) >= 0.25 && fabs(eta) < 0.72) {
0855 dpsi = scaledPhi(dpsi, SMB_21S[3]);
0856 thePt = getPt(SMB21, eta, dpsi)[0];
0857 theSpt = getPt(SMB21, eta, dpsi)[1];
0858 }
0859
0860 if (fabs(eta) >= 0.72 && fabs(eta) < 1.04) {
0861 dpsi = scaledPhi(dpsi, SMB_22S[3]);
0862 thePt = getPt(SMB22, eta, dpsi)[0];
0863 theSpt = getPt(SMB22, eta, dpsi)[1];
0864 }
0865 }
0866 if (layers[0] == 2) {
0867
0868 if (fabs(eta) > 0.95 && fabs(eta) <= 1.6) {
0869 dpsi = scaledPhi(dpsi, SME_22S[3]);
0870 thePt = getPt(SME22, eta, dpsi)[0];
0871 theSpt = getPt(SME22, eta, dpsi)[1];
0872 }
0873
0874 if (fabs(eta) > 1.6 && fabs(eta) < 2.45) {
0875 dpsi = scaledPhi(dpsi, SME_21S[3]);
0876 thePt = getPt(SME21, eta, dpsi)[0];
0877 theSpt = getPt(SME21, eta, dpsi)[1];
0878 }
0879 }
0880
0881
0882 if (layers[0] == -3) {
0883
0884 if (fabs(eta) <= 0.22) {
0885 dpsi = scaledPhi(dpsi, SMB_30S[3]);
0886 thePt = getPt(SMB30, eta, dpsi)[0];
0887 theSpt = getPt(SMB30, eta, dpsi)[1];
0888 }
0889
0890 if (fabs(eta) > 0.22 && fabs(eta) <= 0.6) {
0891 dpsi = scaledPhi(dpsi, SMB_31S[3]);
0892 thePt = getPt(SMB31, eta, dpsi)[0];
0893 theSpt = getPt(SMB31, eta, dpsi)[1];
0894 }
0895
0896 if (fabs(eta) > 0.6 && fabs(eta) < 0.95) {
0897 dpsi = scaledPhi(dpsi, SMB_32S[3]);
0898 thePt = getPt(SMB32, eta, dpsi)[0];
0899 theSpt = getPt(SMB32, eta, dpsi)[1];
0900 }
0901 }
0902 thePt = fabs(thePt) * sign;
0903 theSpt = fabs(theSpt);
0904
0905 return;
0906 }
0907
0908
0909 void MuonSeedCreator::estimatePtShowering(int& NShowers, int& NShowerSegments, double& thePt, double& theSpt) {
0910 if (NShowers > 2 && thePt < 300.) {
0911 thePt = 800.;
0912 theSpt = 200.;
0913 }
0914 if (NShowers == 2 && NShowerSegments > 11 && thePt < 150.) {
0915 thePt = 280.;
0916 theSpt = 70.;
0917 }
0918 if (NShowers == 2 && NShowerSegments <= 11 && thePt < 50.) {
0919 thePt = 80.;
0920 theSpt = 40.;
0921 }
0922 if (NShowers == 1 && NShowerSegments <= 5 && thePt < 10.) {
0923 thePt = 16.;
0924 theSpt = 8.;
0925 }
0926 }
0927
0928
0929
0930
0931
0932
0933
0934 void MuonSeedCreator::weightedPt(const std::vector<double>& ptEstimate,
0935 const std::vector<double>& sptEstimate,
0936 double& thePt,
0937 double& theSpt) {
0938 int size = ptEstimate.size();
0939
0940
0941 if (size < 2) {
0942 thePt = ptEstimate[0];
0943 theSpt = sptEstimate[0];
0944 return;
0945 }
0946
0947 double charge = 0.;
0948
0949
0950
0951 for (unsigned j = 0; j < ptEstimate.size(); j++) {
0952
0953 if (ptEstimate[j] < 0.) {
0954
0955
0956 charge -= 1. * (ptEstimate[j] * ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
0957 } else {
0958
0959 charge += 1. * (ptEstimate[j] * ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
0960 }
0961 }
0962
0963
0964 if (charge < 0.) {
0965 charge = -1.;
0966 } else {
0967 charge = 1.;
0968 }
0969
0970
0971 double weightPtSum = 0.;
0972 double sigmaSqr_sum = 0.;
0973
0974
0975
0976 for (unsigned j = 0; j < ptEstimate.size(); ++j) {
0977
0978
0979
0980 sigmaSqr_sum += 1.0 / (sptEstimate[j] * sptEstimate[j]);
0981 weightPtSum += fabs(ptEstimate[j]) / (sptEstimate[j] * sptEstimate[j]);
0982
0983 }
0984
0985
0986
0987
0988
0989
0990
0991
0992
0993 thePt = (charge * weightPtSum) / sigmaSqr_sum;
0994 theSpt = sqrt(1.0 / sigmaSqr_sum);
0995
0996
0997
0998 return;
0999 }
1000
1001 std::vector<double> MuonSeedCreator::getPt(const std::vector<double>& vPara, double eta, double dPhi) {
1002 double h = fabs(eta);
1003 double estPt = (vPara[0] + vPara[1] * h + vPara[2] * h * h) / dPhi;
1004 double estSPt = (vPara[3] + vPara[4] * h + vPara[5] * h * h) * estPt;
1005 std::vector<double> paraPt;
1006 paraPt.push_back(estPt);
1007 paraPt.push_back(estSPt);
1008
1009
1010 return paraPt;
1011 }
1012
1013 double MuonSeedCreator::scaledPhi(double dphi, double t1) {
1014 if (dphi != 0.) {
1015 double oPhi = 1. / dphi;
1016 dphi = dphi / (1. + t1 / (oPhi + 10.));
1017 return dphi;
1018
1019 } else {
1020 return dphi;
1021 }
1022 }