00001
00004 #include "RecoMuon/MuonSeedGenerator/src/SETFilter.h"
00005
00006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00007
00008
00009 #include "FWCore/Framework/interface/Event.h"
00010
00011 #include "TrackingTools/KalmanUpdators/interface/Chi2MeasurementEstimator.h"
00012
00013 #include "TrackingTools/TrajectoryState/interface/FreeTrajectoryState.h"
00014 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00015 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00016
00017 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00018 #include "TrackingTools/TrackFitters/interface/TrajectoryFitter.h"
00019
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 #include "FWCore/Utilities/interface/Exception.h"
00022
00023 #include <vector>
00024
00025 #include <iostream>
00026 #include <fstream>
00027
00028
00029 struct sorter {
00030
00031 bool operator() (TransientTrackingRecHit::ConstRecHitPointer hit_1,
00032 TransientTrackingRecHit::ConstRecHitPointer hit_2){
00033 if(hit_1->det()->subDetector() != GeomDetEnumerators::CSC ||
00034 hit_2->det()->subDetector() != GeomDetEnumerators::CSC){
00035
00036 return (hit_1->globalPosition().mag2()>hit_2->globalPosition().mag2());
00037 }
00038 else{
00039 return (fabs(hit_1->globalPosition().z())>fabs(hit_2->globalPosition().z()));
00040 }
00041 }
00042 } sortRadius;
00043
00044
00045
00046 using namespace edm;
00047 using namespace std;
00048
00049 SETFilter::SETFilter(const ParameterSet& par,
00050 const MuonServiceProxy* service)
00051 :theService(service)
00052
00053 {
00054 thePropagatorName = par.getParameter<string>("Propagator");
00055 useSegmentsInTrajectory = par.getUntrackedParameter<bool>("UseSegmentsInTrajectory");
00056 }
00057
00058 SETFilter::~SETFilter(){
00059
00060 LogTrace("Muon|RecoMuon|SETFilter")
00061 <<"SETFilter destructor called"<<endl;
00062
00063 }
00064
00065 void SETFilter::setEvent(const Event& event){
00066 }
00067
00068 void SETFilter::reset(){
00069 totalChambers = dtChambers = cscChambers = rpcChambers = 0;
00070
00071 theLastUpdatedTSOS = theLastButOneUpdatedTSOS = TrajectoryStateOnSurface();
00072
00073 theDetLayers.clear();
00074 }
00075
00076
00077 const Propagator* SETFilter::propagator() const {
00078 return &*theService->propagator(thePropagatorName);
00079 }
00080
00081
00082 void SETFilter::incrementChamberCounters(const DetLayer *layer){
00083
00084 if(layer->subDetector()==GeomDetEnumerators::DT) dtChambers++;
00085 else if(layer->subDetector()==GeomDetEnumerators::CSC) cscChambers++;
00086 else if(layer->subDetector()==GeomDetEnumerators::RPCBarrel || layer->subDetector()==GeomDetEnumerators::RPCEndcap) rpcChambers++;
00087 else
00088 LogError("Muon|RecoMuon|SETFilter")
00089 << "Unrecognized module type in incrementChamberCounters";
00090
00091
00092
00093 totalChambers++;
00094 }
00095
00096
00097 bool SETFilter::fwfit_SET(std::vector < SeedCandidate> & validSegmentsSet_in,
00098 std::vector < SeedCandidate> & validSegmentsSet_out){
00099
00100 validSegmentsSet_out.clear();
00101
00102
00103
00104
00105
00106
00107 bool validStep = true;
00108 std::vector <double> chi2AllCombinations(validSegmentsSet_in.size());
00109 std::vector < TrajectoryStateOnSurface > lastUpdatedTSOS_Vect(validSegmentsSet_in.size());
00110
00111 for(unsigned int iSet = 0; iSet<validSegmentsSet_in.size(); ++iSet){
00112
00113
00114 CLHEP::Hep3Vector origin (0.,0.,0.);
00115 Trajectory::DataContainer trajectoryMeasurementsInTheSet_tmp;
00116
00117 chi2AllCombinations[iSet] = findMinChi2(iSet, origin, validSegmentsSet_in[iSet], lastUpdatedTSOS_Vect,
00118 trajectoryMeasurementsInTheSet_tmp);
00119 }
00120
00121 std::vector < double >::iterator itMin = min_element(chi2AllCombinations.begin(),chi2AllCombinations.end());
00122
00123 int positionMin = itMin - chi2AllCombinations.begin();
00124
00125
00126 validSegmentsSet_out.push_back(validSegmentsSet_in[positionMin]);
00127
00128 return validStep;
00129 }
00130
00131
00132 bool SETFilter::buildTrajectoryMeasurements(SeedCandidate * finalMuon, Trajectory::DataContainer & finalCandidate){
00133
00134 bool validTrajectory = true;
00135
00136 reset();
00137 finalCandidate.clear();
00138
00139
00140
00141 if(finalMuon->trajectoryMeasurementsInTheSet.size() &&
00142 finalMuon->trajectoryMeasurementsInTheSet.back().forwardPredictedState().isValid()){
00143
00144 for(unsigned int iMeas =0; iMeas<finalMuon->trajectoryMeasurementsInTheSet.size();++iMeas){
00145
00146 finalCandidate.push_back(finalMuon->trajectoryMeasurementsInTheSet[iMeas]);
00147 const DetLayer *layer = finalMuon->trajectoryMeasurementsInTheSet[iMeas].layer();
00148
00149 incrementChamberCounters(layer);
00150
00151 theDetLayers.push_back(layer);
00152
00153 }
00154 theLastUpdatedTSOS = finalMuon->trajectoryMeasurementsInTheSet.at(finalMuon->trajectoryMeasurementsInTheSet.size()-1).forwardPredictedState();
00155
00156
00157 }
00158 else{
00159 validTrajectory = false;
00160
00161 }
00162 return validTrajectory;
00163 }
00164
00165
00166 bool SETFilter::transform(Trajectory::DataContainer &measurements_segments,
00167 TransientTrackingRecHit::ConstRecHitContainer & hitContainer,
00168 TrajectoryStateOnSurface & firstTSOS){
00169
00170
00171 bool success = true;
00172
00173 for(int iMeas = measurements_segments.size() - 1; iMeas>-1;--iMeas){
00174 TransientTrackingRecHit ::ConstRecHitContainer sortedHits;
00175
00176 for(unsigned int jMeas = 0; jMeas<measurements_segments[iMeas].recHit()->transientHits().size();++jMeas){
00177 if(measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size()>1){
00178
00179
00180 for(unsigned int kMeas = 0;kMeas<measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size();
00181 ++kMeas){
00182 sortedHits.push_back(
00183 measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().at(kMeas));
00184 }
00185 }
00186 else{
00187 sortedHits = measurements_segments[iMeas].recHit()->transientHits();
00188 }
00189 }
00190
00191 sort(sortedHits.begin(),sortedHits.end(),sortRadius);
00192 hitContainer.insert(hitContainer.end(),sortedHits.begin(),sortedHits.end());
00193 }
00194
00195 CLHEP::Hep3Vector p3_propagated,r3_propagated;
00196 AlgebraicSymMatrix66 cov_propagated, covT;
00197 covT *= 1e-20;
00198 cov_propagated *= 1e-20;
00199
00200 FreeTrajectoryState ftsStart = *(measurements_segments.at(measurements_segments.size()-1).forwardPredictedState().freeState());
00201
00202
00203 TransientTrackingRecHit::ConstRecHitPointer muonRecHit = hitContainer[0];
00204 DetId detId_last = hitContainer[0]->hit()->geographicalId();
00205 const GeomDet* layer_last = theService->trackingGeometry()->idToDet(detId_last);
00206 TrajectoryStateOnSurface tSOSDest;
00207
00208 tSOSDest = propagator()->propagate(ftsStart, layer_last->surface());
00209 firstTSOS = tSOSDest;
00210
00211 if (!tSOSDest.isValid()){
00212 success = false;
00213
00214 }
00215 return success;
00216 }
00217
00218 bool SETFilter::transformLight(Trajectory::DataContainer &measurements_segments,
00219 TransientTrackingRecHit::ConstRecHitContainer & hitContainer,
00220 TrajectoryStateOnSurface & firstTSOS){
00221
00222
00223 bool success = true;
00224
00225 if(useSegmentsInTrajectory){
00226
00227 for(unsigned int iMeas = 0; iMeas<measurements_segments.size();++iMeas){
00228 hitContainer.push_back(measurements_segments[iMeas].recHit());
00229 }
00230 }
00231 else{
00232 for(int iMeas = measurements_segments.size() - 1; iMeas>-1;--iMeas){
00233 hitContainer.push_back(measurements_segments[iMeas].recHit());
00234 }
00235
00236 }
00237
00238 firstTSOS = measurements_segments.at(0).forwardPredictedState();
00239 return success;
00240 }
00241
00242
00243
00244 void SETFilter::getFromFTS(const FreeTrajectoryState& fts,
00245 CLHEP::Hep3Vector& p3, CLHEP::Hep3Vector& r3,
00246 int& charge, AlgebraicSymMatrix66& cov){
00247
00248 GlobalVector p3GV = fts.momentum();
00249 GlobalPoint r3GP = fts.position();
00250
00251 p3.set(p3GV.x(), p3GV.y(), p3GV.z());
00252 r3.set(r3GP.x(), r3GP.y(), r3GP.z());
00253
00254 charge = fts.charge();
00255 cov = fts.hasError() ? fts.cartesianError().matrix() : AlgebraicSymMatrix66();
00256
00257 }
00258
00259 FreeTrajectoryState SETFilter::getFromCLHEP(const CLHEP::Hep3Vector& p3, const CLHEP::Hep3Vector& r3,
00260 int charge, const AlgebraicSymMatrix66& cov,
00261 const MagneticField* field){
00262
00263 GlobalVector p3GV(p3.x(), p3.y(), p3.z());
00264 GlobalPoint r3GP(r3.x(), r3.y(), r3.z());
00265 GlobalTrajectoryParameters tPars(r3GP, p3GV, charge, field);
00266
00267 CartesianTrajectoryError tCov(cov);
00268
00269 return cov.kRows == 6 ? FreeTrajectoryState(tPars, tCov) : FreeTrajectoryState(tPars) ;
00270 }
00271
00272 double SETFilter::findChi2(double pX, double pY, double pZ,
00273 const CLHEP::Hep3Vector& r3T,
00274 SeedCandidate & muonCandidate,
00275 TrajectoryStateOnSurface &lastUpdatedTSOS,
00276 Trajectory::DataContainer & trajectoryMeasurementsInTheSet,
00277 bool detailedOutput){
00278
00279
00280
00281
00282 if(detailedOutput){
00283 trajectoryMeasurementsInTheSet.clear();
00284 }
00285
00286 int charge = muonCandidate.charge;
00287 CLHEP::Hep3Vector p3T(pX,pY,pZ);
00288 CLHEP::Hep3Vector p3_propagated,r3_propagated;
00289 AlgebraicSymMatrix66 cov_propagated, covT;
00290 covT *= 1e-20;
00291 cov_propagated *= 1e-20;
00292
00293 FreeTrajectoryState ftsStart = getFromCLHEP(p3T, r3T, charge, covT, &*(theService->magneticField()));
00294 TrajectoryStateOnSurface tSOSDest;
00295
00296 double chi2_loc = 0.;
00297 for(unsigned int iMeas = 0; iMeas <muonCandidate.theSet.size(); ++iMeas){
00298 MuonTransientTrackingRecHit::MuonRecHitPointer muonRecHit = muonCandidate.theSet[iMeas];
00299 DetId detId = muonRecHit->hit()->geographicalId();
00300 const GeomDet* layer = theService->trackingGeometry()->idToDet(detId);
00301
00302
00303
00304
00305
00306
00307
00308 tSOSDest = propagator()->propagate(ftsStart, layer->surface());
00309 lastUpdatedTSOS = tSOSDest;
00310 if (tSOSDest.isValid()){
00311
00312 ftsStart = *tSOSDest.freeState();
00313
00314 } else{
00315
00316 chi2_loc = 9999999999.;
00317 break;
00318 }
00319
00320
00321 getFromFTS(ftsStart, p3_propagated, r3_propagated, charge, cov_propagated);
00322
00323 GlobalPoint globPos = muonRecHit->globalPosition();
00324 LocalPoint locHitPos = muonRecHit->localPosition();
00325 LocalError locHitErr = muonRecHit->localPositionError();
00326 const GlobalPoint globPropPos(r3_propagated.x(), r3_propagated.y(), r3_propagated.z());
00327 LocalPoint locPropPos = layer->toLocal(globPropPos);
00328
00329
00330
00331 CLHEP::HepMatrix dist(1,2);
00332 double chi2_intermed = -9;
00333 int ierr = 0;
00334 dist(1,1) = locPropPos.x() - locHitPos.x();
00335 dist(1,2) = locPropPos.y() - locHitPos.y();
00336 CLHEP::HepMatrix IC(2,2);
00337 IC(1,1) = locHitErr.xx();
00338 IC(2,1) = locHitErr.xy();
00339 IC(2,2) = locHitErr.yy();
00340 IC(1,2) = IC(2,1);
00341
00342
00343 if(4!=muonRecHit->hit()->dimension()){
00344 for(int iE = 1;iE<3;++iE){
00345
00346 if ( fabs(IC(iE,iE)) < 0.00000001){
00347 IC(iE,iE) = 62500./12.;
00348 }
00349 }
00350 }
00351
00352 IC.invert(ierr);
00353
00354
00355
00356 chi2_intermed = 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);
00357 if(chi2_intermed<0){
00358 chi2_intermed = 9999999999.;
00359 }
00360 chi2_loc += chi2_intermed;
00361
00362
00363 if(detailedOutput){
00364 DetId detId = muonRecHit->hit()->geographicalId();
00365 const DetLayer *layer = theService->detLayerGeometry()->idToLayer( detId);
00366
00367
00368 trajectoryMeasurementsInTheSet.push_back( TrajectoryMeasurement
00369 ( lastUpdatedTSOS,
00370 muonRecHit.get(),
00371 chi2_intermed,
00372 layer ) );
00373 }
00374 }
00375 return chi2_loc;
00376 }
00377
00378 double SETFilter::findMinChi2(unsigned int iSet, const CLHEP::Hep3Vector& r3T,
00379 SeedCandidate & muonCandidate,
00380 std::vector < TrajectoryStateOnSurface > &lastUpdatedTSOS_Vect,
00381 Trajectory::DataContainer & trajectoryMeasurementsInTheSet){
00382
00383
00384
00385
00386
00387 bool detailedOutput = false;
00388
00389 double cosTheta = muonCandidate.momentum.cosTheta();
00390 double theta = acos(cosTheta);
00391 double phi = muonCandidate.momentum.phi();
00392 double pMag = muonCandidate.momentum.mag();
00393
00394 double minChi2 = -999.;
00395 TrajectoryStateOnSurface lastUpdatedTSOS;
00396
00397
00398
00399 if(pMag<5.){
00400 pMag = 5.;
00401 }
00402
00403 pMag *=1.2;
00404 double invP = 1./pMag;
00405
00406
00407
00408
00409
00410
00411 const double reflect = 1;
00412 const double expand = -0.5;
00413 const double contract = 0.25;
00414
00415 const int nDim = 3;
00416
00417 std::vector <CLHEP::Hep3Vector> feet(nDim+1);
00418 std::vector <double> chi2Feet(nDim+1);
00419 std::vector <TrajectoryStateOnSurface*> lastUpdatedTSOS_pointer(nDim+1);
00420
00421
00422
00423 CLHEP::Hep3Vector foot1(invP, theta, phi);
00424 feet[0] = foot1;
00425 chi2Feet[0] = chi2AtSpecificStep(feet[0], r3T, muonCandidate, lastUpdatedTSOS,
00426 trajectoryMeasurementsInTheSet, detailedOutput);
00427 lastUpdatedTSOS_pointer[0] = &lastUpdatedTSOS;
00428
00429 std::vector <CLHEP::Hep3Vector> morePoints =
00430 find3MoreStartingPoints(feet[0], r3T, muonCandidate);
00431 feet[1] = morePoints[0];
00432 feet[2] = morePoints[1];
00433 feet[3] = morePoints[2];
00434
00435
00436 for(unsigned int iFoot = 1; iFoot<feet.size();++iFoot){
00437
00438 chi2Feet[iFoot] = chi2AtSpecificStep(feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS,
00439 trajectoryMeasurementsInTheSet, detailedOutput);
00440 lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
00441 }
00442
00443 unsigned int high, second_high, low;
00444
00445 int iCalls = 0;
00446
00447 while(iCalls<3.){
00448
00449 pickElements(chi2Feet, high, second_high, low);
00450 ++iCalls;
00451 feet[high] = reflectFoot(feet, high, reflect );
00452 chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
00453 trajectoryMeasurementsInTheSet, detailedOutput);
00454 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
00455
00456 if(chi2Feet[high] <chi2Feet[low]){
00457 ++iCalls;
00458 feet[high] = reflectFoot(feet, high, expand);
00459 chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
00460 trajectoryMeasurementsInTheSet, detailedOutput);
00461 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
00462 }
00463
00464 else if( chi2Feet[high] > chi2Feet[second_high]){
00465 double worstChi2 = chi2Feet[high];
00466 ++iCalls;
00467 feet[high] = reflectFoot(feet, high, contract);
00468 chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
00469 trajectoryMeasurementsInTheSet, detailedOutput);
00470 lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
00471
00472 if(chi2Feet[high] <worstChi2){
00473 nDimContract(feet, low);
00474 for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
00475 ++iCalls;
00476 chi2Feet[iFoot] = chi2AtSpecificStep(feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS,
00477 trajectoryMeasurementsInTheSet, detailedOutput);
00478 lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
00479 }
00480 --iCalls;
00481 }
00482 }
00483 }
00484
00485
00486
00487 int bestFitElement = min_element(chi2Feet.begin(),chi2Feet.end()) - chi2Feet.begin();
00488
00489
00490 detailedOutput = true;
00491 chi2Feet[bestFitElement] = chi2AtSpecificStep(feet[bestFitElement], r3T, muonCandidate, lastUpdatedTSOS,
00492 trajectoryMeasurementsInTheSet, detailedOutput);
00493 minChi2 = chi2Feet[bestFitElement];
00494
00495 double pMag_updated = 1./feet[bestFitElement].x();
00496 double sin_theta = sin(feet[bestFitElement].y());
00497 double cos_theta = cos(feet[bestFitElement].y());
00498 double sin_phi = sin(feet[bestFitElement].z());
00499 double cos_phi = cos(feet[bestFitElement].z());
00500
00501 double best_pX = pMag_updated*sin_theta*cos_phi;
00502 double best_pY = pMag_updated*sin_theta*sin_phi;
00503 double best_pZ = pMag_updated*cos_theta;
00504 CLHEP::Hep3Vector bestP(best_pX, best_pY, best_pZ);
00505
00506
00507 muonCandidate.momentum = bestP;
00508
00509
00510 muonCandidate.trajectoryMeasurementsInTheSet = trajectoryMeasurementsInTheSet;
00511
00512 lastUpdatedTSOS_Vect[iSet]= *(lastUpdatedTSOS_pointer[bestFitElement]);
00513
00514
00515
00516 return minChi2;
00517 }
00518
00519 double SETFilter::
00520 chi2AtSpecificStep(CLHEP::Hep3Vector &foot,
00521 const CLHEP::Hep3Vector& r3T,
00522 SeedCandidate & muonCandidate,
00523 TrajectoryStateOnSurface &lastUpdatedTSOS,
00524 Trajectory::DataContainer & trajectoryMeasurementsInTheSet,
00525 bool detailedOutput){
00526
00527 double chi2 = 999999999999.;
00528 if(foot.x()>0){
00529 double pMag_updated = 1./foot.x();
00530 double sin_theta = sin(foot.y());
00531 double cos_theta = cos(foot.y());
00532 double sin_phi = sin(foot.z());
00533 double cos_phi = cos(foot.z());
00534
00535 double pX = pMag_updated*sin_theta*cos_phi;
00536 double pY = pMag_updated*sin_theta*sin_phi;
00537 double pZ = pMag_updated*cos_theta;
00538 chi2 = findChi2(pX, pY, pZ, r3T,
00539 muonCandidate, lastUpdatedTSOS,
00540 trajectoryMeasurementsInTheSet, detailedOutput);
00541 }
00542 return chi2;
00543 }
00544
00545 std::vector <CLHEP::Hep3Vector> SETFilter::
00546 find3MoreStartingPoints(CLHEP::Hep3Vector &key_foot,
00547 const CLHEP::Hep3Vector& r3T,
00548 SeedCandidate & muonCandidate){
00549
00550
00551 std::vector <CLHEP::Hep3Vector> morePoints;
00552 double invP = key_foot.x();
00553 double theta = key_foot.y();
00554 double phi = key_foot.z();
00555
00556
00557 double deltaPhi_init = 0.005;
00558 double deltaTheta_init = 0.005;
00559
00560 double deltaInvP_init = 0.1 * invP;
00561
00562
00563
00564 bool optimized = true;
00565 if(optimized){
00566
00567
00568
00569 TrajectoryStateOnSurface lastUpdatedTSOS;
00570 Trajectory::DataContainer trajectoryMeasurementsInTheSet;
00571 bool detailedOutput = false;
00572
00573
00574 std::vector < double > pInv_init(3);
00575 std::vector < double > theta_init(3);
00576 std::vector < double > phi_init(3);
00577 std::vector < double > chi2_init(3);
00578
00579 pInv_init[0] = invP - deltaInvP_init;
00580 pInv_init[1] = invP;
00581 pInv_init[2] = invP + deltaInvP_init;
00582
00583
00584 theta_init[0] = theta-deltaTheta_init;
00585 theta_init[1] = theta;
00586 theta_init[2] = theta+deltaTheta_init;
00587
00588 phi_init[0] = phi-deltaPhi_init;
00589 phi_init[1] = phi;
00590 phi_init[2] = phi+deltaPhi_init;
00591
00592 double sin_theta_nom = sin(theta_init[1]);
00593 double cos_theta_nom = cos(theta_init[1]);
00594 double sin_phi_nom = sin(phi_init[1]);
00595 double cos_phi_nom = cos(phi_init[1]);
00596 double pMag_updated_nom = 1./pInv_init[1];
00597
00598
00599 for(int i=0;i<3;++i){
00600 double pMag_updated = 1./pInv_init[i];
00601 double pX = pMag_updated*sin_theta_nom*cos_phi_nom;
00602 double pY = pMag_updated*sin_theta_nom*sin_phi_nom;
00603 double pZ = pMag_updated*cos_theta_nom;
00604 chi2_init[i] = findChi2(pX, pY, pZ, r3T,
00605 muonCandidate, lastUpdatedTSOS,
00606 trajectoryMeasurementsInTheSet, detailedOutput);
00607 }
00608 std::pair <double,double> result_pInv =
00609 findParabolaMinimum(pInv_init, chi2_init);
00610
00611
00612 for(int i=0;i<3;++i){
00613 double sin_theta = sin(theta_init[i]);
00614 double cos_theta = cos(theta_init[i]);
00615 double pX = pMag_updated_nom*sin_theta*cos_phi_nom;
00616 double pY = pMag_updated_nom*sin_theta*sin_phi_nom;
00617 double pZ = pMag_updated_nom*cos_theta;
00618 chi2_init[i] = findChi2(pX, pY, pZ, r3T,
00619 muonCandidate, lastUpdatedTSOS,
00620 trajectoryMeasurementsInTheSet, detailedOutput);
00621 }
00622 std::pair <double,double> result_theta =
00623 findParabolaMinimum(theta_init, chi2_init);
00624
00625
00626 for(int i=0;i<3;++i){
00627 double sin_phi = sin(phi_init[i]);
00628 double cos_phi = cos(phi_init[i]);
00629 double pX = pMag_updated_nom*sin_theta_nom*cos_phi;
00630 double pY = pMag_updated_nom*sin_theta_nom*sin_phi;
00631 double pZ = pMag_updated_nom*cos_theta_nom;
00632 chi2_init[i] = findChi2(pX, pY, pZ, r3T,
00633 muonCandidate, lastUpdatedTSOS,
00634 trajectoryMeasurementsInTheSet, detailedOutput);
00635 }
00636 std::pair <double,double> result_phi =
00637 findParabolaMinimum(phi_init, chi2_init);
00638
00639 double newPhi = result_phi.first;
00640 if(fabs(newPhi - phi)<0.02){
00641 newPhi = phi + 0.02;
00642 }
00643 CLHEP::Hep3Vector foot2(invP, theta, result_phi.first);
00644 CLHEP::Hep3Vector foot3(invP, result_theta.first , phi);
00645 double newInvP = result_pInv.first;
00646 if(fabs(newInvP - invP)<0.001){
00647 newInvP = invP + 0.001;
00648 }
00649 CLHEP::Hep3Vector foot4(result_pInv.first, theta, phi);
00650 morePoints.push_back(foot2);
00651 morePoints.push_back(foot3);
00652 morePoints.push_back(foot4);
00653 }
00654 else{
00655
00656 CLHEP::Hep3Vector foot2(invP, theta, phi-deltaPhi_init);
00657 CLHEP::Hep3Vector foot3(invP, theta-deltaTheta_init, phi);
00658 CLHEP::Hep3Vector foot4(invP-deltaInvP_init, theta, phi);
00659 morePoints.push_back(foot2);
00660 morePoints.push_back(foot3);
00661 morePoints.push_back(foot4);
00662 }
00663 return morePoints;
00664 }
00665
00666 std::pair <double,double> SETFilter::findParabolaMinimum(std::vector <double> &quadratic_var,
00667 std::vector <double> &quadratic_chi2){
00668
00669
00670
00671 double paramAtMin = -99.;
00672 std::vector <double> quadratic_param(3);
00673
00674 CLHEP::HepMatrix denominator(3,3);
00675 CLHEP::HepMatrix enumerator_1(3,3);
00676 CLHEP::HepMatrix enumerator_2(3,3);
00677 CLHEP::HepMatrix enumerator_3(3,3);
00678
00679 for(int iCol=1;iCol<4;++iCol){
00680 denominator(1,iCol) = 1;
00681 denominator(2,iCol) = quadratic_var.at(iCol-1);
00682 denominator(3,iCol) = pow(quadratic_var.at(iCol-1),2);
00683
00684 enumerator_1(1,iCol) = quadratic_chi2.at(iCol-1);
00685 enumerator_1(2,iCol) = denominator(2,iCol);
00686 enumerator_1(3,iCol) = denominator(3,iCol);
00687
00688 enumerator_2(1,iCol) = denominator(1,iCol);
00689 enumerator_2(2,iCol) = quadratic_chi2.at(iCol-1);
00690 enumerator_2(3,iCol) = denominator(3,iCol);
00691
00692 enumerator_3(1,iCol) = denominator(1,iCol);
00693 enumerator_3(2,iCol) = denominator(2,iCol);
00694 enumerator_3(3,iCol) = quadratic_chi2.at(iCol-1);
00695 }
00696 const double mult = 5.;
00697 denominator *=mult;
00698 enumerator_1*=mult;
00699 enumerator_2*=mult;
00700 enumerator_3*=mult;
00701
00702 std::vector <CLHEP::HepMatrix> enumerator;
00703 enumerator.push_back(enumerator_1);
00704 enumerator.push_back(enumerator_2);
00705 enumerator.push_back(enumerator_3);
00706
00707 double determinant = denominator.determinant();
00708 if(fabs(determinant)>0.00000000001){
00709 for(int iPar=0;iPar<3;++iPar){
00710 quadratic_param.at(iPar) = enumerator.at(iPar).determinant()/determinant;
00711 }
00712 }
00713 else{
00714
00715 }
00716 if(quadratic_param.at(2)>0){
00717 paramAtMin = - quadratic_param.at(1)/quadratic_param.at(2)/2;
00718 }
00719 else {
00720
00721 paramAtMin = quadratic_var.at(1);
00722 }
00723 double chi2_min = quadratic_param.at(0) + quadratic_param.at(1)*paramAtMin + quadratic_param.at(2)*pow(paramAtMin,2);
00724 std::pair <double, double> result;
00725 result = std::make_pair ( paramAtMin, chi2_min);
00726 return result;
00727 }
00728
00729 void SETFilter::pickElements(std::vector <double> &chi2Feet,
00730 unsigned int & high, unsigned int & second_high, unsigned int & low){
00731
00732 std::vector <double> chi2Feet_tmp = chi2Feet;
00733 std::vector <double>::iterator minEl = min_element(chi2Feet.begin(), chi2Feet.end());
00734 std::vector <double>::iterator maxEl = max_element(chi2Feet.begin(), chi2Feet.end());
00735 high = maxEl - chi2Feet.begin();
00736 low = minEl - chi2Feet.begin();
00737 chi2Feet_tmp[high] = chi2Feet_tmp[low];
00738 std::vector <double>::iterator second_maxEl = max_element(chi2Feet_tmp.begin(), chi2Feet_tmp.end());
00739 second_high = second_maxEl - chi2Feet_tmp.begin();
00740
00741 return;
00742 }
00743
00744 CLHEP::Hep3Vector SETFilter::reflectFoot(std::vector <CLHEP::Hep3Vector> & feet,
00745 unsigned int key_foot, double scale ){
00746
00747 CLHEP::Hep3Vector newPosition(0.,0.,0.);
00748 if(scale==0.5){
00749
00750 return newPosition;
00751 }
00752 CLHEP::Hep3Vector centroid(0,0,0);
00753 for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
00754 if(iFoot==key_foot){
00755 continue;
00756 }
00757 centroid += feet[iFoot];
00758 }
00759 centroid/=(feet.size()-1);
00760 CLHEP::Hep3Vector displacement = 2.*(centroid - feet[key_foot]);
00761 newPosition = feet[key_foot] + scale * displacement;
00762 return newPosition;
00763 }
00764
00765 void SETFilter::nDimContract(std::vector <CLHEP::Hep3Vector> & feet, unsigned int low){
00766 for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
00767
00768 if(iFoot==low){
00769 continue;
00770 }
00771 feet[iFoot] += feet[low];
00772 feet[iFoot] /=2.;
00773 }
00774 return;
00775 }