CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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 
53  const MuonServiceProxy* service)
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.size() &&
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  }
157  theLastUpdatedTSOS = finalMuon->trajectoryMeasurementsInTheSet.at(finalMuon->trajectoryMeasurementsInTheSet.size()-1).forwardPredictedState();
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,
245  TrajectoryStateOnSurface &lastUpdatedTSOS,
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,
500  TrajectoryStateOnSurface &lastUpdatedTSOS,
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  double newPhi = result_phi.first;
617  if(fabs(newPhi - phi)<0.02){// too close?
618  newPhi = phi + 0.02;
619  }
620  CLHEP::Hep3Vector foot2(invP, theta, result_phi.first);
621  CLHEP::Hep3Vector foot3(invP, result_theta.first , phi);
622  double newInvP = result_pInv.first;
623  if(fabs(newInvP - invP)<0.001){//too close
624  newInvP = invP + 0.001;
625  }
626  CLHEP::Hep3Vector foot4(result_pInv.first, theta, phi);
627  morePoints.push_back(foot2);
628  morePoints.push_back(foot3);
629  morePoints.push_back(foot4);
630  }
631  else{
632  // the points
633  CLHEP::Hep3Vector foot2(invP, theta, phi-deltaPhi_init);
634  CLHEP::Hep3Vector foot3(invP, theta-deltaTheta_init, phi);
635  CLHEP::Hep3Vector foot4(invP-deltaInvP_init, theta, phi);
636  morePoints.push_back(foot2);
637  morePoints.push_back(foot3);
638  morePoints.push_back(foot4);
639  }
640  return morePoints;
641 }
642 
643 std::pair <double,double> SETFilter::findParabolaMinimum(std::vector <double> &quadratic_var,
644  std::vector <double> &quadratic_chi2){
645 
646  // quadratic equation minimization
647 
648  double paramAtMin = -99.;
649  std::vector <double> quadratic_param(3);
650 
652  math::Matrix<3,3>::type enumerator_1;
653  math::Matrix<3,3>::type enumerator_2;
654  math::Matrix<3,3>::type enumerator_3;
655 
656  for(int iCol=0;iCol<3;++iCol){
657  denominator(0,iCol) = 1;
658  denominator(1,iCol) = quadratic_var.at(iCol);
659  denominator(2,iCol) = pow(quadratic_var.at(iCol),2);
660 
661  enumerator_1(0,iCol) = quadratic_chi2.at(iCol);
662  enumerator_1(1,iCol) = denominator(1,iCol);
663  enumerator_1(2,iCol) = denominator(2,iCol);
664 
665  enumerator_2(0,iCol) = denominator(0,iCol);
666  enumerator_2(1,iCol) = quadratic_chi2.at(iCol);
667  enumerator_2(2,iCol) = denominator(2,iCol);
668 
669  enumerator_3(0,iCol) = denominator(0,iCol);
670  enumerator_3(1,iCol) = denominator(1,iCol);
671  enumerator_3(2,iCol) = quadratic_chi2.at(iCol);
672  }
673  const double mult = 5.;// "save" accuracy"; result is independent on "mult"
674  denominator *=mult;
675  enumerator_1*=mult;
676  enumerator_2*=mult;
677  enumerator_3*=mult;
678 
680  enumerator.push_back(enumerator_1);
681  enumerator.push_back(enumerator_2);
682  enumerator.push_back(enumerator_3);
683 
684  double determinant=0;
685  denominator.Det2(determinant);
686  if(fabs(determinant)>0.00000000001){
687  for(int iPar=0;iPar<3;++iPar){
688  double d = 0.;
689  enumerator.at(iPar).Det2(d);
690  quadratic_param.at(iPar) = d/determinant;
691  }
692  }
693  else{
694  //std::cout<<" determinant 0? Check the code..."<<std::endl;
695  }
696  if(quadratic_param.at(2)>0){
697  paramAtMin = - quadratic_param.at(1)/quadratic_param.at(2)/2;
698  }
699  else {
700  //std::cout<<" parabola has a maximum or division by zero... Using initial value. "<<std::endl;
701  paramAtMin = quadratic_var.at(1);
702  }
703  double chi2_min = quadratic_param.at(0) + quadratic_param.at(1)*paramAtMin + quadratic_param.at(2)*pow(paramAtMin,2);
704  std::pair <double, double> result;
705  result = std::make_pair ( paramAtMin, chi2_min);
706  return result;
707 }
708 
709 void SETFilter::pickElements(std::vector <double> &chi2Feet,
710  unsigned int & high, unsigned int & second_high, unsigned int & low){
711  // a SIMPLEX function
712  std::vector <double> chi2Feet_tmp = chi2Feet;
713  std::vector <double>::iterator minEl = min_element(chi2Feet.begin(), chi2Feet.end());
714  std::vector <double>::iterator maxEl = max_element(chi2Feet.begin(), chi2Feet.end());
715  high = maxEl - chi2Feet.begin();
716  low = minEl - chi2Feet.begin();
717  chi2Feet_tmp[high] = chi2Feet_tmp[low];
718  std::vector <double>::iterator second_maxEl = max_element(chi2Feet_tmp.begin(), chi2Feet_tmp.end());
719  second_high = second_maxEl - chi2Feet_tmp.begin();
720 
721  return;
722 }
723 
724 CLHEP::Hep3Vector SETFilter::reflectFoot(std::vector <CLHEP::Hep3Vector> & feet,
725  unsigned int key_foot, double scale ){
726  // a SIMPLEX function
727  CLHEP::Hep3Vector newPosition(0.,0.,0.);
728  if(scale==0.5){
729  //std::cout<<" STA muon: scale parameter for simplex method incorrect : "<<scale<<std::endl;
730  return newPosition;
731  }
732  CLHEP::Hep3Vector centroid(0,0,0);
733  for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
734  if(iFoot==key_foot){
735  continue;
736  }
737  centroid += feet[iFoot];
738  }
739  centroid/=(feet.size()-1);
740  CLHEP::Hep3Vector displacement = 2.*(centroid - feet[key_foot]);
741  newPosition = feet[key_foot] + scale * displacement;
742  return newPosition;
743 }
744 
745 void SETFilter::nDimContract(std::vector <CLHEP::Hep3Vector> & feet, unsigned int low){
746  for(unsigned int iFoot = 0; iFoot<feet.size();++iFoot){
747  // a SIMPLEX function
748  if(iFoot==low){
749  continue;
750  }
751  feet[iFoot] += feet[low];
752  feet[iFoot] /=2.;
753  }
754  return;
755 }
void nDimContract(std::vector< CLHEP::Hep3Vector > &feet, unsigned int low)
Definition: SETFilter.cc:745
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 &quot;segment trajectory&quot; to &quot;rechit container&quot;
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
virtual FreeTrajectoryState propagate(const FreeTrajectoryState &ftsStart, const GlobalPoint &pDest) const final
Definition: Propagator.h:119
int i
Definition: DBlmapReader.cc:9
virtual int dimension() const =0
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 &quot;segment trajectory&quot; to &quot;segment container&quot;
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
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
virtual const TrackingRecHit * hit() const
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
virtual SubDetector subDetector() const =0
The type of detector (PixelBarrel, PixelEndcap, TIB, TOB, TID, TEC, CSC, DT, RPCBarrel, RPCEndcap)
bool buildTrajectoryMeasurements(SeedCandidate *validSegmentsSet, Trajectory::DataContainer &finalCandidate)
from SeedCandidate to DataContainer only
Definition: SETFilter.cc:135
virtual LocalPoint localPosition() const override
LocalPoint toLocal(const GlobalPoint &gp) const
Conversion to the R.F. of the GeomDet.
Definition: GeomDet.h:67
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
virtual LocalError localPositionError() const override
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:40
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
tuple d
Definition: ztail.py:151
float xy() const
Definition: LocalError.h:25
std::vector< TrajectoryMeasurement > DataContainer
Definition: Trajectory.h:42
list denominator
Definition: cuy.py:484
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
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
tuple result
Definition: query.py:137
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
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
void pickElements(std::vector< double > &chi2Feet, unsigned int &high, unsigned int &second_high, unsigned int &low)
Definition: SETFilter.cc:709
#define LogTrace(id)
std::vector< ConstRecHitPointer > ConstRecHitContainer
Definition: DetId.h:18
const MuonServiceProxy * theService
Definition: SETFilter.h:192
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
int rpcChambers
Definition: SETFilter.h:184
MuonTransientTrackingRecHit::MuonRecHitContainer theSet
Definition: SETFilter.h:35
DetId geographicalId() const
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:643
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:724