CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TkLasBeamFitter.cc
Go to the documentation of this file.
1 
16 // system include files
17 #include <memory>
18 
19 // framework include files
31 
37 
38 // data formats
39 // for edm::InRun
41 
42 // laser data formats
45 
46 // further includes
51 
52 #include <iostream>
53 #include "TMinuit.h"
54 #include "TGraphErrors.h"
55 #include "TF1.h"
56 #include "TH1.h"
57 #include "TH2.h"
58 
59 using namespace edm;
60 using namespace std;
61 
62 
63 //
64 // class declaration
65 //
66 
68 public:
69  explicit TkLasBeamFitter(const edm::ParameterSet &config);
70  ~TkLasBeamFitter();
71 
72  //virtual void beginJob(const edm::EventSetup& /*access deprecated*/) {}
73  virtual void produce(edm::Event &event, const edm::EventSetup &setup);
74  // virtual void beginRun(edm::Run &run, const edm::EventSetup &setup);
75  virtual void endRun(edm::Run &run, const edm::EventSetup &setup);
76  //virtual void endJob() {}
77 
78 private:
81  void getLasBeams(TkFittedLasBeam &beam,vector<TrajectoryStateOnSurface> &tsosLas);
82  void getLasHits(TkFittedLasBeam &beam, const SiStripLaserRecHit2D &hit,
83  vector<const GeomDetUnit*> &gd, vector<GlobalPoint> &globHit,
84  unsigned int &hitsAtTecPlus);
85 // void fillVectors(TkFittedLasBeam &beam);
86 
87  // need static functions to be used in fitter(..);
88  // all parameters used therein have to be static, as well (see below)
89  static double tecPlusFunction(double *x, double *par);
90  static double tecMinusFunction(double *x, double *par);
91  static double atFunction(double *x, double *par);
92 
93  void fitter(TkFittedLasBeam &beam, AlgebraicSymMatrix &covMatrix,
94  unsigned int &hitsAtTecPlus, unsigned int &nFitParams,
95  std::vector<double> &hitPhi, std::vector<double> &hitPhiError, std::vector<double> &hitZprimeError,
96  double &zMin, double &zMax, double &bsAngleParam,
97  double &offset, double &offsetError, double &slope, double &slopeError,
98  double &phiAtMinusParam, double &phiAtPlusParam,
99  double &atThetaSplitParam);
100 
101  void trackPhi(TkFittedLasBeam &beam, unsigned int &hit,
102  double &trackPhi, double &trackPhiRef,
103  double &offset, double &slope, double &bsAngleParam,
104  double &phiAtMinusParam, double &phiAtPlusParam,
105  double &atThetaSplitParam, std::vector<GlobalPoint> &globHit);
106 
107  void globalTrackPoint(TkFittedLasBeam &beam,
108  unsigned int &hit, unsigned int &hitsAtTecPlus,
109  double &trackPhi, double &trackPhiRef,
110  std::vector<GlobalPoint> &globHit, std::vector<GlobalPoint> &globPtrack,
111  GlobalPoint &globPref, std::vector<double> &hitPhiError);
112 
113  void buildTrajectory(TkFittedLasBeam &beam, unsigned int &hit,
114  vector<const GeomDetUnit*> &gd, std::vector<GlobalPoint> &globPtrack,
115  vector<TrajectoryStateOnSurface> &tsosLas, GlobalPoint &globPref);
116 
117  bool fitBeam(TkFittedLasBeam &beam, AlgebraicSymMatrix &covMatrix,
118  unsigned int &hitsAtTecPlus, unsigned int &nFitParams,
119  double &offset, double &slope, vector<GlobalPoint> &globPtrack,
120  double &bsAngleParam, double &chi2);
121 
122  // ----------member data ---------------------------
125  unsigned int nAtParameters_;
126 
128 
129  // static parameters used in static parametrization functions
130  static vector<double> gHitZprime;
131  static vector<double> gBarrelModuleRadius;
132  static vector<double> gBarrelModuleOffset;
133  static float gTIBparam;
134  static float gTOBparam;
135  static double gBeamR;
136  static double gBeamZ0;
137  static double gBeamSplitterZprime;
138  static unsigned int gHitsAtTecMinus;
139  static double gBSparam;
140  static bool gFitBeamSplitters;
141  static bool gIsInnerBarrel;
142 
143  // histograms
144  TH1F *h_bsAngle, *h_hitX, *h_hitXTecPlus, *h_hitXTecMinus,
145  *h_hitXAt, *h_chi2, *h_chi2ndof, *h_pull, *h_res,
146  *h_resTecPlus, *h_resTecMinus, *h_resAt;
147  TH2F *h_bsAngleVsBeam, *h_hitXvsZTecPlus, *h_hitXvsZTecMinus,
148  *h_hitXvsZAt, *h_resVsZTecPlus, *h_resVsZTecMinus, *h_resVsZAt,
149  *h_resVsHitTecPlus, *h_resVsHitTecMinus, *h_resVsHitAt;
150 };
151 
152 //
153 // constants, enums and typedefs
154 //
155 
156 
157 //
158 // static data member definitions
159 //
160 
161 // static parameters used in parametrization functions
162 vector<double> TkLasBeamFitter::gHitZprime;
165 float TkLasBeamFitter::gTIBparam = 0.097614; // = abs(r_offset/r_module) (nominal!)
166 float TkLasBeamFitter::gTOBparam = 0.034949; // = abs(r_offset/r_module) (nominal!)
167 double TkLasBeamFitter::gBeamR = 0.0;
168 double TkLasBeamFitter::gBeamZ0 = 0.0;
170 unsigned int TkLasBeamFitter::gHitsAtTecMinus = 0;
171 double TkLasBeamFitter::gBSparam = 0.0;
174 
175 // handles
179 
180 //
181 // constructors and destructor
182 //
184  src_(iConfig.getParameter<edm::InputTag>("src")),
185  fitBeamSplitters_(iConfig.getParameter<bool>("fitBeamSplitters")),
186  nAtParameters_(iConfig.getParameter<unsigned int>("numberOfFittedAtParameters"))
187 {
188  // declare the products to produce
189  this->produces<TkFittedLasBeamCollection, edm::InRun>();
190  this->produces<TsosVectorCollection, edm::InRun>();
191 
192  //now do what ever other initialization is needed
193 }
194 
195 //---------------------------------------------------------------------------------------
197 {
198 
199  // do anything here that needs to be done at desctruction time
200  // (e.g. close files, deallocate resources etc.)
201 
202 }
203 
204 
205 //
206 // member functions
207 //
208 
209 //---------------------------------------------------------------------------------------
210 // ------------ method called to produce the data ------------
212 {
213  // Nothing per event!
214 }
215 
216 //---------------------------------------------------------------------------------------
217 // ------------ method called at end of each run ---------------------------------------
219 {
220 // }
221 // // FIXME!
222 // // Indeed, that should be in endRun(..) - as soon as AlignmentProducer can call
223 // // the algorithm's endRun correctly!
224 //
225 //
226 // void TkLasBeamFitter::beginRun(edm::Run &run, const edm::EventSetup &setup)
227 // {
228 
229  // book histograms
230  h_hitX = fs->make<TH1F>("hitX","local x of LAS hits;local x [cm];N",100,-0.5,0.5);
231  h_hitXTecPlus = fs->make<TH1F>("hitXTecPlus","local x of LAS hits in TECplus;local x [cm];N",100,-0.5,0.5);
232  h_hitXTecMinus = fs->make<TH1F>("hitXTecMinus","local x of LAS hits in TECminus;local x [cm];N",100,-0.5,0.5);
233  h_hitXAt = fs->make<TH1F>("hitXAt","local x of LAS hits in ATs;local x [cm];N",100,-2.5,2.5);
234  h_hitXvsZTecPlus = fs->make<TH2F>("hitXvsZTecPlus","local x vs z in TECplus;z [cm];local x [cm]",80,120,280,100,-0.5,0.5);
235  h_hitXvsZTecMinus = fs->make<TH2F>("hitXvsZTecMinus","local x vs z in TECMinus;z [cm];local x [cm]",80,-280,-120,100,-0.5,0.5);
236  h_hitXvsZAt = fs->make<TH2F>("hitXvsZAt","local x vs z in ATs;z [cm];local x [cm]",200,-200,200,100,-0.5,0.5);
237  h_chi2 = fs->make<TH1F>("chi2","#chi^{2};#chi^{2};N",100,0,2000);
238  h_chi2ndof = fs->make<TH1F>("chi2ndof","#chi^{2} per degree of freedom;#chi^{2}/N_{dof};N",100,0,300);
239  h_pull = fs->make<TH1F>("pull","pulls of #phi residuals;pull;N",50,-10,10);
240  h_res = fs->make<TH1F>("res","#phi residuals;#phi_{track} - #phi_{hit} [rad];N",60,-0.0015,0.0015);
241  h_resTecPlus = fs->make<TH1F>("resTecPlus","#phi residuals in TECplus;#phi_{track} - #phi_{hit} [rad];N",30,-0.0015,0.0015);
242  h_resTecMinus = fs->make<TH1F>("resTecMinus","#phi residuals in TECminus;#phi_{track} - #phi_{hit} [rad];N",60,-0.0015,0.0015);
243  h_resAt = fs->make<TH1F>("resAt","#phi residuals in ATs;#phi_{track} - #phi_{hit} [rad];N",30,-0.0015,0.0015);
244  h_resVsZTecPlus = fs->make<TH2F>("resVsZTecPlus","phi residuals vs. z in TECplus;z [cm];#phi_{track} - #phi_{hit} [rad]",
245  80,120,280,100,-0.0015,0.0015);
246  h_resVsZTecMinus = fs->make<TH2F>("resVsZTecMinus","phi residuals vs. z in TECminus;z [cm];#phi_{track} - #phi_{hit} [rad]",
247  80,-280,-120,100,-0.0015,0.0015);
248  h_resVsZAt = fs->make<TH2F>("resVsZAt","#phi residuals vs. z in ATs;N;#phi_{track} - #phi_{hit} [rad]",
249  200,-200,200,100,-0.0015,0.0015);
250  h_resVsHitTecPlus = fs->make<TH2F>("resVsHitTecPlus","#phi residuals vs. hits in TECplus;hit no.;#phi_{track} - #phi_{hit} [rad]",
251  144,0,144,100,-0.0015,0.0015);
252  h_resVsHitTecMinus = fs->make<TH2F>("resVsHitTecMinus","#phi residuals vs. hits in TECminus;hit no.;#phi_{track} - #phi_{hit} [rad]",
253  144,0,144,100,-0.0015,0.0015);
254  h_resVsHitAt = fs->make<TH2F>("resVsHitAt","#phi residuals vs. hits in ATs;hit no.;#phi_{track} - #phi_{hit} [rad]",
255  176,0,176,100,-0.0015,0.0015);
256  h_bsAngle = fs->make<TH1F>("bsAngle","fitted beam splitter angle;BS angle [rad];N",40,-0.004,0.004);
257  h_bsAngleVsBeam = fs->make<TH2F>("bsAngleVsBeam","fitted beam splitter angle per beam;Beam no.;BS angle [rad]",
258  40,0,300,100,-0.004,0.004);
259 
260  // Create output collections - they are parallel.
261  // (edm::Ref etc. and thus edm::AssociationVector are not supported for edm::Run...)
262  std::auto_ptr<TkFittedLasBeamCollection> fittedBeams(new TkFittedLasBeamCollection);
263  // One std::vector<TSOS> for each TkFittedLasBeam:
264  std::auto_ptr<TsosVectorCollection> tsosesVec(new TsosVectorCollection);
265 
266  // get TkLasBeams, Tracker geometry, magnetic field
267  run.getByLabel( "LaserAlignment", "tkLaserBeams", laserBeams );
268  setup.get<TrackerDigiGeometryRecord>().get(geometry);
270 
271  // hack for fixed BSparams (ugly!)
272 // double bsParams[34] = {-0.000266,-0.000956,-0.001205,-0.000018,-0.000759,0.002554,
273 // 0.000465,0.000975,0.001006,0.002027,-0.001263,-0.000763,
274 // -0.001702,0.000906,-0.002120,0.001594,0.000661,-0.000457,
275 // -0.000447,0.000347,-0.002266,-0.000446,0.000659,0.000018,
276 // -0.001630,-0.000324,
277 // // ATs
278 // -999.,-0.001709,-0.002091,-999.,
279 // -0.001640,-999.,-0.002444,-0.002345};
280 
281  double bsParams[40] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
282  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
283 
284  // beam counter
285  unsigned int beamNo(0);
286  // fit BS? If false, values from bsParams are taken
288  if(fitBeamSplitters_) cout << "Fitting BS!" << endl;
289  else cout << "BS fixed, not fitted!" << endl;
290 
291  // loop over LAS beams
292  for(TkLasBeamCollection::const_iterator iBeam = laserBeams->begin(), iEnd = laserBeams->end();
293  iBeam != iEnd; ++iBeam){
294 
295  TkFittedLasBeam beam(*iBeam);
296  vector<TrajectoryStateOnSurface> tsosLas;
297 
298  // set BS param for fit
299  gBSparam = bsParams[beamNo];
300 
301  // call main function; all other functions are called inside getLasBeams(..)
302  this->getLasBeams(beam, tsosLas);
303 
304  // fill output products
305  fittedBeams->push_back(beam);
306  tsosesVec->push_back(tsosLas);
307 
308 // if(!this->fitBeam(fittedBeams->back(), tsosesVec->back())){
309 // edm::LogError("BadFit")
310 // << "Problems fitting TkLasBeam, id " << fittedBeams->back().getBeamId() << ".";
311 // fittedBeams->pop_back(); // remove last entry added just before
312 // tsosesVec->pop_back(); // dito
313 // }
314 
315  beamNo++;
316  }
317 
318  // finally, put fitted beams and TSOS vectors into run
319  run.put(fittedBeams);
320  run.put(tsosesVec);
321 }
322 
323 // methods for las data processing
324 
325 // -------------- loop over beams, call functions ----------------------------
326 void TkLasBeamFitter::getLasBeams(TkFittedLasBeam &beam, vector<TrajectoryStateOnSurface> &tsosLas)
327 {
328  cout << "---------------------------------------" << endl;
329  cout << "beam id: " << beam.getBeamId() // << " isTec: " << (beam.isTecInternal() ? "Y" : "N")
330  << " isTec+: " << (beam.isTecInternal(1) ? "Y" : "N") << " isTec-: " << (beam.isTecInternal(-1) ? "Y" : "N")
331  << " isAt: " << (beam.isAlignmentTube() ? "Y" : "N") << " isR6: " << (beam.isRing6() ? "Y" : "N")
332  << endl;
333 
334  // reset static variables
335  gHitsAtTecMinus = 0;
336  gHitZprime.clear();
337  gBarrelModuleRadius.clear();
338  gBarrelModuleOffset.clear();
339 
340  // set right beam radius
341  gBeamR = beam.isRing6() ? 84.0 : 56.4;
342 
343  vector<const GeomDetUnit*> gd;
344  vector<GlobalPoint> globHit;
345  unsigned int hitsAtTecPlus(0);
346  double sumZ(0.);
347 
348  // loop over hits
349  for( TkLasBeam::const_iterator iHit = beam.begin(); iHit < beam.end(); ++iHit ){
350  // iHit is a SiStripLaserRecHit2D
351 
352  const SiStripLaserRecHit2D hit(*iHit);
353 
354  this->getLasHits(beam, hit, gd, globHit, hitsAtTecPlus);
355  sumZ += globHit.back().z();
356 
357  // fill histos
358  h_hitX->Fill(hit.localPosition().x());
359  // TECplus
360  if(beam.isTecInternal(1)){
361  h_hitXTecPlus->Fill(hit.localPosition().x());
362  h_hitXvsZTecPlus->Fill(globHit.back().z(),hit.localPosition().x());
363  }
364  // TECminus
365  else if(beam.isTecInternal(-1)){
366  h_hitXTecMinus->Fill(hit.localPosition().x());
367  h_hitXvsZTecMinus->Fill(globHit.back().z(),hit.localPosition().x());
368  }
369  // ATs
370  else{
371  h_hitXAt->Fill(hit.localPosition().x());
372  h_hitXvsZAt->Fill(globHit.back().z(),hit.localPosition().x());
373  }
374  }
375 
376  gBeamZ0 = sumZ / globHit.size();
377  double zMin(0.), zMax(0.);
378  // TECplus
379  if(beam.isTecInternal(1)){
380  gBeamSplitterZprime = 205.75 - gBeamZ0;
381  zMin = 120.0 - gBeamZ0;
382  zMax = 280.0 - gBeamZ0;
383  }
384  // TECminus
385  else if(beam.isTecInternal(-1)){
386  gBeamSplitterZprime = -205.75 - gBeamZ0;
387  zMin = -280.0 - gBeamZ0;
388  zMax = -120.0 - gBeamZ0;
389  }
390  // AT
391  else{
392  gBeamSplitterZprime = 112.3 - gBeamZ0;
393  zMin = -200.0 - gBeamZ0;
394  zMax = 200.0 - gBeamZ0;
395  }
396 
397  // fill vectors for fitted quantities
398  vector<double> hitPhi, hitPhiError, hitZprimeError;
399 
400  for(unsigned int hit = 0; hit < globHit.size(); ++hit){
401  hitPhi.push_back(static_cast<double>(globHit[hit].phi()));
402  // localPositionError[hit] or assume 0.003, 0.006
403  hitPhiError.push_back( 0.003 / globHit[hit].perp());
404  // no errors on z, fill with zeros
405  hitZprimeError.push_back(0.0);
406  // barrel-specific values
407  if(beam.isAlignmentTube() && abs(globHit[hit].z()) < 112.3){
408  gBarrelModuleRadius.push_back(globHit[hit].perp());
409  gBarrelModuleOffset.push_back(gBarrelModuleRadius.back() - gBeamR);
410  // TIB/TOB flag
411  if(gBarrelModuleOffset.back() < 0.0){
412  gIsInnerBarrel = 1;
413  }
414  else{
415  gIsInnerBarrel = 0;
416  }
417  gHitZprime.push_back(globHit[hit].z() - gBeamZ0 - abs(gBarrelModuleOffset.back()));
418  }
419  // non-barrel z'
420  else{
421  gHitZprime.push_back(globHit[hit].z() - gBeamZ0);
422  }
423  }
424 
425  // number of fit parameters, 3 for TECs (always!); 3, 5, or 6 for ATs
426  unsigned int tecParams(3), atParams(0);
427  if(nAtParameters_ == 3) atParams = 3;
428  else if(nAtParameters_ == 5) atParams = 5;
429  else atParams = 6; // <-- default value, recommended
430  unsigned int nFitParams(0);
431  if(!fitBeamSplitters_ ||
432  (hitsAtTecPlus == 0 && beam.isAlignmentTube() ) ){
433  tecParams = tecParams - 1;
434  atParams = atParams - 1;
435  }
436  if(beam.isTecInternal()){
437  nFitParams = tecParams;
438  }
439  else{
440  nFitParams = atParams;
441  }
442 
443  // fit parameter definitions
444  double offset(0.), offsetError(0.), slope(0.), slopeError(0.),
445  bsAngleParam(0.), phiAtMinusParam(0.), phiAtPlusParam(0.),
446  atThetaSplitParam(0.);
447  AlgebraicSymMatrix covMatrix;
448  if(!fitBeamSplitters_ || (beam.isAlignmentTube() && hitsAtTecPlus == 0)){
449  covMatrix = AlgebraicSymMatrix(nFitParams, 1);
450  }
451  else{
452  covMatrix = AlgebraicSymMatrix(nFitParams - 1, 1);
453  }
454 
455  this->fitter(beam, covMatrix,
456  hitsAtTecPlus, nFitParams,
457  hitPhi, hitPhiError, hitZprimeError,
458  zMin, zMax, bsAngleParam,
459  offset, offsetError, slope, slopeError,
460  phiAtMinusParam, phiAtPlusParam,
461  atThetaSplitParam);
462 
463  vector<GlobalPoint> globPtrack;
464  GlobalPoint globPref;
465  double chi2(0.);
466 
467  for(unsigned int hit = 0; hit < gHitZprime.size(); ++hit){
468 
469  // additional phi value (trackPhiRef) for trajectory calculation
470  double trackPhi(0.), trackPhiRef(0.);
471 
472  this->trackPhi(beam, hit, trackPhi, trackPhiRef,
473  offset, slope, bsAngleParam,
474  phiAtMinusParam, phiAtPlusParam,
475  atThetaSplitParam, globHit);
476 
477  cout << "track phi = " << trackPhi
478  << ", hit phi = " << hitPhi[hit]
479  << ", zPrime = " << gHitZprime[hit]
480  << " r = " << globHit[hit].perp() << endl;
481 
482  this->globalTrackPoint(beam, hit, hitsAtTecPlus,
483  trackPhi, trackPhiRef,
484  globHit, globPtrack, globPref,
485  hitPhiError);
486 
487  // calculate residuals = pred - hit (in global phi)
488  const double phiResidual = globPtrack[hit].phi() - globHit[hit].phi();
489  // pull calculation (FIX!!!)
490  const double phiResidualPull = phiResidual / hitPhiError[hit];
491  // sqrt(hitPhiError[hit]*hitPhiError[hit] +
492  // (offsetError*offsetError + globPtrack[hit].z()*globPtrack[hit].z() * slopeError*slopeError));
493 
494  // calculate chi2
495  chi2 += phiResidual*phiResidual / (hitPhiError[hit]*hitPhiError[hit]);
496 
497  // fill histos
498  h_res->Fill(phiResidual);
499  // TECplus
500  if(beam.isTecInternal(1)){
501  h_pull->Fill(phiResidualPull);
502  h_resTecPlus->Fill(phiResidual);
503  h_resVsZTecPlus->Fill(globPtrack[hit].z(), phiResidual);
504  // Ring 6
505  if(beam.isRing6()){
506  h_resVsHitTecPlus->Fill(hit+(beam.getBeamId()-1)/10*9+72, phiResidual);
507  }
508  // Ring 4
509  else{
510  h_resVsHitTecPlus->Fill(hit+beam.getBeamId()/10*9, phiResidual);
511  }
512  }
513  // TECminus
514  else if(beam.isTecInternal(-1)){
515  h_pull->Fill(phiResidualPull);
516  h_resTecMinus->Fill(phiResidual);
517  h_resVsZTecMinus->Fill(globPtrack[hit].z(), phiResidual);
518  // Ring 6
519  if(beam.isRing6()){
520  h_resVsHitTecMinus->Fill(hit+(beam.getBeamId()-101)/10*9+72, phiResidual);
521  }
522  // Ring 4
523  else{
524  h_resVsHitTecMinus->Fill(hit+(beam.getBeamId()-100)/10*9, phiResidual);
525  }
526  }
527  // ATs
528  else{
529  h_pull->Fill(phiResidualPull);
530  h_resAt->Fill(phiResidual);
531  h_resVsZAt->Fill(globPtrack[hit].z(), phiResidual);
532  h_resVsHitAt->Fill(hit+(beam.getBeamId()-200)/10*22, phiResidual);
533  }
534 
535  this->buildTrajectory(beam, hit, gd, globPtrack, tsosLas, globPref);
536  }
537 
538  cout << "chi^2 = " << chi2 << ", chi^2/ndof = " << chi2/(gHitZprime.size() - nFitParams) << endl;
539  this->fitBeam(beam, covMatrix, hitsAtTecPlus, nFitParams,
540  offset, slope, globPtrack, bsAngleParam, chi2);
541 
542  cout << "bsAngleParam = " << bsAngleParam << endl;
543 
544  // fill histos
545  // include slope, offset, covariance plots here
546  h_chi2->Fill(chi2);
547  h_chi2ndof->Fill(chi2/(gHitZprime.size() - nFitParams));
548  if(bsAngleParam != 0.0){
549  h_bsAngle->Fill(2.0*atan(0.5*bsAngleParam));
550  h_bsAngleVsBeam->Fill(beam.getBeamId(), 2.0*atan(0.5*bsAngleParam));
551  }
552 }
553 
554 
555 // --------- get hits, convert to global coordinates ---------------------------
557  vector<const GeomDetUnit*> &gd, vector<GlobalPoint> &globHit,
558  unsigned int &hitsAtTecPlus)
559 {
560  // get global position of LAS hits
561  gd.push_back(geometry->idToDetUnit(hit.getDetId()));
562  GlobalPoint globPtemp(gd.back()->toGlobal(hit.localPosition()));
563 
564  // testing: globPtemp should be right
565  globHit.push_back(globPtemp);
566 
567  if(beam.isAlignmentTube()){
568  if(abs(globPtemp.z()) > 112.3){
569  if(globPtemp.z() < 112.3) gHitsAtTecMinus++ ;
570  else hitsAtTecPlus++ ;
571  }
572  }
573 }
574 
575 
576 // ------------ parametrization functions for las beam fits ------------
577 double TkLasBeamFitter::tecPlusFunction(double *x, double *par)
578 {
579  double z = x[0]; // 'primed'? -> yes!!!
580 
581  if(z < gBeamSplitterZprime){
582  return par[0] + par[1] * z;
583  }
584  else{
585  if(gFitBeamSplitters){
586  // par[2] = 2*tan(BeamSplitterAngle/2.0)
587  return par[0] + par[1] * z - par[2] * (z - gBeamSplitterZprime)/gBeamR;
588  }
589  else{
590  return par[0] + par[1] * z - gBSparam * (z - gBeamSplitterZprime)/gBeamR;
591  }
592  }
593 }
594 
595 
596 double TkLasBeamFitter::tecMinusFunction(double *x, double *par)
597 {
598  double z = x[0]; // 'primed'? -> yes!!!
599 
600  if(z > gBeamSplitterZprime){
601  return par[0] + par[1] * z;
602  }
603  else{
604  if(gFitBeamSplitters){
605  // par[2] = 2*tan(BeamSplitterAngle/2.0)
606  return par[0] + par[1] * z + par[2] * (z - gBeamSplitterZprime)/gBeamR;
607  }
608  else{
609  return par[0] + par[1] * z + gBSparam * (z - gBeamSplitterZprime)/gBeamR;
610  }
611  }
612 }
613 
614 double TkLasBeamFitter::atFunction(double *x, double *par)
615 {
616  double z = x[0]; // 'primed'? -> yes!!!
617  // TECminus
618  if(z < -gBeamSplitterZprime - 2.0*gBeamZ0){
619  return par[0] + par[1] * z;
620  }
621  // BarrelMinus
622  else if(-gBeamSplitterZprime - 2.0*gBeamZ0 < z && z < -gBeamZ0){
623  // z value includes module offset from main beam axis
624  // TOB
625  if(!gIsInnerBarrel){
626  return par[0] + par[1] * z + gTOBparam * (par[2] + par[4]);
627  }
628  // TIB
629  else{
630  return par[0] + par[1] * z - gTIBparam * (par[2] - par[4]);
631  }
632  }
633  // BarrelPlus
634  else if(-gBeamZ0 < z && z < gBeamSplitterZprime){
635  // z value includes module offset from main beam axis
636  // TOB
637  if(!gIsInnerBarrel){
638  return par[0] + par[1] * z + gTOBparam * (par[3] - par[4]);
639  }
640  // TIB
641  else{
642  return par[0] + par[1] * z - gTIBparam * (par[3] + par[4]);
643  }
644  }
645  // TECplus
646  else{
647  if(gFitBeamSplitters){
648  // par[2] = 2*tan(BeamSplitterAngle/2.0)
649  return par[0] + par[1] * z - par[5] * (z - gBeamSplitterZprime)/gBeamR; // BS par: 5, 4, or 2
650  }
651  else{
652  return par[0] + par[1] * z - gBSparam * (z - gBeamSplitterZprime)/gBeamR;
653  }
654  }
655 }
656 
657 
658 // ------------ perform fit of beams ------------------------------------
660  unsigned int &hitsAtTecPlus, unsigned int &nFitParams,
661  vector<double> &hitPhi, vector<double> &hitPhiError, vector<double> &hitZprimeError,
662  double &zMin, double &zMax, double &bsAngleParam,
663  double &offset, double &offsetError, double &slope, double &slopeError,
664  double &phiAtMinusParam, double &phiAtPlusParam, double &atThetaSplitParam)
665 {
666  TGraphErrors *lasData = new TGraphErrors(gHitZprime.size(),
667  &(gHitZprime[0]), &(hitPhi[0]),
668  &(hitZprimeError[0]), &(hitPhiError[0]));
669 
670  // do fit (R = entire range)
671  if(beam.isTecInternal(1)){
672  TF1 tecPlus("tecPlus", tecPlusFunction, zMin, zMax, nFitParams );
673  tecPlus.SetParameter( 1, 0 ); // slope
674  tecPlus.SetParameter( nFitParams - 1, 0 ); // BS
675  lasData->Fit("tecPlus", "R"); // "R", "RV" or "RQ"
676  }
677  else if(beam.isTecInternal(-1)){
678  TF1 tecMinus("tecMinus", tecMinusFunction, zMin, zMax, nFitParams );
679  tecMinus.SetParameter( 1, 0 ); // slope
680  tecMinus.SetParameter( nFitParams - 1, 0 ); // BS
681  lasData->Fit("tecMinus", "R");
682  }
683  else{
684  TF1 at("at", atFunction, zMin, zMax, nFitParams );
685  at.SetParameter( 1, 0 ); // slope
686  at.SetParameter( nFitParams - 1, 0 ); // BS
687  lasData->Fit("at","R");
688  }
689 
690  // get values and errors for offset and slope
691  gMinuit->GetParameter(0, offset, offsetError);
692  gMinuit->GetParameter(1, slope, slopeError);
693 
694  // additional AT parameters
695  // define param errors that are not used later
696  double bsAngleParamError(0.), phiAtMinusParamError(0.),
697  phiAtPlusParamError(0.), atThetaSplitParamError(0.);
698 
699  if(beam.isAlignmentTube()){
700  gMinuit->GetParameter(2, phiAtMinusParam, phiAtMinusParamError);
701  gMinuit->GetParameter(3, phiAtPlusParam, phiAtPlusParamError);
702  gMinuit->GetParameter(4, atThetaSplitParam, atThetaSplitParamError);
703  }
704  // get Beam Splitter parameters
705  if(fitBeamSplitters_){
706  if(beam.isAlignmentTube() && hitsAtTecPlus == 0){
707  bsAngleParam = gBSparam;
708  }
709  else{
710  gMinuit->GetParameter( nFitParams - 1 , bsAngleParam, bsAngleParamError);
711  }
712  }
713  else{
714  bsAngleParam = gBSparam;
715  }
716 
717  // fill covariance matrix
718  vector<double> vec( covMatrix.num_col() * covMatrix.num_col() );
719  gMinuit->mnemat( &vec[0], covMatrix.num_col() );
720  for(int col = 0; col < covMatrix.num_col(); col++){
721  for(int row = 0; row < covMatrix.num_col(); row++){
722  covMatrix[col][row] = vec[row + covMatrix.num_col()*col];
723  }
724  }
725  // compute correlation between parameters
726 // double corr01 = covMatrix[1][0]/(offsetError*slopeError);
727 
728  delete lasData;
729 }
730 
731 
732 // -------------- calculate track phi value ----------------------------------
733 void TkLasBeamFitter::trackPhi(TkFittedLasBeam &beam, unsigned int &hit,
734  double &trackPhi, double &trackPhiRef,
735  double &offset, double &slope, double &bsAngleParam,
736  double &phiAtMinusParam, double &phiAtPlusParam,
737  double &atThetaSplitParam, vector<GlobalPoint> &globHit)
738 {
739  // TECplus
740  if(beam.isTecInternal(1)){
741  if(gHitZprime[hit] < gBeamSplitterZprime){
742  trackPhi = offset + slope * gHitZprime[hit];
743  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0);
744  }
745  else{
746  trackPhi = offset + slope * gHitZprime[hit]
747  - bsAngleParam * (gHitZprime[hit] - gBeamSplitterZprime)/gBeamR;
748  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0)
749  - bsAngleParam * ((gHitZprime[hit] + 1.0) - gBeamSplitterZprime)/gBeamR;
750  }
751  }
752  // TECminus
753  else if(beam.isTecInternal(-1)){
754  if(gHitZprime[hit] > gBeamSplitterZprime){
755  trackPhi = offset + slope * gHitZprime[hit];
756  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0);
757  }
758  else{
759  trackPhi = offset + slope * gHitZprime[hit]
760  + bsAngleParam * (gHitZprime[hit] - gBeamSplitterZprime)/gBeamR;
761  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0)
762  + bsAngleParam * ((gHitZprime[hit] + 1.0) - gBeamSplitterZprime)/gBeamR;
763  }
764  }
765  // ATs
766  else{
767  // TECminus
768  if(gHitZprime[hit] < -gBeamSplitterZprime - 2.0*gBeamZ0){
769  trackPhi = offset + slope * gHitZprime[hit];
770  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0);
771  }
772  // BarrelMinus
773  else if(-gBeamSplitterZprime - 2.0*gBeamZ0 < gHitZprime[hit] && gHitZprime[hit] < -gBeamZ0){
774  if(!gIsInnerBarrel){
775  trackPhi = offset + slope * gHitZprime[hit] + gTOBparam * (phiAtMinusParam + atThetaSplitParam);
776  }
777  else{
778  trackPhi = offset + slope * gHitZprime[hit] - gTIBparam * (phiAtMinusParam - atThetaSplitParam);
779  }
780  trackPhiRef = offset + slope * (gHitZprime[hit] + abs(gBarrelModuleOffset[hit-gHitsAtTecMinus]));
781  }
782  // BarrelPlus
783  else if(-gBeamZ0 < gHitZprime[hit] && gHitZprime[hit] < gBeamSplitterZprime){
784  if(!gIsInnerBarrel){
785  trackPhi = offset + slope * gHitZprime[hit] + gTOBparam * (phiAtPlusParam - atThetaSplitParam);
786  }
787  else{
788  trackPhi = offset + slope * gHitZprime[hit] - gTIBparam * (phiAtPlusParam + atThetaSplitParam);
789  }
790  trackPhiRef = offset + slope * (gHitZprime[hit] + abs(gBarrelModuleOffset[hit-gHitsAtTecMinus]));
791  }
792  // TECplus
793  else{
794  trackPhi = offset + slope * gHitZprime[hit]
795  - bsAngleParam * (gHitZprime[hit] - gBeamSplitterZprime)/gBeamR;
796  trackPhiRef = offset + slope * (gHitZprime[hit] + 1.0)
797  - bsAngleParam * ((gHitZprime[hit] + 1.0) - gBeamSplitterZprime)/gBeamR;
798  }
799  }
800 }
801 
802 
803 // -------------- calculate global track points, hit residuals, chi2 ----------------------------------
805  unsigned int &hit, unsigned int &hitsAtTecPlus,
806  double &trackPhi, double &trackPhiRef,
807  vector<GlobalPoint> &globHit, vector<GlobalPoint> &globPtrack,
808  GlobalPoint &globPref, vector<double> &hitPhiError)
809 {
810  // TECs
811  if(beam.isTecInternal(0)){
812  globPtrack.push_back(GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhi, globHit[hit].z())));
813  globPref = GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhiRef, globHit[hit].z() + 1.0));
814  }
815  // ATs
816  else{
817  // TECminus
818  if(hit < gHitsAtTecMinus){ // gHitZprime[hit] < -gBeamSplitterZprime - 2.0*gBeamZ0
819  globPtrack.push_back(GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhi, globHit[hit].z())));
820  globPref = GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhiRef, globHit[hit].z() + 1.0));
821  }
822  // TECplus
823  else if(hit > gHitZprime.size() - hitsAtTecPlus - 1){ // gHitZprime[hit] > gBeamSplitterZprime
824  globPtrack.push_back(GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhi, globHit[hit].z())));
825  globPref = GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhiRef, globHit[hit].z() + 1.0));
826  }
827  // Barrel
828  else{
829  globPtrack.push_back(GlobalPoint(GlobalPoint::Cylindrical(globHit[hit].perp(), trackPhi, globHit[hit].z())));
830  globPref = GlobalPoint(GlobalPoint::Cylindrical(gBeamR, trackPhiRef, globHit[hit].z()));
831  }
832  }
833 }
834 
835 
836 // ----------- create TrajectoryStateOnSurface for each track hit ----------------------------------------------
838  vector<const GeomDetUnit*> &gd, vector<GlobalPoint> &globPtrack,
839  vector<TrajectoryStateOnSurface> &tsosLas, GlobalPoint &globPref)
840 {
841  const MagneticField* magneticField = fieldHandle.product();
842  GlobalVector trajectoryState;
843 
844  // TECplus
845  if(beam.isTecInternal(1)){
846  trajectoryState = GlobalVector(globPref-globPtrack[hit]);
847  }
848  // TECminus
849  else if(beam.isTecInternal(-1)){
850  trajectoryState = GlobalVector(globPtrack[hit]-globPref);
851  }
852  // ATs
853  else{
854  // TECminus
855  if(gHitZprime[hit] < -gBeamSplitterZprime - 2.0*gBeamZ0){
856  trajectoryState = GlobalVector(globPtrack[hit]-globPref);
857  }
858  // TECplus
859  else if(gHitZprime[hit] > gBeamSplitterZprime){
860  trajectoryState = GlobalVector(globPref-globPtrack[hit]);
861  }
862  // Barrel
863  else{
864  trajectoryState = GlobalVector(globPtrack[hit]-globPref);
865  }
866  }
867 // cout << "trajectory: " << trajectoryState << endl;
868  const FreeTrajectoryState ftsLas = FreeTrajectoryState(globPtrack[hit],trajectoryState,0,magneticField);
869  tsosLas.push_back(TrajectoryStateOnSurface(ftsLas,gd[hit]->surface(),
871 }
872 
873 
874 //---------------------- set beam parameters for fittedBeams ---------------------------------
876  unsigned int &hitsAtTecPlus, unsigned int &nFitParams,
877  double &offset, double &slope, vector<GlobalPoint> &globPtrack,
878  double &bsAngleParam, double &chi2)
879 {
880  // set beam parameters for beam output
881  unsigned int paramType(0);
882  if(!fitBeamSplitters_) paramType = 1;
883  if(beam.isAlignmentTube() && hitsAtTecPlus == 0) paramType = 0;
884 // const unsigned int nPedeParams = nFitParams + paramType;
885 
886  // test without BS params
887  const unsigned int nPedeParams(nFitParams);
888 // cout << "number of Pede parameters: " << nPedeParams << endl;
889 
890  std::vector<TkFittedLasBeam::Scalar> params(nPedeParams);
891  params[0] = offset;
892  params[1] = slope;
893  // no BS parameter for AT beams without TECplus hits
894 // if(beam.isTecInternal() || hitsAtTecPlus > 0) params[2] = bsAngleParam;
895 
896  AlgebraicMatrix derivatives(gHitZprime.size(), nPedeParams);
897  // fill derivatives matrix with local track derivatives
898  for(unsigned int hit = 0; hit < gHitZprime.size(); ++hit){
899 
900  // d(delta phi)/d(offset) is identical for every hit
901  derivatives[hit][0] = 1.0;
902 
903  // d(delta phi)/d(slope) and d(delta phi)/d(bsAngleParam) depend on parametrizations
904  // TECplus
905  if(beam.isTecInternal(1)){
906  derivatives[hit][1] = globPtrack[hit].z();
907 // if(gHitZprime[hit] < gBeamSplitterZprime){
908 // derivatives[hit][2] = 0.0;
909 // }
910 // else{
911 // derivatives[hit][2] = - (globPtrack[hit].z() - gBeamSplitterZprime) / gBeamR;
912 // }
913  }
914  // TECminus
915  else if(beam.isTecInternal(-1)){
916  derivatives[hit][1] = globPtrack[hit].z();
917 // if(gHitZprime[hit] > gBeamSplitterZprime){
918 // derivatives[hit][2] = 0.0;
919 // }
920 // else{
921 // derivatives[hit][2] = (globPtrack[hit].z() - gBeamSplitterZprime) / gBeamR;
922 // }
923  }
924  // ATs
925  else{
926  // TECminus
928  derivatives[hit][1] = globPtrack[hit].z();
929 // if(hitsAtTecPlus > 0){
930 // derivatives[hit][2] = 0.0;
931 // }
932  }
933  // TECplus
934  else if(gHitZprime[hit] > gBeamSplitterZprime){
935  derivatives[hit][1] = globPtrack[hit].z();
936 // if(hitsAtTecPlus > 0){
937 // derivatives[hit][2] = - (globPtrack[hit].z() - gBeamSplitterZprime) / gBeamR;
938 // }
939  }
940  // Barrel
941  else{
942  derivatives[hit][1] = globPtrack[hit].z() - gBarrelModuleOffset[hit-gHitsAtTecMinus];
943 // if(hitsAtTecPlus > 0){
944 // derivatives[hit][2] = 0.0;
945 // }
946  }
947  }
948  }
949 
950  unsigned int firstFixedParam(covMatrix.num_col()); // FIXME! --> no, is fine!!!
951 // unsigned int firstFixedParam = nPedeParams - 1;
952 // if(beam.isAlignmentTube() && hitsAtTecPlus == 0) firstFixedParam = nPedeParams;
953 // cout << "first fixed parameter: " << firstFixedParam << endl;
954  // set fit results
955  beam.setParameters(paramType, params, covMatrix, derivatives, firstFixedParam, chi2);
956 
957  return true; // return false in case of problems
958 }
959 
960 
961 //---------------------------------------------------------------------------------------
962 //define this as a plug-in
ESHandle< MagneticField > fieldHandle
static vector< double > gHitZprime
static float gTOBparam
bool getByLabel(std::string const &label, Handle< PROD > &result) const
Definition: Run.h:175
static double gBeamR
static double tecMinusFunction(double *x, double *par)
static double tecPlusFunction(double *x, double *par)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
TkLasBeamFitter(const edm::ParameterSet &config)
static const double slope[3]
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
bool isRing6(void) const
true if this beam hits TEC R6 (last digit of beamId)
Definition: TkLasBeam.h:49
#define abs(x)
Definition: mlp_lapack.h:159
static vector< double > gBarrelModuleRadius
virtual LocalPoint localPosition() const
bool fitBeam(TkFittedLasBeam &beam, AlgebraicSymMatrix &covMatrix, unsigned int &hitsAtTecPlus, unsigned int &nFitParams, double &offset, double &slope, vector< GlobalPoint > &globPtrack, double &bsAngleParam, double &chi2)
static bool gFitBeamSplitters
bool isTecInternal(int side=0) const
true if this is a TEC internal beam (from 10^2 digit of beamId). side parameter: -1 = ask if TEC-...
Definition: TkLasBeam.cc:4
double double double z
virtual void endRun(edm::Run &run, const edm::EventSetup &setup)
Handle< TkLasBeamCollection > laserBeams
static bool gIsInnerBarrel
int iEvent
Definition: GenABIO.cc:243
unsigned int nAtParameters_
CLHEP::HepMatrix AlgebraicMatrix
unsigned int getBeamId(void) const
return the full beam identifier
Definition: TkLasBeam.h:25
T z() const
Definition: PV3DBase.h:58
void globalTrackPoint(TkFittedLasBeam &beam, unsigned int &hit, unsigned int &hitsAtTecPlus, double &trackPhi, double &trackPhiRef, std::vector< GlobalPoint > &globHit, std::vector< GlobalPoint > &globPtrack, GlobalPoint &globPref, std::vector< double > &hitPhiError)
static double gBeamSplitterZprime
std::vector< SiStripLaserRecHit2D >::const_iterator end(void) const
access iterator to the collection of hits
Definition: TkLasBeam.h:34
std::vector< SiStripLaserRecHit2D >::const_iterator begin(void) const
access iterator to the collection of hits
Definition: TkLasBeam.h:31
unsigned int offset(bool)
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
static unsigned int gHitsAtTecMinus
void fitter(TkFittedLasBeam &beam, AlgebraicSymMatrix &covMatrix, unsigned int &hitsAtTecPlus, unsigned int &nFitParams, std::vector< double > &hitPhi, std::vector< double > &hitPhiError, std::vector< double > &hitZprimeError, double &zMin, double &zMax, double &bsAngleParam, double &offset, double &offsetError, double &slope, double &slopeError, double &phiAtMinusParam, double &phiAtPlusParam, double &atThetaSplitParam)
const edm::InputTag src_
const SiStripDetId & getDetId(void) const
void buildTrajectory(TkFittedLasBeam &beam, unsigned int &hit, vector< const GeomDetUnit * > &gd, std::vector< GlobalPoint > &globPtrack, vector< TrajectoryStateOnSurface > &tsosLas, GlobalPoint &globPref)
virtual void produce(edm::Event &event, const edm::EventSetup &setup)
static double gBSparam
const T & get() const
Definition: EventSetup.h:55
T const * product() const
Definition: ESHandle.h:62
static vector< double > gBarrelModuleOffset
ESHandle< TrackerGeometry > geometry
T perp() const
Magnitude of transverse component.
void trackPhi(TkFittedLasBeam &beam, unsigned int &hit, double &trackPhi, double &trackPhiRef, double &offset, double &slope, double &bsAngleParam, double &phiAtMinusParam, double &phiAtPlusParam, double &atThetaSplitParam, std::vector< GlobalPoint > &globHit)
std::vector< TkFittedLasBeam > TkFittedLasBeamCollection
CLHEP::HepSymMatrix AlgebraicSymMatrix
tuple gMinuit
Definition: fitWZ.py:35
T * make() const
make new ROOT object
static float gTIBparam
static double atFunction(double *x, double *par)
tuple cout
Definition: gather_cfg.py:41
void put(std::auto_ptr< PROD > product)
Put a new product.
Definition: Run.h:80
void getLasBeams(TkFittedLasBeam &beam, vector< TrajectoryStateOnSurface > &tsosLas)
Definition: DDAxes.h:10
std::vector< std::vector< TrajectoryStateOnSurface > > TsosVectorCollection
void getLasHits(TkFittedLasBeam &beam, const SiStripLaserRecHit2D &hit, vector< const GeomDetUnit * > &gd, vector< GlobalPoint > &globHit, unsigned int &hitsAtTecPlus)
T x() const
Definition: PV3DBase.h:56
edm::Service< TFileService > fs
std::vector< SiStripLaserRecHit2D >::const_iterator const_iterator
Definition: TkLasBeam.h:16
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
bool isAlignmentTube(void) const
true if this is an AT beam (from 10^2 digit of beamId)
Definition: TkLasBeam.h:46
Definition: Run.h:32
Global3DVector GlobalVector
Definition: GlobalVector.h:10
list at
Definition: asciidump.py:428
const double par[8 *NPar][4]
void setParameters(unsigned int parametrisation, const std::vector< Scalar > &params, const AlgebraicSymMatrix &paramCovariance, const AlgebraicMatrix &derivatives, unsigned int firstFixedParam, float chi2)
static double gBeamZ0
Definition: DDAxes.h:10