CMS 3D CMS Logo

SETFilter.cc
Go to the documentation of this file.
1 
5 
7 
8 // FIXME: remove this
10 
12 
16 
19 
22 
24 
25 #include <vector>
26 
27 #include <iostream>
28 #include <fstream>
29 
30 // there is an existing sorter somewhere in the CMSSW code (I think) - delete that
31 struct sorter {
32  //bigger first!
33  sorter() {}
36  if(hit_1->det()->subDetector() != GeomDetEnumerators::CSC ||
37  hit_2->det()->subDetector() != GeomDetEnumerators::CSC){
38  // this is a piculiar "fix" for CSCs
39  return (hit_1->globalPosition().mag2()>hit_2->globalPosition().mag2());
40  }
41  else{
42  return (fabs(hit_1->globalPosition().z())>fabs(hit_2->globalPosition().z()));
43  }
44  }
45 } const sortRadius;// bigger first
46 
47 
48 
49 using namespace edm;
50 using namespace std;
51 
54  :theService(service)//,
55  //theOverlappingChambersFlag(true)
56 {
57  thePropagatorName = par.getParameter<string>("Propagator");
58  useSegmentsInTrajectory = par.getUntrackedParameter<bool>("UseSegmentsInTrajectory");
59 }
60 
62 
63  LogTrace("Muon|RecoMuon|SETFilter")
64  <<"SETFilter destructor called"<<endl;
65 
66 }
67 
69 }
70 
73 
75 
76  theDetLayers.clear();
77 }
78 
79 
81  return &*theService->propagator(thePropagatorName);
82 }
83 
84 
86 
88  else if(layer->subDetector()==GeomDetEnumerators::CSC) cscChambers++;
90  else
91  LogError("Muon|RecoMuon|SETFilter")
92  << "Unrecognized module type in incrementChamberCounters";
93  // FIXME:
94  // << layer->module() << " " <<layer->Part() << endl;
95 
96  totalChambers++;
97 }
98 
99 //---- the SET FW-fitter within a cluster
100 bool SETFilter::fwfit_SET(std::vector < SeedCandidate> & validSegmentsSet_in,
101  std::vector < SeedCandidate> & validSegmentsSet_out){
102  // this is the SET algorithm fit
103  validSegmentsSet_out.clear();
104 
105  //---- It is supposed to be called within a loop over "segment clusters";
106  //---- so std::vector < SeedCandidate> consists of "valid" combinations (sets) within a "cluster"
107  //---- "seed" above has nothing to do with the "Seed" in the STA code
108 
109  // a trajectory is not really build but a TSOS is build and is checked (below)
110  bool validStep = true;
111  std::vector <double> chi2AllCombinations(validSegmentsSet_in.size());
112  std::vector < TrajectoryStateOnSurface > lastUpdatedTSOS_Vect(validSegmentsSet_in.size());
113  // loop over all valid sets
114  for(unsigned int iSet = 0; iSet<validSegmentsSet_in.size(); ++iSet){
115  //std::cout<<" iSET = "<<iSet<<std::endl;
116  //---- start fit from the origin
117  CLHEP::Hep3Vector origin (0.,0.,0.);
118  Trajectory::DataContainer trajectoryMeasurementsInTheSet_tmp;
119  //---- Find minimum chi2 (corresponding to a specific 3D-momentum)
120  chi2AllCombinations[iSet] = findMinChi2(iSet, origin, validSegmentsSet_in[iSet], lastUpdatedTSOS_Vect,
121  trajectoryMeasurementsInTheSet_tmp);
122  }
123  //---- Find the best muon candidate (min chi2) in the cluster; find more candidates?
124  std::vector < double >::iterator itMin = min_element(chi2AllCombinations.begin(),chi2AllCombinations.end());
125 
126  int positionMin = itMin - chi2AllCombinations.begin();
127 
128  // "the best" set; have to find reasonable conditions to include more than one set
129  validSegmentsSet_out.push_back(validSegmentsSet_in[positionMin]);
130 
131  return validStep;
132 }
133 
134 //---- the SET FW-fitter
136  // this is the SET algorithm fit
137  bool validTrajectory = true;
138  // reset the fitter
139  reset(); // the layer counters
140  finalCandidate.clear();
141 
142  //---- Check if (only last?) TSOS is valid and build a trajectory (for the backward filter)
143 
144  if(!finalMuon->trajectoryMeasurementsInTheSet.empty() &&
145  finalMuon->trajectoryMeasurementsInTheSet.back().forwardPredictedState().isValid()){
146  // loop over all measurements in the set
147  for(unsigned int iMeas =0; iMeas<finalMuon->trajectoryMeasurementsInTheSet.size();++iMeas){
148  // strore the measurements
149  finalCandidate.push_back(finalMuon->trajectoryMeasurementsInTheSet[iMeas]);
150  const DetLayer *layer = finalMuon->trajectoryMeasurementsInTheSet[iMeas].layer();
151 
153 
154  theDetLayers.push_back(layer);
155 
156  }
158  //std::cout<<" THE OUTPUT FROM FW FILTER: |P| = "<<finalMuon->momentum.mag()<<
159  //" theta = "<<finalMuon->momentum.theta()<<" phi = "<<finalMuon->momentum.phi()<<std::endl;
160  }
161  else{
162  validTrajectory = false;
163  //std::cout<<" TSOS not valid; no trajectory build"<<std::endl;
164  }
165  return validTrajectory;
166 }
167 
168 //
169 bool SETFilter::transform(Trajectory::DataContainer &measurements_segments,
171  TrajectoryStateOnSurface & firstTSOS){
172  // transforms "segment trajectory" to "rechit container"
173  //sort(measurements_segments.begin(),measurements_segments.end(),sortRadius);
174  bool success = true;
175  // loop over all segments in the trajectory
176  for(int iMeas = measurements_segments.size() - 1; iMeas>-1;--iMeas){
178  // loop over the rechits contained in the segments
179  for(unsigned int jMeas = 0; jMeas<measurements_segments[iMeas].recHit()->transientHits().size();++jMeas){
180  if(measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size()>1){
181  // loop over the rechits contained in the rechits contained in the segments (OK, OK - this is for DT only;
182  // the convention there is a bit different from the CSCs)
183  for(unsigned int kMeas = 0;kMeas<measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().size();
184  ++kMeas){
185  sortedHits.push_back(
186  measurements_segments[iMeas].recHit()->transientHits().at(jMeas)->transientHits().at(kMeas));
187  }
188  }
189  else{
190  sortedHits = measurements_segments[iMeas].recHit()->transientHits();
191  }
192  }
193  // sort the rechits by radius (or z) and put them in a container
194  sort(sortedHits.begin(),sortedHits.end(),sortRadius);
195  hitContainer.insert(hitContainer.end(),sortedHits.begin(),sortedHits.end());
196  }
197 
198  // this is the last segment state
199  FreeTrajectoryState ftsStart = *(measurements_segments.at(measurements_segments.size()-1).forwardPredictedState().freeState());
200 
201  // this is the last (from the IP) rechit
202  TransientTrackingRecHit::ConstRecHitPointer muonRecHit = hitContainer[0];
203  DetId detId_last = hitContainer[0]->hit()->geographicalId();
204  const GeomDet* layer_last = theService->trackingGeometry()->idToDet(detId_last);
205 
206  // get the last rechit TSOS
207  TrajectoryStateOnSurface tSOSDest = propagator()->propagate(ftsStart, layer_last->surface());
208  firstTSOS = tSOSDest;
209  // ftsStart should be at the last rechit surface
210  if (!tSOSDest.isValid()){
211  success = false;
212  // ftsStart = *tSOSDest.freeState();
213  }
214  return success;
215 }
216 
219  TrajectoryStateOnSurface & firstTSOS){
220  // transforms "segment trajectory" to "segment container"
221 
222  bool success = true;
223  // loop over all segments in the trajectory
224  if(useSegmentsInTrajectory){// if segments the "backword fit" (rechits)
225  // performed later is actually a forward one (?!)
226  for(unsigned int iMeas = 0; iMeas<measurements_segments.size();++iMeas){
227  hitContainer.push_back(measurements_segments[iMeas].recHit());
228  }
229  }
230  else{
231  for(int iMeas = measurements_segments.size() - 1; iMeas>-1;--iMeas){
232  hitContainer.push_back(measurements_segments[iMeas].recHit());
233  }
234 
235  }
236  // this is the last segment state
237  firstTSOS = measurements_segments.at(0).forwardPredictedState();
238  return success;
239 }
240 
241 
242 double SETFilter::findChi2(double pX, double pY, double pZ,
243  const CLHEP::Hep3Vector& r3T,
244  SeedCandidate & muonCandidate,
246  Trajectory::DataContainer & trajectoryMeasurementsInTheSet,
247  bool detailedOutput){
248  //---- actual chi2 calculations; only the measurement error is taken into accout!
249  //---- chi2 is to compare an extrapolated point to various measurements so
250  //---- the extrapolation error is not an issue (is it?)
251 
252  if(detailedOutput){
253  trajectoryMeasurementsInTheSet.clear();
254  }
255 
256  int charge = muonCandidate.charge;
257  GlobalVector p3GV(pX,pY,pZ);
258  GlobalPoint r3GP(r3T.x(), r3T.y(), r3T.z());
259  //---- how to disable error propagation?
260  // VI: just not set it!
261  FreeTrajectoryState ftsStart(r3GP, p3GV, charge, &*(theService->magneticField()));
262  // VI let's be backward compatible...
263  if(detailedOutput) {
264  AlgebraicSymMatrix55 cov; cov*=1e-20;
265  ftsStart.setCurvilinearError(cov);
266  }
267  TrajectoryStateOnSurface tSOSDest;
268 
269  double chi2_loc = 0.;
270  for(unsigned int iMeas = 0; iMeas <muonCandidate.theSet.size(); ++iMeas){
271  MuonTransientTrackingRecHit::MuonRecHitPointer muonRecHit = muonCandidate.theSet[iMeas];
272  DetId detId = muonRecHit->hit()->geographicalId();
273  const GeomDet* layer = theService->trackingGeometry()->idToDet(detId);
274 
275  //---- propagate the muon starting from position r3T and momentum p3T
276 
277  // bool radX0CorrectionMode_ = false; // not needed here?
278  //if (radX0CorrectionMode_ ){
279  //} else {
280 
281  tSOSDest = propagator()->propagate(ftsStart, layer->surface());
282  lastUpdatedTSOS = tSOSDest;
283  if (tSOSDest.isValid()){
284  //---- start next step ("adding" measurement) from the last TSOS
285  ftsStart = *tSOSDest.freeState();
286  } else{
287  //std::cout<<"... not valid TSOS"<<std::endl;
288  chi2_loc = 9999999999.;
289  break;
290  }
291  //}
292 
293  LocalPoint locHitPos = muonRecHit->localPosition();
294  LocalError locHitErr = muonRecHit->localPositionError();
295  const GlobalPoint globPropPos = ftsStart.position();
296  LocalPoint locPropPos = layer->toLocal(globPropPos);
297 
298  //
299  //---- chi2 calculated in local system; correlation taken into accont
300  CLHEP::HepMatrix dist(1,2);//, distT(2,1);
301  double chi2_intermed = -9;
302  int ierr = 0;
303  dist(1,1) = locPropPos.x() - locHitPos.x();
304  dist(1,2) = locPropPos.y() - locHitPos.y();
305  CLHEP::HepMatrix IC(2,2);
306  IC(1,1) = locHitErr.xx();
307  IC(2,1) = locHitErr.xy();
308  IC(2,2) = locHitErr.yy();
309  IC(1,2) = IC(2,1);
310 
311  //---- Special care is needed for "1-dim measurements" (RPCs, outer DT(?))
312  if(4!=muonRecHit->hit()->dimension()){
313  for(int iE = 1;iE<3;++iE){
314  // this is bellow is a DT fix; hopefully it will not be needed
315  if ( fabs(IC(iE,iE)) < 0.00000001){
316  IC(iE,iE) = 62500./12.;// error squared - ( 250 cm /sqrt(12) )^2; large
317  }
318  }
319  }
320  //---- Invert covariance matrix
321  IC.invert(ierr);
322  //if (ierr != 0) {
323  //std::cout << "failed to invert covariance matrix (2x2) =\n" << IC << std::endl;;
324  //}
325  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);
326  if(chi2_intermed<0){// should we check?
327  chi2_intermed = 9999999999.;
328  }
329  chi2_loc += chi2_intermed;
330 
331  // that's for the last call; we don't need to construct a TrajectoryMeasurement at every chi2 step
332  if(detailedOutput){
333  DetId detId = muonRecHit->hit()->geographicalId();
334  const DetLayer *layer = theService->detLayerGeometry()->idToLayer( detId);
335  //std::cout<<" seg pos in traj : "<<lastUpdatedTSOS.globalPosition()<<std::endl;
336  // put the measurement into the set
337  // VI set the error as the fit needs it... (it is nonsense anyhow...)
338  // (do it on the tsos)
339  /*
340  if (!lastUpdatedTSOS.hasError()){
341  AlgebraicSymMatrix55 cov; cov*=1e6;
342  lastUpdatedTSOS.freeTrajectoryState().setCurvilinearError(cov);
343  }
344  */
345  trajectoryMeasurementsInTheSet.push_back( TrajectoryMeasurement
346  ( lastUpdatedTSOS,
347  muonRecHit,
348  chi2_intermed,
349  layer ) );
350  }
351  }
352  return chi2_loc;
353 }
354 
355 double SETFilter::findMinChi2(unsigned int iSet, const CLHEP::Hep3Vector& r3T,
356  SeedCandidate & muonCandidate,
357  std::vector < TrajectoryStateOnSurface > &lastUpdatedTSOS_Vect,// delete
358  Trajectory::DataContainer & trajectoryMeasurementsInTheSet){
359  // a chi2 minimization procedure
360 
361  //---- Which three variables to use?
362  //---- (1/|P|, theta, phi) ? in that case many sin() and cos() operations :-/
363  //---- maybe vary directly sin() and cos()?
364  bool detailedOutput = false;
365 
366  double cosTheta = muonCandidate.momentum.cosTheta();
367  double theta = acos(cosTheta);
368  double phi = muonCandidate.momentum.phi();
369  double pMag = muonCandidate.momentum.mag();
370 
371  double minChi2 = -999.;
373 
374  //---- Fit Parameters
375 
376  if(pMag<5.){// hardcoded - remove it! same in SETSeedFinder
377  pMag = 5.;// GeV
378  }
379  //---- This offset helps the minimization to go faster (in the specific case)
380  pMag *=1.2;
381  double invP = 1./pMag;
382  //std::cout<<" INIT pMag = "<<pMag<<" invP = "<<invP<<" theta = "<<theta<<" phi = "<<phi<<std::endl;
383 
384  //---- apply downhill SIMPLEX minimization (also "amoeba" method; thus the "feet" below are amoeba's feet)
385 
386  //std::cout<<" SIMPLEX minimization"<<std::endl;
387  //---- parameters ; the should be hardcoded
388  const double reflect = 1;
389  const double expand = -0.5;
390  const double contract = 0.25;
391 
392  const int nDim = 3; // invP, theta, phi
393  //---- Now choose nDim + 1 points
394  std::vector <CLHEP::Hep3Vector> feet(nDim+1);
395  std::vector <double> chi2Feet(nDim+1);
396  std::vector <TrajectoryStateOnSurface*> lastUpdatedTSOS_pointer(nDim+1);// probably not needed; to be deleted
397 
398  //---- The minimization procedure strats from these nDim+1 points (feet)
399 
400  CLHEP::Hep3Vector foot1(invP, theta, phi);// well obviuosly it is not a real Hep3Vector; better change it to a simple vector
401  feet[0] = foot1;
402  chi2Feet[0] = chi2AtSpecificStep(feet[0], r3T, muonCandidate, lastUpdatedTSOS,
403  trajectoryMeasurementsInTheSet, detailedOutput);
404  lastUpdatedTSOS_pointer[0] = &lastUpdatedTSOS;
405 
406  std::vector <CLHEP::Hep3Vector> morePoints =
407  find3MoreStartingPoints(feet[0], r3T, muonCandidate);
408  feet[1] = morePoints[0];
409  feet[2] = morePoints[1];
410  feet[3] = morePoints[2];
411 
412  //--- SIMPLEX initial step(s)
413  for(unsigned int iFoot = 1; iFoot<feet.size();++iFoot){
414 
415  chi2Feet[iFoot] = chi2AtSpecificStep(feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS,
416  trajectoryMeasurementsInTheSet, detailedOutput);
417  lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
418  }
419 
420  unsigned int high, second_high, low;
421  //const unsigned int iterations = 1;//---- to be replaced by something better
422  int iCalls = 0;
423  //for(unsigned int iIt = 0;iIt<iterations;++iIt){
424  while(iCalls<3.){
425  //---- SIMPLEX step 1
426  pickElements(chi2Feet, high, second_high, low);
427  ++iCalls;
428  feet[high] = reflectFoot(feet, high, reflect );
429  chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
430  trajectoryMeasurementsInTheSet, detailedOutput);
431  lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
432  //---- SIMPLEX step 2.1
433  if(chi2Feet[high] <chi2Feet[low]){
434  ++iCalls;
435  feet[high] = reflectFoot(feet, high, expand);
436  chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
437  trajectoryMeasurementsInTheSet, detailedOutput);
438  lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
439  }
440  //---- SIMPLEX step 2.2
441  else if( chi2Feet[high] > chi2Feet[second_high]){
442  double worstChi2 = chi2Feet[high];
443  ++iCalls;
444  feet[high] = reflectFoot(feet, high, contract);
445  chi2Feet[high] = chi2AtSpecificStep(feet[high], r3T, muonCandidate, lastUpdatedTSOS,
446  trajectoryMeasurementsInTheSet, detailedOutput);
447  lastUpdatedTSOS_pointer[high] = &lastUpdatedTSOS;
448  //---- SIMPLEX step 2.2.1
449  if(chi2Feet[high] <worstChi2){
450  nDimContract(feet, low);
451  for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
452  ++iCalls;
453  chi2Feet[iFoot] = chi2AtSpecificStep(feet[iFoot], r3T, muonCandidate, lastUpdatedTSOS,
454  trajectoryMeasurementsInTheSet, detailedOutput);
455  lastUpdatedTSOS_pointer[iFoot] = &lastUpdatedTSOS;
456  }
457  --iCalls;// one of the above is not changed
458  }
459  }
460  }
461  //---- Here the SIMPLEX minimization ends
462 
463  // this is the minimum found
464  int bestFitElement = min_element(chi2Feet.begin(),chi2Feet.end()) - chi2Feet.begin();
465 
466  //---- repeat to get the trajectoryMeasurementsInTheSet (optimize?)
467  detailedOutput = true;
468  chi2Feet[bestFitElement] = chi2AtSpecificStep(feet[bestFitElement], r3T, muonCandidate, lastUpdatedTSOS,
469  trajectoryMeasurementsInTheSet, detailedOutput);
470  minChi2 = chi2Feet[bestFitElement];
471 
472  double pMag_updated = 1./feet[bestFitElement].x();
473  double sin_theta = sin(feet[bestFitElement].y());
474  double cos_theta = cos(feet[bestFitElement].y());
475  double sin_phi = sin(feet[bestFitElement].z());
476  double cos_phi = cos(feet[bestFitElement].z());
477 
478  double best_pX = pMag_updated*sin_theta*cos_phi;
479  double best_pY = pMag_updated*sin_theta*sin_phi;
480  double best_pZ = pMag_updated*cos_theta;
481  CLHEP::Hep3Vector bestP(best_pX, best_pY, best_pZ);
482  //---- update the best momentum estimate
483  //if(minChi2<999999. && pMag_updated>0.){//fit failed?! check
484  muonCandidate.momentum = bestP;
485  //}
486  //---- update the trajectory
487  muonCandidate.trajectoryMeasurementsInTheSet = trajectoryMeasurementsInTheSet;
488  // do we need that?
489  lastUpdatedTSOS_Vect[iSet]= *(lastUpdatedTSOS_pointer[bestFitElement]);
490 
491  //std::cout<<" FINAL: P = "<<muonCandidate.momentum.mag()<<" theta = "<<muonCandidate.momentum.theta()<<
492  //" phi = "<<muonCandidate.momentum.phi()<<" chi = "<<chi2Feet[bestFitElement]<<std::endl;
493  return minChi2;
494 }
495 
496 double SETFilter::
497 chi2AtSpecificStep(CLHEP::Hep3Vector &foot,
498  const CLHEP::Hep3Vector& r3T,
499  SeedCandidate & muonCandidate,
501  Trajectory::DataContainer & trajectoryMeasurementsInTheSet,
502  bool detailedOutput){
503  // specific input parameters - find chi2
504  double chi2 = 999999999999.;
505  if(foot.x()>0){ // this is |P|; maybe return a flag too?
506  double pMag_updated = 1./foot.x();
507  double sin_theta = sin(foot.y());
508  double cos_theta = cos(foot.y());
509  double sin_phi = sin(foot.z());
510  double cos_phi = cos(foot.z());
511 
512  double pX = pMag_updated*sin_theta*cos_phi;
513  double pY = pMag_updated*sin_theta*sin_phi;
514  double pZ = pMag_updated*cos_theta;
515  chi2 = findChi2(pX, pY, pZ, r3T,
516  muonCandidate, lastUpdatedTSOS,
517  trajectoryMeasurementsInTheSet, detailedOutput);
518  }
519  return chi2;
520 }
521 
522 std::vector <CLHEP::Hep3Vector> SETFilter::
523 find3MoreStartingPoints(CLHEP::Hep3Vector &key_foot,
524  const CLHEP::Hep3Vector& r3T,
525  SeedCandidate & muonCandidate){
526  // SIMPLEX uses nDim + 1 starting points;
527  // so here we need 3 more (one we already have)
528  std::vector <CLHEP::Hep3Vector> morePoints;// again - CLHEP::Hep3Vector is not a good choice here
529  double invP = key_foot.x();
530  double theta = key_foot.y();
531  double phi = key_foot.z();
532 
533 
534  double deltaPhi_init = 0.005;
535  double deltaTheta_init = 0.005;
536  //double deltaInvP_init = 1.1 * invP;
537  double deltaInvP_init = 0.1 * invP;
538  //deltaInvP_init = 0.5 * invP;
539 
540  // try to chose better point to start with
541  bool optimized = true;
542  if(optimized){
543  //---- Find a minimum chi2 for every variable (others are fixed) by supposing chi2 is a parabola
544  //---- Then these points ("minima") are probably better starting points for the real minimization
545 
547  Trajectory::DataContainer trajectoryMeasurementsInTheSet;// fake here
548  bool detailedOutput = false;// fake here
549 
550 
551  std::vector < double > pInv_init(3);
552  std::vector < double > theta_init(3);
553  std::vector < double > phi_init(3);
554  std::vector < double > chi2_init(3);
555 
556  pInv_init[0] = invP - deltaInvP_init;
557  pInv_init[1] = invP;
558  pInv_init[2] = invP + deltaInvP_init;
559  //pInv_init[2] = invP + 0.1 * invP;
560 
561  theta_init[0] = theta-deltaTheta_init;
562  theta_init[1] = theta;
563  theta_init[2] = theta+deltaTheta_init;
564 
565  phi_init[0] = phi-deltaPhi_init;
566  phi_init[1] = phi;
567  phi_init[2] = phi+deltaPhi_init;
568 
569  double sin_theta_nom = sin(theta_init[1]);
570  double cos_theta_nom = cos(theta_init[1]);
571  double sin_phi_nom = sin(phi_init[1]);
572  double cos_phi_nom = cos(phi_init[1]);
573  double pMag_updated_nom = 1./pInv_init[1];
574 
575  //--- invP
576  for(int i=0;i<3;++i){
577  double pMag_updated = 1./pInv_init[i];
578  double pX = pMag_updated*sin_theta_nom*cos_phi_nom;
579  double pY = pMag_updated*sin_theta_nom*sin_phi_nom;
580  double pZ = pMag_updated*cos_theta_nom;
581  chi2_init[i] = findChi2(pX, pY, pZ, r3T,
582  muonCandidate, lastUpdatedTSOS,
583  trajectoryMeasurementsInTheSet, detailedOutput);
584  }
585  std::pair <double,double> result_pInv =
586  findParabolaMinimum(pInv_init, chi2_init);
587 
588  //---- theta
589  for(int i=0;i<3;++i){
590  double sin_theta = sin(theta_init[i]);
591  double cos_theta = cos(theta_init[i]);
592  double pX = pMag_updated_nom*sin_theta*cos_phi_nom;
593  double pY = pMag_updated_nom*sin_theta*sin_phi_nom;
594  double pZ = pMag_updated_nom*cos_theta;
595  chi2_init[i] = findChi2(pX, pY, pZ, r3T,
596  muonCandidate, lastUpdatedTSOS,
597  trajectoryMeasurementsInTheSet, detailedOutput);
598  }
599  std::pair <double,double> result_theta =
600  findParabolaMinimum(theta_init, chi2_init);
601 
602  //---- phi
603  for(int i=0;i<3;++i){
604  double sin_phi = sin(phi_init[i]);
605  double cos_phi = cos(phi_init[i]);
606  double pX = pMag_updated_nom*sin_theta_nom*cos_phi;
607  double pY = pMag_updated_nom*sin_theta_nom*sin_phi;
608  double pZ = pMag_updated_nom*cos_theta_nom;
609  chi2_init[i] = findChi2(pX, pY, pZ, r3T,
610  muonCandidate, lastUpdatedTSOS,
611  trajectoryMeasurementsInTheSet, detailedOutput);
612  }
613  std::pair <double,double> result_phi =
614  findParabolaMinimum(phi_init, chi2_init);
615  // should we use that?
616  /* not used, keep it in case some interest comes back
617  double newPhi = result_phi.first;
618  if(fabs(newPhi - phi)<0.02){// too close?
619  newPhi = phi + 0.02;
620  }
621  */
622  CLHEP::Hep3Vector foot2(invP, theta, result_phi.first);
623  CLHEP::Hep3Vector foot3(invP, result_theta.first , phi);
624  /* not used, keep it in case some interest comes back
625  double newInvP = result_pInv.first;
626  if(fabs(newInvP - invP)<0.001){//too close
627  newInvP = invP + 0.001;
628  }
629  */
630  CLHEP::Hep3Vector foot4(result_pInv.first, theta, phi);
631  morePoints.push_back(foot2);
632  morePoints.push_back(foot3);
633  morePoints.push_back(foot4);
634  }
635  else{
636  // the points
637  CLHEP::Hep3Vector foot2(invP, theta, phi-deltaPhi_init);
638  CLHEP::Hep3Vector foot3(invP, theta-deltaTheta_init, phi);
639  CLHEP::Hep3Vector foot4(invP-deltaInvP_init, theta, phi);
640  morePoints.push_back(foot2);
641  morePoints.push_back(foot3);
642  morePoints.push_back(foot4);
643  }
644  return morePoints;
645 }
646 
647 std::pair <double,double> SETFilter::findParabolaMinimum(std::vector <double> &quadratic_var,
648  std::vector <double> &quadratic_chi2){
649 
650  // quadratic equation minimization
651 
652  double paramAtMin = -99.;
653  std::vector <double> quadratic_param(3);
654 
656  math::Matrix<3,3>::type enumerator_1;
657  math::Matrix<3,3>::type enumerator_2;
658  math::Matrix<3,3>::type enumerator_3;
659 
660  for(int iCol=0;iCol<3;++iCol){
661  denominator(0,iCol) = 1;
662  denominator(1,iCol) = quadratic_var.at(iCol);
663  denominator(2,iCol) = pow(quadratic_var.at(iCol),2);
664 
665  enumerator_1(0,iCol) = quadratic_chi2.at(iCol);
666  enumerator_1(1,iCol) = denominator(1,iCol);
667  enumerator_1(2,iCol) = denominator(2,iCol);
668 
669  enumerator_2(0,iCol) = denominator(0,iCol);
670  enumerator_2(1,iCol) = quadratic_chi2.at(iCol);
671  enumerator_2(2,iCol) = denominator(2,iCol);
672 
673  enumerator_3(0,iCol) = denominator(0,iCol);
674  enumerator_3(1,iCol) = denominator(1,iCol);
675  enumerator_3(2,iCol) = quadratic_chi2.at(iCol);
676  }
677  const double mult = 5.;// "save" accuracy"; result is independent on "mult"
678  denominator *=mult;
679  enumerator_1*=mult;
680  enumerator_2*=mult;
681  enumerator_3*=mult;
682 
684  enumerator.push_back(enumerator_1);
685  enumerator.push_back(enumerator_2);
686  enumerator.push_back(enumerator_3);
687 
688  double determinant=0;
689  denominator.Det2(determinant);
690  if(fabs(determinant)>0.00000000001){
691  for(int iPar=0;iPar<3;++iPar){
692  double d = 0.;
693  enumerator.at(iPar).Det2(d);
694  quadratic_param.at(iPar) = d/determinant;
695  }
696  }
697  else{
698  //std::cout<<" determinant 0? Check the code..."<<std::endl;
699  }
700  if(quadratic_param.at(2)>0){
701  paramAtMin = - quadratic_param.at(1)/quadratic_param.at(2)/2;
702  }
703  else {
704  //std::cout<<" parabola has a maximum or division by zero... Using initial value. "<<std::endl;
705  paramAtMin = quadratic_var.at(1);
706  }
707  double chi2_min = quadratic_param.at(0) + quadratic_param.at(1)*paramAtMin + quadratic_param.at(2)*pow(paramAtMin,2);
708  std::pair <double, double> result;
709  result = std::make_pair ( paramAtMin, chi2_min);
710  return result;
711 }
712 
713 void SETFilter::pickElements(std::vector <double> &chi2Feet,
714  unsigned int & high, unsigned int & second_high, unsigned int & low){
715  // a SIMPLEX function
716  std::vector <double> chi2Feet_tmp = chi2Feet;
717  std::vector <double>::iterator minEl = min_element(chi2Feet.begin(), chi2Feet.end());
718  std::vector <double>::iterator maxEl = max_element(chi2Feet.begin(), chi2Feet.end());
719  high = maxEl - chi2Feet.begin();
720  low = minEl - chi2Feet.begin();
721  chi2Feet_tmp[high] = chi2Feet_tmp[low];
722  std::vector <double>::iterator second_maxEl = max_element(chi2Feet_tmp.begin(), chi2Feet_tmp.end());
723  second_high = second_maxEl - chi2Feet_tmp.begin();
724 
725  return;
726 }
727 
728 CLHEP::Hep3Vector SETFilter::reflectFoot(std::vector <CLHEP::Hep3Vector> & feet,
729  unsigned int key_foot, double scale ){
730  // a SIMPLEX function
731  CLHEP::Hep3Vector newPosition(0.,0.,0.);
732  if(scale==0.5){
733  //std::cout<<" STA muon: scale parameter for simplex method incorrect : "<<scale<<std::endl;
734  return newPosition;
735  }
736  CLHEP::Hep3Vector centroid(0,0,0);
737  for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
738  if(iFoot==key_foot){
739  continue;
740  }
741  centroid += feet[iFoot];
742  }
743  centroid/=(feet.size()-1);
744  CLHEP::Hep3Vector displacement = 2.*(centroid - feet[key_foot]);
745  newPosition = feet[key_foot] + scale * displacement;
746  return newPosition;
747 }
748 
749 void SETFilter::nDimContract(std::vector <CLHEP::Hep3Vector> & feet, unsigned int low){
750  for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
751  // a SIMPLEX function
752  if(iFoot==low){
753  continue;
754  }
755  feet[iFoot] += feet[low];
756  feet[iFoot] /=2.;
757  }
758  return;
759 }
void nDimContract(std::vector< CLHEP::Hep3Vector > &feet, unsigned int low)
Definition: SETFilter.cc:749
std::string thePropagatorName
the propagator name
Definition: SETFilter.h:168
type
Definition: HCALResponse.h:21
bool transform(Trajectory::DataContainer &measurements_segments, TransientTrackingRecHit::ConstRecHitContainer &hitContainer, TrajectoryStateOnSurface &firstTSOS)
transforms "segment trajectory" to "rechit container"
Definition: SETFilter.cc:169
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
TrajectoryStateOnSurface theLastUpdatedTSOS
the trajectory state on the last available surface
Definition: SETFilter.h:174
float xx() const
Definition: LocalError.h:24
double chi2AtSpecificStep(CLHEP::Hep3Vector &foot, const CLHEP::Hep3Vector &r3T, SeedCandidate &muonCandidate, TrajectoryStateOnSurface &lastUpdatedTSOS, Trajectory::DataContainer &trajectoryMeasurementsInTheSet, bool detailedOutput)
Definition: SETFilter.cc:497
bool transformLight(Trajectory::DataContainer &measurements_segments, TransientTrackingRecHit::ConstRecHitContainer &hitContainer, TrajectoryStateOnSurface &firstTSOS)
transforms "segment trajectory" to "segment container"
Definition: SETFilter.cc:217
const Propagator * propagator() const
access at the propagator
Definition: SETFilter.cc:80
ROOT::Math::SMatrix< double, N, M > type
Definition: Matrix.h:10
CLHEP::Hep3Vector momentum
Definition: SETFilter.h:36
virtual SubDetector subDetector() const =0
The type of detector (PixelBarrel, PixelEndcap, TIB, TOB, TID, TEC, CSC, DT, RPCBarrel, RPCEndcap)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
TrajectoryStateOnSurface theLastButOneUpdatedTSOS
the trajectory state on the last but one available surface
Definition: SETFilter.h:176
void reset()
Definition: SETFilter.cc:71
Geom::Theta< T > theta() const
T y() const
Definition: PV3DBase.h:63
Trajectory::DataContainer trajectoryMeasurementsInTheSet
Definition: SETFilter.h:39
bool buildTrajectoryMeasurements(SeedCandidate *validSegmentsSet, Trajectory::DataContainer &finalCandidate)
from SeedCandidate to DataContainer only
Definition: SETFilter.cc:135
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:69
double findMinChi2(unsigned int iSet, const CLHEP::Hep3Vector &r3T, SeedCandidate &muonCandidate, std::vector< TrajectoryStateOnSurface > &lastUpdatedTSOS_Vect, Trajectory::DataContainer &trajectoryMeasurementsInTheSet)
Definition: SETFilter.cc:355
ROOT::Math::SMatrix< double, 5, 5, ROOT::Math::MatRepSym< double, 5 > > AlgebraicSymMatrix55
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:42
int cscChambers
Definition: SETFilter.h:183
TrajectoryStateOnSurface lastUpdatedTSOS() const
the Trajectory state on the last surface of the fitting
Definition: SETFilter.h:67
struct sorter sortRadius
sorter()
Definition: SETFilter.cc:33
int dtChambers
Definition: SETFilter.h:182
float xy() const
Definition: LocalError.h:25
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:44
bool fwfit_SET(std::vector< SeedCandidate > &validSegmentsSet_in, std::vector< SeedCandidate > &validSegmentsSet_out)
Perform the SET inner-outward fitting.
Definition: SETFilter.cc:100
int totalChambers
Definition: SETFilter.h:181
std::shared_ptr< MuonTransientTrackingRecHit > MuonRecHitPointer
float yy() const
Definition: LocalError.h:26
virtual ~SETFilter()
Destructor.
Definition: SETFilter.cc:61
std::shared_ptr< TrackingRecHit const > ConstRecHitPointer
FreeTrajectoryState const * freeState(bool withErrors=true) const
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
bool useSegmentsInTrajectory
Definition: SETFilter.h:186
SETFilter(const edm::ParameterSet &par, const MuonServiceProxy *service)
Constructor.
Definition: SETFilter.cc:52
bool operator()(TransientTrackingRecHit::ConstRecHitPointer hit_1, TransientTrackingRecHit::ConstRecHitPointer hit_2) const
Definition: SETFilter.cc:34
std::vector< CLHEP::Hep3Vector > find3MoreStartingPoints(CLHEP::Hep3Vector &key_foot, const CLHEP::Hep3Vector &r3T, SeedCandidate &muonCandidate)
Definition: SETFilter.cc:523
void pickElements(std::vector< double > &chi2Feet, unsigned int &high, unsigned int &second_high, unsigned int &low)
Definition: SETFilter.cc:713
#define LogTrace(id)
std::vector< ConstRecHitPointer > ConstRecHitContainer
Definition: DetId.h:18
const MuonServiceProxy * theService
Definition: SETFilter.h:192
TrajectoryStateOnSurface propagate(STA const &state, SUR const &surface) const
Definition: Propagator.h:53
double findChi2(double pX, double pY, double pZ, const CLHEP::Hep3Vector &r3T, SeedCandidate &muonCandidate, TrajectoryStateOnSurface &lastUpdatedTSOS, Trajectory::DataContainer &trajectoryMeasurementsInTheSet, bool detailedOutput)
Definition: SETFilter.cc:242
void incrementChamberCounters(const DetLayer *layer)
Increment the DT,CSC,RPC counters.
Definition: SETFilter.cc:85
HLT enums.
int rpcChambers
Definition: SETFilter.h:184
MuonTransientTrackingRecHit::MuonRecHitContainer theSet
Definition: SETFilter.h:35
std::vector< const DetLayer * > theDetLayers
the det layer used in the reconstruction
Definition: SETFilter.h:179
T x() const
Definition: PV3DBase.h:62
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:40
std::pair< double, double > findParabolaMinimum(std::vector< double > &quadratic_var, std::vector< double > &quadratic_chi2)
Definition: SETFilter.cc:647
virtual void setEvent(const edm::Event &event)
Pass the Event to the algo at each event.
Definition: SETFilter.cc:68
CLHEP::Hep3Vector reflectFoot(std::vector< CLHEP::Hep3Vector > &feet, unsigned int key_foot, double scale)
Definition: SETFilter.cc:728
Definition: event.py:1