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