File indexing completed on 2025-01-09 23:33:58
0001
0002
0003
0004 #include "RecoMuon/MuonSeedGenerator/interface/SETFilter.h"
0005
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007
0008
0009 #include "FWCore/Framework/interface/Event.h"
0010
0011 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
0012
0013 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
0014 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
0015 #include "TrackingTools/DetLayers/interface/DetLayer.h"
0016
0017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
0018 #include "TrackingTools/TrackFitters/interface/TrajectoryFitter.h"
0019
0020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0021 #include "FWCore/Utilities/interface/Exception.h"
0022
0023 #include "DataFormats/Math/interface/Matrix.h"
0024
0025 #include <vector>
0026
0027 #include <iostream>
0028 #include <fstream>
0029
0030
0031 struct sorter {
0032
0033 sorter() {}
0034 bool operator()(TransientTrackingRecHit::ConstRecHitPointer hit_1,
0035 TransientTrackingRecHit::ConstRecHitPointer hit_2) const {
0036 if (hit_1->det()->subDetector() != GeomDetEnumerators::CSC ||
0037 hit_2->det()->subDetector() != GeomDetEnumerators::CSC) {
0038
0039 return (hit_1->globalPosition().mag2() > hit_2->globalPosition().mag2());
0040 } else {
0041 return (fabs(hit_1->globalPosition().z()) > fabs(hit_2->globalPosition().z()));
0042 }
0043 }
0044 } const sortRadius;
0045
0046 using namespace edm;
0047 using namespace std;
0048
0049 SETFilter::SETFilter(const ParameterSet &par,
0050 const MuonServiceProxy *service)
0051 : theService(service)
0052
0053 {
0054 thePropagatorName = par.getParameter<string>("Propagator");
0055 useSegmentsInTrajectory = par.getUntrackedParameter<bool>("UseSegmentsInTrajectory");
0056 }
0057
0058 SETFilter::~SETFilter() { LogTrace("Muon|RecoMuon|SETFilter") << "SETFilter destructor called" << endl; }
0059
0060 void SETFilter::setEvent(const Event &event) {}
0061
0062 void SETFilter::reset() {
0063 totalChambers = dtChambers = cscChambers = rpcChambers = 0;
0064
0065 theLastUpdatedTSOS = theLastButOneUpdatedTSOS = TrajectoryStateOnSurface();
0066
0067 theDetLayers.clear();
0068 }
0069
0070 const Propagator *SETFilter::propagator() const { return &*theService->propagator(thePropagatorName); }
0071
0072 void SETFilter::incrementChamberCounters(const DetLayer *layer) {
0073 if (layer->subDetector() == GeomDetEnumerators::DT)
0074 dtChambers++;
0075 else if (layer->subDetector() == GeomDetEnumerators::CSC)
0076 cscChambers++;
0077 else if (layer->subDetector() == GeomDetEnumerators::RPCBarrel ||
0078 layer->subDetector() == GeomDetEnumerators::RPCEndcap)
0079 rpcChambers++;
0080 else
0081 LogError("Muon|RecoMuon|SETFilter") << "Unrecognized module type in incrementChamberCounters";
0082
0083
0084
0085 totalChambers++;
0086 }
0087
0088
0089 bool SETFilter::fwfit_SET(std::vector<SeedCandidate> &validSegmentsSet_in,
0090 std::vector<SeedCandidate> &validSegmentsSet_out) {
0091
0092 validSegmentsSet_out.clear();
0093
0094
0095
0096
0097
0098
0099 bool validStep = true;
0100 std::vector<double> chi2AllCombinations(validSegmentsSet_in.size());
0101 std::vector<TrajectoryStateOnSurface> lastUpdatedTSOS_Vect(validSegmentsSet_in.size());
0102
0103 for (unsigned int iSet = 0; iSet < validSegmentsSet_in.size(); ++iSet) {
0104
0105
0106 CLHEP::Hep3Vector origin(0., 0., 0.);
0107 Trajectory::DataContainer trajectoryMeasurementsInTheSet_tmp;
0108
0109 chi2AllCombinations[iSet] =
0110 findMinChi2(iSet, origin, validSegmentsSet_in[iSet], lastUpdatedTSOS_Vect, trajectoryMeasurementsInTheSet_tmp);
0111 }
0112
0113 std::vector<double>::iterator itMin = min_element(chi2AllCombinations.begin(), chi2AllCombinations.end());
0114
0115 int positionMin = itMin - chi2AllCombinations.begin();
0116
0117
0118 validSegmentsSet_out.push_back(validSegmentsSet_in[positionMin]);
0119
0120 return validStep;
0121 }
0122
0123
0124 bool SETFilter::buildTrajectoryMeasurements(SeedCandidate *finalMuon, Trajectory::DataContainer &finalCandidate) {
0125
0126 bool validTrajectory = true;
0127
0128 reset();
0129 finalCandidate.clear();
0130
0131
0132
0133 if (!finalMuon->trajectoryMeasurementsInTheSet.empty() &&
0134 finalMuon->trajectoryMeasurementsInTheSet.back().forwardPredictedState().isValid()) {
0135
0136 for (unsigned int iMeas = 0; iMeas < finalMuon->trajectoryMeasurementsInTheSet.size(); ++iMeas) {
0137
0138 finalCandidate.push_back(finalMuon->trajectoryMeasurementsInTheSet[iMeas]);
0139 const DetLayer *layer = finalMuon->trajectoryMeasurementsInTheSet[iMeas].layer();
0140
0141 incrementChamberCounters(layer);
0142
0143 theDetLayers.push_back(layer);
0144 }
0145 theLastUpdatedTSOS =
0146 finalMuon->trajectoryMeasurementsInTheSet.at(finalMuon->trajectoryMeasurementsInTheSet.size() - 1)
0147 .forwardPredictedState();
0148
0149
0150 } else {
0151 validTrajectory = false;
0152
0153 }
0154 return validTrajectory;
0155 }
0156
0157
0158 bool SETFilter::transform(Trajectory::DataContainer &measurements_segments,
0159 TransientTrackingRecHit::ConstRecHitContainer &hitContainer,
0160 TrajectoryStateOnSurface &firstTSOS) {
0161
0162
0163 bool success = true;
0164
0165 for (int iMeas = measurements_segments.size() - 1; iMeas > -1; --iMeas) {
0166 TransientTrackingRecHit ::ConstRecHitContainer sortedHits;
0167
0168 for (unsigned int jMeas = 0; jMeas < measurements_segments[iMeas].recHit()->transientHits().size(); ++jMeas) {
0169 if (measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size() > 1) {
0170
0171
0172 for (unsigned int kMeas = 0;
0173 kMeas < measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size();
0174 ++kMeas) {
0175 sortedHits.push_back(
0176 measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().at(kMeas));
0177 }
0178 } else {
0179 sortedHits = measurements_segments[iMeas].recHit()->transientHits();
0180 }
0181 }
0182
0183 sort(sortedHits.begin(), sortedHits.end(), sortRadius);
0184 hitContainer.insert(hitContainer.end(), sortedHits.begin(), sortedHits.end());
0185 }
0186
0187
0188 FreeTrajectoryState ftsStart =
0189 *(measurements_segments.at(measurements_segments.size() - 1).forwardPredictedState().freeState());
0190
0191
0192 TransientTrackingRecHit::ConstRecHitPointer muonRecHit = hitContainer[0];
0193 DetId detId_last = hitContainer[0]->hit()->geographicalId();
0194 const GeomDet *layer_last = theService->trackingGeometry()->idToDet(detId_last);
0195
0196
0197 TrajectoryStateOnSurface tSOSDest = propagator()->propagate(ftsStart, layer_last->surface());
0198 firstTSOS = tSOSDest;
0199
0200 if (!tSOSDest.isValid()) {
0201 success = false;
0202
0203 }
0204 return success;
0205 }
0206
0207 bool SETFilter::transformLight(Trajectory::DataContainer &measurements_segments,
0208 TransientTrackingRecHit::ConstRecHitContainer &hitContainer,
0209 TrajectoryStateOnSurface &firstTSOS) {
0210
0211
0212 bool success = true;
0213
0214 if (useSegmentsInTrajectory) {
0215
0216 for (unsigned int iMeas = 0; iMeas < measurements_segments.size(); ++iMeas) {
0217 hitContainer.push_back(measurements_segments[iMeas].recHit());
0218 }
0219 } else {
0220 for (int iMeas = measurements_segments.size() - 1; iMeas > -1; --iMeas) {
0221 hitContainer.push_back(measurements_segments[iMeas].recHit());
0222 }
0223 }
0224
0225 firstTSOS = measurements_segments.at(0).forwardPredictedState();
0226 return success;
0227 }
0228
0229 double SETFilter::findChi2(double pX,
0230 double pY,
0231 double pZ,
0232 const CLHEP::Hep3Vector &r3T,
0233 SeedCandidate &muonCandidate,
0234 TrajectoryStateOnSurface &lastUpdatedTSOS,
0235 Trajectory::DataContainer &trajectoryMeasurementsInTheSet,
0236 bool detailedOutput) {
0237
0238
0239
0240
0241 if (detailedOutput) {
0242 trajectoryMeasurementsInTheSet.clear();
0243 }
0244
0245 int charge = muonCandidate.charge;
0246 GlobalVector p3GV(pX, pY, pZ);
0247 GlobalPoint r3GP(r3T.x(), r3T.y(), r3T.z());
0248
0249
0250 FreeTrajectoryState ftsStart(r3GP, p3GV, charge, &*(theService->magneticField()));
0251
0252 if (detailedOutput) {
0253 AlgebraicSymMatrix55 cov;
0254 cov *= 1e-20;
0255 ftsStart.setCurvilinearError(cov);
0256 }
0257 TrajectoryStateOnSurface tSOSDest;
0258
0259 double chi2_loc = 0.;
0260 for (unsigned int iMeas = 0; iMeas < muonCandidate.theSet.size(); ++iMeas) {
0261 MuonTransientTrackingRecHit::MuonRecHitPointer muonRecHit = muonCandidate.theSet[iMeas];
0262 DetId detId = muonRecHit->hit()->geographicalId();
0263 const GeomDet *layer = theService->trackingGeometry()->idToDet(detId);
0264
0265
0266
0267
0268
0269
0270
0271 tSOSDest = propagator()->propagate(ftsStart, layer->surface());
0272 lastUpdatedTSOS = tSOSDest;
0273 if (tSOSDest.isValid()) {
0274
0275 ftsStart = *tSOSDest.freeState();
0276 } else {
0277
0278 chi2_loc = 9999999999.;
0279 break;
0280 }
0281
0282
0283 LocalPoint locHitPos = muonRecHit->localPosition();
0284 LocalError locHitErr = muonRecHit->localPositionError();
0285 const GlobalPoint globPropPos = ftsStart.position();
0286 LocalPoint locPropPos = layer->toLocal(globPropPos);
0287
0288
0289
0290 CLHEP::HepMatrix dist(1, 2);
0291 double chi2_intermed = -9;
0292 int ierr = 0;
0293 dist(1, 1) = locPropPos.x() - locHitPos.x();
0294 dist(1, 2) = locPropPos.y() - locHitPos.y();
0295 CLHEP::HepMatrix IC(2, 2);
0296 IC(1, 1) = locHitErr.xx();
0297 IC(2, 1) = locHitErr.xy();
0298 IC(2, 2) = locHitErr.yy();
0299 IC(1, 2) = IC(2, 1);
0300
0301
0302 if (4 != muonRecHit->hit()->dimension()) {
0303 for (int iE = 1; iE < 3; ++iE) {
0304
0305 if (fabs(IC(iE, iE)) < 0.00000001) {
0306 IC(iE, iE) = 62500. / 12.;
0307 }
0308 }
0309 }
0310
0311 IC.invert(ierr);
0312
0313
0314
0315 chi2_intermed =
0316 pow(dist(1, 1), 2) * IC(1, 1) + 2. * dist(1, 1) * dist(1, 2) * IC(1, 2) + pow(dist(1, 2), 2) * IC(2, 2);
0317 if (chi2_intermed < 0) {
0318 chi2_intermed = 9999999999.;
0319 }
0320 chi2_loc += chi2_intermed;
0321
0322
0323 if (detailedOutput) {
0324 DetId detId = muonRecHit->hit()->geographicalId();
0325 const DetLayer *layer = theService->detLayerGeometry()->idToLayer(detId);
0326
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336 trajectoryMeasurementsInTheSet.push_back(
0337 TrajectoryMeasurement(lastUpdatedTSOS, muonRecHit, chi2_intermed, layer));
0338 }
0339 }
0340 return chi2_loc;
0341 }
0342
0343 double SETFilter::findMinChi2(unsigned int iSet,
0344 const CLHEP::Hep3Vector &r3T,
0345 SeedCandidate &muonCandidate,
0346 std::vector<TrajectoryStateOnSurface> &lastUpdatedTSOS_Vect,
0347 Trajectory::DataContainer &trajectoryMeasurementsInTheSet) {
0348
0349
0350
0351
0352
0353 bool detailedOutput = false;
0354
0355 double cosTheta = muonCandidate.momentum.cosTheta();
0356 double theta = acos(cosTheta);
0357 double phi = muonCandidate.momentum.phi();
0358 double pMag = muonCandidate.momentum.mag();
0359
0360 double minChi2 = -999.;
0361 TrajectoryStateOnSurface lastUpdatedTSOS;
0362
0363
0364
0365 if (pMag < 5.) {
0366 pMag = 5.;
0367 }
0368
0369 pMag *= 1.2;
0370 double invP = 1. / pMag;
0371
0372
0373
0374
0375
0376
0377 const double reflect = 1;
0378 const double expand = -0.5;
0379 const double contract = 0.25;
0380
0381 const int nDim = 3;
0382
0383 std::vector<CLHEP::Hep3Vector> feet(nDim + 1);
0384 std::vector<double> chi2Feet(nDim + 1);
0385 std::vector<TrajectoryStateOnSurface *> lastUpdatedTSOS_pointer(nDim + 1);
0386
0387
0388
0389 CLHEP::Hep3Vector foot1(
0390 invP, theta, phi);
0391 feet[0] = foot1;
0392 chi2Feet[0] =
0393 chi2AtSpecificStep(feet[0], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0394 lastUpdatedTSOS_pointer[0] = &lastUpdatedTSOS;
0395
0396 std::vector<CLHEP::Hep3Vector> morePoints = find3MoreStartingPoints(feet[0], r3T, muonCandidate);
0397 feet[1] = morePoints[0];
0398 feet[2] = morePoints[1];
0399 feet[3] = morePoints[2];
0400
0401
0402 for (unsigned int iFoot = 1; iFoot < feet.size(); ++iFoot) {
0403 chi2Feet[iFoot] = chi2AtSpecificStep(
0404 feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0405 lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
0406 }
0407
0408 unsigned int high, second_high, low;
0409
0410 int iCalls = 0;
0411
0412 while (iCalls < 3.) {
0413
0414 pickElements(chi2Feet, high, second_high, low);
0415 ++iCalls;
0416 feet[high] = reflectFoot(feet, high, reflect);
0417 chi2Feet[high] = chi2AtSpecificStep(
0418 feet[high], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0419 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
0420
0421 if (chi2Feet[high] < chi2Feet[low]) {
0422 ++iCalls;
0423 feet[high] = reflectFoot(feet, high, expand);
0424 chi2Feet[high] = chi2AtSpecificStep(
0425 feet[high], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0426 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
0427 }
0428
0429 else if (chi2Feet[high] > chi2Feet[second_high]) {
0430 double worstChi2 = chi2Feet[high];
0431 ++iCalls;
0432 feet[high] = reflectFoot(feet, high, contract);
0433 chi2Feet[high] = chi2AtSpecificStep(
0434 feet[high], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0435 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
0436
0437 if (chi2Feet[high] < worstChi2) {
0438 nDimContract(feet, low);
0439 for (unsigned int iFoot = 0; iFoot < feet.size(); ++iFoot) {
0440 ++iCalls;
0441 chi2Feet[iFoot] = chi2AtSpecificStep(
0442 feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0443 lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
0444 }
0445 --iCalls;
0446 }
0447 }
0448 }
0449
0450
0451
0452 int bestFitElement = min_element(chi2Feet.begin(), chi2Feet.end()) - chi2Feet.begin();
0453
0454
0455 detailedOutput = true;
0456 chi2Feet[bestFitElement] = chi2AtSpecificStep(
0457 feet[bestFitElement], r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0458 minChi2 = chi2Feet[bestFitElement];
0459
0460 double pMag_updated = 1. / feet[bestFitElement].x();
0461 double sin_theta = sin(feet[bestFitElement].y());
0462 double cos_theta = cos(feet[bestFitElement].y());
0463 double sin_phi = sin(feet[bestFitElement].z());
0464 double cos_phi = cos(feet[bestFitElement].z());
0465
0466 double best_pX = pMag_updated * sin_theta * cos_phi;
0467 double best_pY = pMag_updated * sin_theta * sin_phi;
0468 double best_pZ = pMag_updated * cos_theta;
0469 CLHEP::Hep3Vector bestP(best_pX, best_pY, best_pZ);
0470
0471
0472 muonCandidate.momentum = bestP;
0473
0474
0475 muonCandidate.trajectoryMeasurementsInTheSet = trajectoryMeasurementsInTheSet;
0476
0477 lastUpdatedTSOS_Vect[iSet] = *(lastUpdatedTSOS_pointer[bestFitElement]);
0478
0479
0480
0481 return minChi2;
0482 }
0483
0484 double SETFilter::chi2AtSpecificStep(CLHEP::Hep3Vector &foot,
0485 const CLHEP::Hep3Vector &r3T,
0486 SeedCandidate &muonCandidate,
0487 TrajectoryStateOnSurface &lastUpdatedTSOS,
0488 Trajectory::DataContainer &trajectoryMeasurementsInTheSet,
0489 bool detailedOutput) {
0490
0491 double chi2 = 999999999999.;
0492 if (foot.x() > 0) {
0493 double pMag_updated = 1. / foot.x();
0494 double sin_theta = sin(foot.y());
0495 double cos_theta = cos(foot.y());
0496 double sin_phi = sin(foot.z());
0497 double cos_phi = cos(foot.z());
0498
0499 double pX = pMag_updated * sin_theta * cos_phi;
0500 double pY = pMag_updated * sin_theta * sin_phi;
0501 double pZ = pMag_updated * cos_theta;
0502 chi2 = findChi2(pX, pY, pZ, r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0503 }
0504 return chi2;
0505 }
0506
0507 std::vector<CLHEP::Hep3Vector> SETFilter::find3MoreStartingPoints(CLHEP::Hep3Vector &key_foot,
0508 const CLHEP::Hep3Vector &r3T,
0509 SeedCandidate &muonCandidate) {
0510
0511
0512 std::vector<CLHEP::Hep3Vector> morePoints;
0513 double invP = key_foot.x();
0514 double theta = key_foot.y();
0515 double phi = key_foot.z();
0516
0517 double deltaPhi_init = 0.005;
0518 double deltaTheta_init = 0.005;
0519
0520 double deltaInvP_init = 0.1 * invP;
0521
0522
0523
0524 bool optimized = true;
0525 if (optimized) {
0526
0527
0528
0529 TrajectoryStateOnSurface lastUpdatedTSOS;
0530 Trajectory::DataContainer trajectoryMeasurementsInTheSet;
0531 bool detailedOutput = false;
0532
0533 std::vector<double> pInv_init(3);
0534 std::vector<double> theta_init(3);
0535 std::vector<double> phi_init(3);
0536 std::vector<double> chi2_init(3);
0537
0538 pInv_init[0] = invP - deltaInvP_init;
0539 pInv_init[1] = invP;
0540 pInv_init[2] = invP + deltaInvP_init;
0541
0542
0543 theta_init[0] = theta - deltaTheta_init;
0544 theta_init[1] = theta;
0545 theta_init[2] = theta + deltaTheta_init;
0546
0547 phi_init[0] = phi - deltaPhi_init;
0548 phi_init[1] = phi;
0549 phi_init[2] = phi + deltaPhi_init;
0550
0551 double sin_theta_nom = sin(theta_init[1]);
0552 double cos_theta_nom = cos(theta_init[1]);
0553 double sin_phi_nom = sin(phi_init[1]);
0554 double cos_phi_nom = cos(phi_init[1]);
0555 double pMag_updated_nom = 1. / pInv_init[1];
0556
0557
0558 for (int i = 0; i < 3; ++i) {
0559 double pMag_updated = 1. / pInv_init[i];
0560 double pX = pMag_updated * sin_theta_nom * cos_phi_nom;
0561 double pY = pMag_updated * sin_theta_nom * sin_phi_nom;
0562 double pZ = pMag_updated * cos_theta_nom;
0563 chi2_init[i] =
0564 findChi2(pX, pY, pZ, r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0565 }
0566 std::pair<double, double> result_pInv = findParabolaMinimum(pInv_init, chi2_init);
0567
0568
0569 for (int i = 0; i < 3; ++i) {
0570 double sin_theta = sin(theta_init[i]);
0571 double cos_theta = cos(theta_init[i]);
0572 double pX = pMag_updated_nom * sin_theta * cos_phi_nom;
0573 double pY = pMag_updated_nom * sin_theta * sin_phi_nom;
0574 double pZ = pMag_updated_nom * cos_theta;
0575 chi2_init[i] =
0576 findChi2(pX, pY, pZ, r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0577 }
0578 std::pair<double, double> result_theta = findParabolaMinimum(theta_init, chi2_init);
0579
0580
0581 for (int i = 0; i < 3; ++i) {
0582 double sin_phi = sin(phi_init[i]);
0583 double cos_phi = cos(phi_init[i]);
0584 double pX = pMag_updated_nom * sin_theta_nom * cos_phi;
0585 double pY = pMag_updated_nom * sin_theta_nom * sin_phi;
0586 double pZ = pMag_updated_nom * cos_theta_nom;
0587 chi2_init[i] =
0588 findChi2(pX, pY, pZ, r3T, muonCandidate, lastUpdatedTSOS, trajectoryMeasurementsInTheSet, detailedOutput);
0589 }
0590 std::pair<double, double> result_phi = findParabolaMinimum(phi_init, chi2_init);
0591
0592
0593
0594
0595
0596
0597
0598 CLHEP::Hep3Vector foot2(invP, theta, result_phi.first);
0599 CLHEP::Hep3Vector foot3(invP, result_theta.first, phi);
0600
0601
0602
0603
0604
0605
0606 CLHEP::Hep3Vector foot4(result_pInv.first, theta, phi);
0607 morePoints.push_back(foot2);
0608 morePoints.push_back(foot3);
0609 morePoints.push_back(foot4);
0610 } else {
0611
0612 CLHEP::Hep3Vector foot2(invP, theta, phi - deltaPhi_init);
0613 CLHEP::Hep3Vector foot3(invP, theta - deltaTheta_init, phi);
0614 CLHEP::Hep3Vector foot4(invP - deltaInvP_init, theta, phi);
0615 morePoints.push_back(foot2);
0616 morePoints.push_back(foot3);
0617 morePoints.push_back(foot4);
0618 }
0619 return morePoints;
0620 }
0621
0622 std::pair<double, double> SETFilter::findParabolaMinimum(std::vector<double> &quadratic_var,
0623 std::vector<double> &quadratic_chi2) {
0624
0625
0626 double paramAtMin = -99.;
0627 std::vector<double> quadratic_param(3);
0628
0629 math::Matrix<3, 3>::type denominator;
0630 math::Matrix<3, 3>::type enumerator_1;
0631 math::Matrix<3, 3>::type enumerator_2;
0632 math::Matrix<3, 3>::type enumerator_3;
0633
0634 for (int iCol = 0; iCol < 3; ++iCol) {
0635 denominator(0, iCol) = 1;
0636 denominator(1, iCol) = quadratic_var.at(iCol);
0637 denominator(2, iCol) = pow(quadratic_var.at(iCol), 2);
0638
0639 enumerator_1(0, iCol) = quadratic_chi2.at(iCol);
0640 enumerator_1(1, iCol) = denominator(1, iCol);
0641 enumerator_1(2, iCol) = denominator(2, iCol);
0642
0643 enumerator_2(0, iCol) = denominator(0, iCol);
0644 enumerator_2(1, iCol) = quadratic_chi2.at(iCol);
0645 enumerator_2(2, iCol) = denominator(2, iCol);
0646
0647 enumerator_3(0, iCol) = denominator(0, iCol);
0648 enumerator_3(1, iCol) = denominator(1, iCol);
0649 enumerator_3(2, iCol) = quadratic_chi2.at(iCol);
0650 }
0651 const double mult = 5.;
0652 denominator *= mult;
0653 enumerator_1 *= mult;
0654 enumerator_2 *= mult;
0655 enumerator_3 *= mult;
0656
0657 std::vector<math::Matrix<3, 3>::type> enumerator;
0658 enumerator.push_back(enumerator_1);
0659 enumerator.push_back(enumerator_2);
0660 enumerator.push_back(enumerator_3);
0661
0662 double determinant = 0;
0663 denominator.Det2(determinant);
0664 if (fabs(determinant) > 0.00000000001) {
0665 for (int iPar = 0; iPar < 3; ++iPar) {
0666 double d = 0.;
0667 enumerator.at(iPar).Det2(d);
0668 quadratic_param.at(iPar) = d / determinant;
0669 }
0670 } else {
0671
0672 }
0673 if (quadratic_param.at(2) > 0) {
0674 paramAtMin = -quadratic_param.at(1) / quadratic_param.at(2) / 2;
0675 } else {
0676
0677 paramAtMin = quadratic_var.at(1);
0678 }
0679 double chi2_min =
0680 quadratic_param.at(0) + quadratic_param.at(1) * paramAtMin + quadratic_param.at(2) * pow(paramAtMin, 2);
0681 std::pair<double, double> result;
0682 result = std::make_pair(paramAtMin, chi2_min);
0683 return result;
0684 }
0685
0686 void SETFilter::pickElements(std::vector<double> &chi2Feet,
0687 unsigned int &high,
0688 unsigned int &second_high,
0689 unsigned int &low) {
0690
0691 std::vector<double> chi2Feet_tmp = chi2Feet;
0692 std::vector<double>::iterator minEl = min_element(chi2Feet.begin(), chi2Feet.end());
0693 std::vector<double>::iterator maxEl = max_element(chi2Feet.begin(), chi2Feet.end());
0694 high = maxEl - chi2Feet.begin();
0695 low = minEl - chi2Feet.begin();
0696 chi2Feet_tmp[high] = chi2Feet_tmp[low];
0697 std::vector<double>::iterator second_maxEl = max_element(chi2Feet_tmp.begin(), chi2Feet_tmp.end());
0698 second_high = second_maxEl - chi2Feet_tmp.begin();
0699
0700 return;
0701 }
0702
0703 CLHEP::Hep3Vector SETFilter::reflectFoot(std::vector<CLHEP::Hep3Vector> &feet, unsigned int key_foot, double scale) {
0704
0705 CLHEP::Hep3Vector newPosition(0., 0., 0.);
0706 if (scale == 0.5) {
0707
0708 return newPosition;
0709 }
0710 CLHEP::Hep3Vector centroid(0, 0, 0);
0711 for (unsigned int iFoot = 0; iFoot < feet.size(); ++iFoot) {
0712 if (iFoot == key_foot) {
0713 continue;
0714 }
0715 centroid += feet[iFoot];
0716 }
0717 centroid /= (feet.size() - 1);
0718 CLHEP::Hep3Vector displacement = 2. * (centroid - feet[key_foot]);
0719 newPosition = feet[key_foot] + scale * displacement;
0720 return newPosition;
0721 }
0722
0723 void SETFilter::nDimContract(std::vector<CLHEP::Hep3Vector> &feet, unsigned int low) {
0724 for (unsigned int iFoot = 0; iFoot < feet.size(); ++iFoot) {
0725
0726 if (iFoot == low) {
0727 continue;
0728 }
0729 feet[iFoot] += feet[low];
0730 feet[iFoot] /= 2.;
0731 }
0732 return;
0733 }