00001 #include "RecoHI/HiMuonAlgos/interface/HICMuonUpdator.h"
00002 #include "TrackingTools/PatternTools/interface/TrajectoryMeasurement.h"
00003 #include "DataFormats/GeometrySurface/interface/BoundPlane.h"
00004 #include "DataFormats/GeometryVector/interface/GlobalPoint.h"
00005 #include "DataFormats/GeometryVector/interface/GlobalVector.h"
00006
00007 #include <cmath>
00008 #include <stdlib.h>
00009 #include <string>
00010 #include <iostream>
00011 #include <vector>
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 using namespace std;
00022
00023 TrajectoryStateOnSurface HICMuonUpdator::update(const Trajectory& mt,
00024 const TrajectoryStateOnSurface& nTsos,
00025 const TrajectoryMeasurement& ntm,
00026 const DetLayer* layer,
00027 double& chirz, double& chirf) const {
00028 double pi = 4.*atan(1.);
00029 double twopi=8.*atan(1.);
00030 TrajectoryStateOnSurface badtsos;
00031 if(!nTsos.isValid()) {
00032 std::cout<<" HICMuonUpdator::update:: can not start::initial tsos is not valid " <<std::endl;
00033 return badtsos;
00034 }
00035
00036
00037 vector<TrajectoryMeasurement> MTM=mt.measurements();
00038 #ifdef DEBUG
00039 std::cout<<" HICMuonUpdator::update::MTM size "<<MTM.size()<<" vertex "<<zvert<<std::endl;
00040 std::cout<<" HICMuonUpdator::update::charge from trajectory"<<(MTM.back()).updatedState().freeTrajectoryState()->parameters().charge()<<std::endl;
00041 std::cout<<" HICMuonUpdator::update::charge predicted tsos"<<nTsos.freeTrajectoryState()->charge()<<std::endl;
00042 std::cout<<" HICMuonUpdator::update::momentum "<<(MTM.back()).updatedState().freeTrajectoryState()->parameters().momentum()<<std::endl;
00043 #endif
00044 vector<double> phihit,rhit,zhit,dphihit,drhit,dzhit,dzhitl,ehitphi,dehitphi,ehitstrip;
00045
00046 double rvert=0.;
00047 double ezvert=0.014;
00048
00049 const TransientTrackingRecHit::ConstRecHitPointer pRecHit=(MTM.back()).recHit();
00050 const TransientTrackingRecHit::ConstRecHitPointer nRecHit=ntm.recHit();
00051
00052
00053
00054 GlobalVector pold=(MTM.back()).updatedState().freeTrajectoryState()->parameters().momentum();
00055 double theta=pold.theta();
00056
00057 for(vector<TrajectoryMeasurement>::const_iterator ihit=MTM.begin();ihit!=MTM.end();ihit++){
00058
00059
00060 phihit.push_back((*ihit).recHit()->globalPosition().phi());
00061 rhit.push_back((*ihit).recHit()->globalPosition().perp());
00062 zhit.push_back((*ihit).recHit()->globalPosition().z());
00063 GlobalPoint realhit = (*ihit).recHit()->globalPosition();
00064
00065 double phierror=sqrt((*ihit).recHit()->globalPositionError().phierr(realhit));
00066
00067 if(fabs(phierror)<0.0000001) {
00068 phierror=0.00008;
00069 }
00070 ehitphi.push_back(phierror);
00071
00072 #ifdef UPDATOR_BARREL_DEBUG
00073 cout<<" Errors "<<phierror<<" "<<(*ihit).recHit()->globalPositionError().rerr(realhit)<<" "<<tan(theta)<<endl;
00074 #endif
00075
00076
00077 if((*ihit).layer()->location()==GeomDetEnumerators::barrel){
00078 ehitstrip.push_back(sqrt((*ihit).recHit()->globalPositionError().czz()));
00079 } else{
00080 ehitstrip.push_back(sqrt((*ihit).recHit()->globalPositionError().rerr(realhit)/fabs(tan(theta))));
00081 }
00082
00083 }
00084
00085 phihit.push_back(nRecHit->globalPosition().phi());
00086 rhit.push_back(nRecHit->globalPosition().perp());
00087 zhit.push_back(nRecHit->globalPosition().z());
00088 ehitphi.push_back(sqrt(nRecHit->globalPositionError().phierr(nRecHit->globalPosition())));
00089
00090
00091
00092
00093
00094 if(ntm.layer()->location()==GeomDetEnumerators::barrel){
00095 ehitstrip.push_back(sqrt(nRecHit->globalPositionError().czz()));
00096 } else {
00097 ehitstrip.push_back(sqrt(nRecHit->globalPositionError().rerr(nRecHit->globalPosition()))/fabs(tan(theta)));
00098 }
00099
00100
00101
00102 rhit.push_back(rvert);
00103 zhit.push_back(zvert);
00104 ehitstrip.push_back(ezvert);
00105
00106 for(vector<double>::const_iterator iphi=phihit.begin();iphi!=phihit.end()-1;iphi++){
00107 double dpnew=fabs(*iphi-*(iphi+1));
00108 if(dpnew>pi) dpnew=twopi-dpnew;
00109
00110 #ifdef UPDATOR_BARREL_DEBUG
00111 cout<<" dphi=dpnew="<<dpnew<<" "<<*iphi<<" "<<*(iphi+1)<<endl;
00112 #endif
00113
00114 dphihit.push_back(dpnew);
00115 }
00116
00117 for(vector<double>::const_iterator ir=rhit.begin();ir!=rhit.end()-2;ir++){
00118 double dpnew=fabs(*ir-*(ir+1));
00119
00120 #ifdef UPDATOR_BARREL_DEBUG
00121 cout<<" dr=dpnew="<<dpnew<<" "<<*ir<<" "<<*(ir+1)<<endl;
00122 #endif
00123
00124 drhit.push_back(dpnew);
00125 }
00126 for(vector<double>::const_iterator iz=zhit.begin();iz!=zhit.end()-2;iz++){
00127 double dpnew=*iz-*(iz+1);
00128
00129 #ifdef UPDATOR_BARREL_DEBUG
00130 cout<<" dZ=dpnew="<<dpnew<<" "<<*iz<<" "<<*(iz+1)<<endl;
00131 #endif
00132
00133 dzhit.push_back(fabs(dpnew));
00134 dzhitl.push_back(dpnew);
00135 }
00136
00137 dzhitl.push_back(*(zhit.end()-1)-zvert);
00138
00139 for(vector<double>::const_iterator ie=ehitphi.begin();ie!=ehitphi.end()-1;ie++){
00140 double dpnew=(*ie)*1.14;
00141 dehitphi.push_back(dpnew);
00142 }
00143
00144
00145
00146 int tType = 1;
00147 if ( (*(MTM.begin())).layer()->location()==GeomDetEnumerators::barrel){
00148
00149 TrajectoryStateOnSurface tsos=updateBarrel(rhit, zhit, dphihit, drhit, ehitstrip, dehitphi, pRecHit, nRecHit,
00150 nTsos, chirz, chirf, tType);
00151
00152 if(!tsos.isValid()) {
00153 #ifdef DEBUG
00154 std::cout<<" Trajectory is not valid "<<std::endl;
00155 #endif
00156 return badtsos;
00157 }
00158
00159 return tsos;
00160
00161 } else{
00162
00163 TrajectoryStateOnSurface tsos=updateEndcap(rhit, zhit, dphihit, dzhit, ehitstrip, dehitphi, pRecHit, nRecHit,
00164 nTsos, chirz, chirf, tType);
00165 return tsos;
00166
00167 }
00168 }
00169
00170 bool HICMuonUpdator::linefit2(const vector <double>& y, const vector <double>& x,
00171 const vector <double>& err, double& co1, double& co2,
00172 double & chi2) const{
00173 double a00=0.;
00174 double a01=0.;
00175 double a10=0.;
00176 double a11=0.;
00177
00178 double b0=0.;
00179 double b1=0.;
00180
00181 bool fit;
00182 fit=false;
00183
00184 #ifdef LINEFIT_DEBUG
00185 cout<<" linefit2::sizes="<<x.size()<<" "<<y.size()<<" "<<err.size()<<endl;
00186 cout<<" linefit2::a00 "<<a00<<" "<<a01<<" "<<a11<<" "<<b0<<" "<<b1<<endl;
00187 #endif
00188
00189 if(x.size() != y.size()) return fit;
00190 if(x.size() != err.size()) return fit;
00191
00192
00193 for (unsigned int i=0;i<x.size();i++){
00194 #ifdef LINEFIT_DEBUG
00195 cout<<" line2fit "<<a00<<" "<<x[i]/err[i]<<" "<<x[i]<<" "<<err[i]<<" second try "<<err[i]<<endl;
00196 #endif
00197 a00=a00+(x[i]/err[i])*(x[i]/err[i]);
00198 a01=a01+(x[i]/err[i])/err[i];
00199 a10=a01;
00200 a11=a11+1./(err[i]*err[i]);
00201 b0=b0+(x[i]/err[i])*(y[i]/err[i]);
00202 b1=b1+(y[i]/err[i])/err[i];
00203
00204 #ifdef LINEFIT_DEBUG
00205 cout<<"linefit2="<<x[i]<<" "<<y[i]<<" "<<err[i]<<" "<<a00<<" "<<a01<<" "<<a11<<" "<<b0<<" "<<b1<<endl;
00206 #endif
00207
00208 }
00209 double det=a00*a11-a01*a01;
00210
00211 #ifdef LINEFIT_DEBUG
00212 cout<<" linefit2::det="<<det<<endl;
00213 #endif
00214
00215 if(fabs(det)<0.00000001) return fit;
00216 co1=(b0*a11-b1*a01)/det;
00217 co2=(b1*a00-b0*a10)/det;
00218
00219
00220 #ifdef LINEFIT_DEBUG
00221 cout<<" linefit2::Previous element= "<<y[x.size()-3]<<" "<<x[x.size()-3]<<endl;
00222 #endif
00223
00224 if(y[x.size()-2]<14.) {
00225
00226 #ifdef LINEFIT_DEBUG
00227 cout<<" check 90 degree track "<<endl;
00228 #endif
00229
00230 if(fabs(x[x.size()-2]-x[x.size()-1])<0.1){
00231
00232 #ifdef LINEFIT_DEBUG
00233 cout<<" Redetermine line - 90 degree "<<endl;
00234 #endif
00235
00236 if(fabs(x[x.size()-2]-x[x.size()-1])>0.0001){
00237 co1=(y[x.size()-2]-y[x.size()-1])/(x[x.size()-2]-x[x.size()-1]);
00238 co2=y[x.size()-2]-co1*x[x.size()-2];
00239 }
00240 else
00241 {
00242 co1=10000.;
00243 co2=-zvert*10000.;
00244 }
00245 }
00246 }
00247
00248 #ifdef LINEFIT_DEBUG
00249 cout<<"linefit2::co1,co2="<<co1<<" "<<co2<<" size "<<x.size()<<endl;
00250 #endif
00251
00252 chi2=0.;
00253 for (unsigned int i=0;i<x.size();i++){
00254 double zdet=(y[i]-co2)/co1;
00255 chi2=chi2+(x[i]-zdet)*(x[i]-zdet)/(err[i]*err[i]);
00256
00257 #ifdef LINEFIT_DEBUG
00258 cout<<"linefit2::chi2="<<chi2<<" err="<<err[i]<<" x[i]="<<x[i]<<" teor="<<zdet<<endl;
00259 #endif
00260
00261 }
00262
00263 chi2=chi2/x.size();
00264 #ifdef LINEFIT_DEBUG
00265 cout<<" linefit2::chi2= "<<chi2<<endl;
00266 #endif
00267
00268 return fit=true;
00269 }
00270 bool HICMuonUpdator::linefit1(const vector <double>& y, const vector <double>& x, const vector <double>& err,
00271 double& co1, double& chi2)
00272 const{
00273 double s1=0.;
00274 double s2=0.;
00275
00276 bool fit;
00277 fit=false;
00278
00279 #ifdef LINEFIT_DEBUG
00280 cout<<" linefit1::sizes="<<x.size()<<" "<<y.size()<<" "<<err.size()<<endl;
00281 #endif
00282
00283 if(x.size() != y.size()) return fit;
00284 if(x.size() != err.size()) return fit;
00285
00286 for (unsigned int i=0;i<x.size();i++){
00287 s1=s1+(x[i]/err[i])*(y[i]/err[i]);
00288 s2=s2+(x[i]/err[i])*(x[i]/err[i]);
00289
00290 #ifdef LINEFIT_DEBUG
00291 cout<<"linefit1="<<x[i]<<" "<<y[i]<<" "<<err[i]<<" "<<s1<<" "<<s2<<endl;
00292 #endif
00293
00294 }
00295
00296 co1=s1/s2;
00297
00298 #ifdef LINEFIT_DEBUG
00299 cout<<"linefit1::co1,co2="<<co1<<endl;
00300 #endif
00301
00302 chi2=0.;
00303 for (unsigned int i=0;i<x.size();i++){
00304 chi2=chi2+(y[i]-co1*x[i])*(y[i]-co1*x[i])/(err[i]*err[i]);
00305 }
00306 chi2=chi2/x.size();
00307 #ifdef LINEFIT_DEBUG
00308 cout<<"linefit1::chi2="<<chi2<<endl;
00309 #endif
00310 return fit=true;
00311 }
00312
00313
00314 double
00315 HICMuonUpdator::findPhiInVertex(const FreeTrajectoryState& fts, const double& rc, const GeomDetEnumerators::Location location) const{
00316
00317 double pi = 4.*atan(1.);
00318
00319
00320 double acharge=fts.parameters().charge();
00321 double phiclus=fts.parameters().position().phi();
00322 double psi;
00323 if(location==GeomDetEnumerators::barrel){
00324 double xrclus=fts.parameters().position().perp();
00325 double xdouble=xrclus/(2.*rc);
00326 psi= phiclus+acharge*asin(xdouble);
00327 } else {
00328 double zclus=fts.parameters().position().z();
00329 double pl=fts.parameters().momentum().z();
00330 psi=phiclus+acharge*0.006*fabs(zclus)/fabs(pl);
00331 }
00332 double phic = psi-acharge*pi/2.;
00333 #ifdef CORRECT_DEBUG
00334 cout<<"Momentum of track="<<fts.parameters().momentum().perp()<<
00335 " rad of previous cluster= "<<fts.parameters().position().perp()<<
00336 " phi of previous cluster="<<fts.parameters().position().phi()<<endl;
00337 cout<<" position of the previous cluster="<<fts.parameters().position()<<endl;
00338 cout<<"radius of track="<<rc<<endl;
00339 cout<<"acharge="<<acharge<<endl;
00340 cout<<"psi="<<psi<<endl;
00341 cout<<"phic="<<phic<<" pi="<<pi<<" pi2="<<pi2<<endl;
00342 #endif
00343
00344 return phic;
00345 }
00346
00347 TrajectoryStateOnSurface HICMuonUpdator::updateBarrel(vector<double>& rhit, vector<double>& zhit,
00348 vector<double>& dphihit, vector<double>& drhit,
00349 vector<double>& ehitstrip, vector<double>& dehitphi,
00350 const TransientTrackingRecHit::ConstRecHitPointer& pRecHit,
00351 const TransientTrackingRecHit::ConstRecHitPointer& nRecHit,
00352 const TrajectoryStateOnSurface& nTsos,
00353 double& chirz, double& chirf, int& tType) const{
00354
00355
00356 TrajectoryStateOnSurface badtsos;
00357 double pi = 4.*atan(1.);
00358 double twopi=8.*atan(1.);
00359
00360
00361
00362 double ch1,dphi,dr,ptnew;
00363 double co1,co2;
00364 bool fitrf,fitrz;
00365
00366
00367
00368 fitrz=this->linefit2(rhit,zhit,ehitstrip,co1,co2,chirz);
00369
00370 #ifdef UPDATOR_BARREL_DEBUG
00371 cout<<"UPDATE::BARREL::line fit rz= "<<fitrz<<" chirz="<<chirz<<endl;
00372 cout<<" co1="<<co1<<" co2="<<co2<<endl;
00373 #endif
00374
00375 if(!fitrz) {
00376 #ifdef DEBUG
00377 cout<<"UPDATE::BARREL::line fit failed rz= "<<fitrz<<" chirz="<<chirz<<endl;
00378 #endif
00379
00380 return badtsos;
00381 }
00382 if(dphihit.size()>1){
00383 fitrf=this->linefit1(dphihit,drhit,dehitphi,ch1,chirf);
00384
00385 #ifdef UPDATOR_BARREL_DEBUG
00386 cout<<"UPDATE::BARREL::line fit dphi= "<<fitrf<<" chirf="<<chirf<<endl;
00387 cout<<" ch1="<<ch1<<endl;
00388 #endif
00389
00390 if(!fitrf) {
00391 #ifdef DEBUG
00392 cout<<"UPDATE::BARREL::line fit failed dphi= "<<fitrf<<" chirz="<<chirf<<endl;
00393 #endif
00394 return badtsos;
00395 }
00396 }else{
00397
00398 chirf = 0.;
00399 dphi=fabs(dphihit.back());
00400 dr=fabs(drhit.back());
00401 if(dphi > pi) dphi = twopi-dphi;
00402 ch1=dphi/dr;
00403
00404 #ifdef UPDATOR_BARREL_DEBUG
00405 cout<<"UPDATE::BARREL::line calc dphi= "<<dphi<<" dr="<<dr<<" chirf="<<chirf<<endl;
00406 cout<<" ch1="<<ch1<<endl;
00407 #endif
00408
00409 }
00410
00411
00412 ptnew=0.006/ch1;
00413 GlobalPoint xrhit = nRecHit->globalPosition();
00414 TrackCharge aCharge = nTsos.freeTrajectoryState()->parameters().charge();
00415 double phiclus=xrhit.phi();
00416 double xrclus=xrhit.perp();
00417
00418 double rc=100.*ptnew/(0.3*4.);
00419 double xdouble=xrclus/(2.*rc);
00420 double psi=phiclus-aCharge*asin(xdouble);
00421 double pznew=ptnew/co1;
00422 double znew=(xrclus-co2)/co1;
00423 double delphinew=fabs(0.006*drhit.back()/ptnew);
00424 double phinew=pRecHit->globalPosition().phi()+aCharge*delphinew;
00425 GlobalVector pnew(ptnew*cos(psi),ptnew*sin(psi),pznew);
00426 GlobalPoint xnew(xrclus*cos(phinew),xrclus*sin(phinew),znew);
00427 AlgebraicSymMatrix55 m;
00428 m(0,0)=ptnew; m(1,1)=thePhiWin,
00429 m(2,2)=theZWin,
00430 m(3,3)=thePhiWin,
00431 m(4,4)=theZWin;
00432
00433 #ifdef UPDATOR_BARREL_DEBUG
00434 cout<< "MuUpdator::xnew=" << xnew<<endl;
00435 #endif
00436
00437 TrajectoryStateOnSurface tsos(
00438 GlobalTrajectoryParameters(xnew, pnew, aCharge, field),
00439 CurvilinearTrajectoryError(m), nTsos.surface());
00440
00441
00442
00443 return tsos;
00444 }
00445 TrajectoryStateOnSurface HICMuonUpdator::updateEndcap(vector<double>& rhit, vector<double>& zhit,
00446 vector<double>& dphihit, vector<double>& drhit,
00447 vector<double>& ehitstrip, vector<double>& dehitphi,
00448 const TransientTrackingRecHit::ConstRecHitPointer& pRecHit,
00449 const TransientTrackingRecHit::ConstRecHitPointer& nRecHit,
00450 const TrajectoryStateOnSurface& nTsos,
00451 double& chirz, double& chirf, int& tType) const{
00452
00453
00454 double pi = 4.*atan(1.);
00455 double twopi=8.*atan(1.);
00456
00457
00458 TrajectoryStateOnSurface badtsos;
00459
00460
00461
00462 double ch1,dphi,dr;
00463 double co1,co2;
00464 bool fitrf,fitrz;
00465
00466 #ifdef UPDATOR_ENDCAP_DEBUG
00467 cout<<"updateEndcap switched on"<<endl;
00468 #endif
00469
00470
00471
00472 fitrz=this->linefit2(rhit,zhit,ehitstrip,co1,co2,chirz);
00473
00474 #ifdef UPDATOR_ENDCAP_DEBUG
00475 cout<<"line fit rz= "<<fitrz<<" chirz="<<chirz<<endl;
00476 cout<<" co1="<<co1<<" co2="<<co2<<endl;
00477 #endif
00478
00479 if(!fitrz) {
00480 #ifdef DEBUG
00481 cout<<"UPDATE::ENDCAP::line fit failed rz= "<<fitrz<<" chirz="<<chirz<<endl;
00482 #endif
00483 return badtsos;
00484 }
00485 if(dphihit.size()>1){
00486 fitrf=this->linefit1(dphihit,drhit,dehitphi,ch1,chirf);
00487 if(zhit.front()<0.) ch1=-1.*ch1;
00488 #ifdef UPDATOR_ENDCAP_DEBUG
00489 cout<<"MuUpdate::barrel::line fit dphi= "<<fitrf<<" chirf="<<chirf<<endl;
00490 cout<<" ch1="<<ch1<<endl;
00491 #endif
00492 if(!fitrf) {
00493 #ifdef DEBUG
00494 cout<<"UPDATE::ENDCAP::line fit failed dphi= "<<fitrf<<" chirz="<<chirf<<endl;
00495 #endif
00496
00497 return badtsos;
00498 }
00499 }else{
00500 dphi=fabs(dphihit.back());
00501 dr=fabs(drhit.back());
00502 if(dphi > pi) dphi = twopi-dphi;
00503 ch1=dphi/dr;
00504 if(zhit.front()<0.) ch1=-1.*ch1;
00505 chirf = 0.;
00506 #ifdef UPDATOR_ENDCAP_DEBUG
00507 cout<< "MuUpdate::barrel::linedphi=" << dphi <<" dz= "<< dr << " ch1= " <<ch1<<" pznew= "<<0.006/ch1<<endl;
00508 #endif
00509 }
00510
00511
00512 double pznew=0.006/ch1;
00513
00514 GlobalPoint xrhit = nRecHit->globalPosition();
00515
00516 TrackCharge aCharge = nTsos.freeTrajectoryState()->charge();
00517
00518 double phiclus=xrhit.phi();
00519
00520 double xzclus=xrhit.z();
00521
00522 double psi=phiclus-aCharge*0.006*fabs(xzclus-zvert)/fabs(pznew);
00523
00524 double ptnew=pznew*co1;
00525
00526 double xrclus=co1*xzclus+co2;
00527
00528 double delphinew=fabs(0.006*drhit.back()/pznew);
00529
00530 double phinew=pRecHit->globalPosition().phi()+aCharge*delphinew;
00531
00532 GlobalVector pnew(ptnew*cos(psi),ptnew*sin(psi),pznew);
00533
00534 GlobalPoint xnew(xrclus*cos(phinew),xrclus*sin(phinew),xzclus);
00535
00536
00537
00538
00539 #ifdef UPDATOR_ENDCAP_DEBUG
00540 cout<< "MuUpdator::xnew=" << xnew<<endl;
00541 #endif
00542
00543
00544 AlgebraicSymMatrix55 m;
00545 m(0,0)=pznew; m(1,1)=thePhiWin,
00546 m(2,2)=theZWin,
00547 m(3,3)=thePhiWin,
00548 m(4,4)=theZWin;
00549
00550 TrajectoryStateOnSurface tsos(
00551 GlobalTrajectoryParameters(xnew, pnew, aCharge, field),
00552 CurvilinearTrajectoryError(m), nTsos.surface());
00553
00554
00555 return tsos;
00556 }
00557
00558
00559
00560
00561