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