00001 #include "RecoHI/HiMuonAlgos/interface/DiMuonSeedGeneratorHIC.h"
00002 #include "DataFormats/TrackerRecHit2D/interface/SiStripMatchedRecHit2DCollection.h"
00003 #include "DataFormats/TrackerRecHit2D/interface/SiStripRecHit2DCollection.h"
00004 #include "DataFormats/TrajectorySeed/interface/TrajectorySeedCollection.h"
00005 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00006 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00007 #include "TrackingTools/MeasurementDet/interface/MeasurementDet.h"
00008 #include "DataFormats/Common/interface/Handle.h"
00009
00010
00011 using namespace edm;
00012 using namespace std;
00013
00014
00015 namespace cms {
00016 DiMuonSeedGeneratorHIC::DiMuonSeedGeneratorHIC(edm::InputTag rphirecHitsTag0,
00017 const MagneticField* magfield0,
00018 const GeometricSearchTracker* theTracker0,
00019 const HICConst* hh,
00020 const string bb,
00021 int aMult = 1)
00022 {
00023
00024
00025
00026 theTracker = theTracker0;
00027 theHICConst = hh;
00028 theLowMult = aMult;
00029 magfield = magfield0;
00030 rphirecHitsTag = rphirecHitsTag0;
00031 TTRHbuilder = 0;
00032 builderName = bb;
00033
00034 thePropagator=new PropagatorWithMaterial(oppositeToMomentum,0.1057,&(*magfield) );
00035
00036 }
00037
00038 map<DetLayer*,DiMuonSeedGeneratorHIC::SeedContainer> DiMuonSeedGeneratorHIC::produce(const edm::Event& e, const edm::EventSetup& iSetup,
00039 FreeTrajectoryState& theFtsTracker,
00040 TrajectoryStateOnSurface& newtsos,
00041 FreeTrajectoryState& theFtsMuon,
00042 const TransientTrackingRecHitBuilder* RecHitBuilder,
00043 const MeasurementTracker* measurementTracker,
00044 vector<DetLayer*>* theDetLayer ) {
00045
00046
00047 theMeasurementTracker = measurementTracker;
00048 theLayerMeasurements = new LayerMeasurements(theMeasurementTracker);
00049
00050
00051
00052 std::map<DetLayer*,DiMuonSeedGeneratorHIC::SeedContainer> seedMap;
00053
00054
00055 bl = theTracker->barrelLayers();
00056 fpos = theTracker->posForwardLayers();
00057 fneg = theTracker->negForwardLayers();
00058
00059 if(TTRHbuilder == 0){
00060 edm::ESHandle<TransientTrackingRecHitBuilder> theBuilderHandle;
00061 iSetup.get<TransientRecHitRecord>().get(builderName,theBuilderHandle);
00062 TTRHbuilder = theBuilderHandle.product();
00063 }
00064
00065
00066
00067
00068
00069 int nSig =3;
00070 bool itrust=true;
00071 HICSeedMeasurementEstimator theEstimator(itrust,nSig);
00072
00073
00074
00075 double phipred=0.; double zpred=0.; double phiupd=0.;double zupd=0.;
00076
00077 for( vector<DetLayer* >::const_iterator ml=theDetLayer->begin(); ml != theDetLayer->end(); ml++)
00078 {
00079
00080
00081
00082 SeedContainer seedContainer;
00083
00084 const BarrelDetLayer* bl = dynamic_cast<const BarrelDetLayer*>(*ml);
00085 const ForwardDetLayer* fl = dynamic_cast<const ForwardDetLayer*>(*ml);
00086 if( bl != 0 )
00087 {
00088
00089 phipred = (double)theHICConst->phicut[12];
00090 phiupd = (double)theHICConst->phiro[12];
00091 zpred = (double)theHICConst->zcut[12];
00092 zupd = (double)theHICConst->tetro[12];
00093
00094 }
00095 else
00096 {
00097 if ( fl != 0 )
00098 {
00099
00100
00101 phipred = (double)theHICConst->phicutf[13];
00102 phiupd = (double)theHICConst->phirof[13];
00103 zpred = (double)theHICConst->tetcutf[13];
00104 zupd = (double)theHICConst->tetrof[13];
00105
00106
00107
00108 }
00109 }
00110
00111 theEstimator.set(phipred, zpred);
00112 #ifdef DEBUG
00113 std::cout<<" DiMuonSeedGenerator::estimator::set cuts "<<std::endl;
00114 #endif
00115 std::vector<TrajectoryMeasurement> vTM = theLayerMeasurements->measurements((**ml),newtsos, *thePropagator, theEstimator);
00116 #ifdef DEBUG
00117 std::cout<<" DiMuonSeedGenerator::Size of compatible TM found by measurements "<<vTM.size()<<std::endl;
00118 #endif
00119
00120
00121
00122 for(std::vector<TrajectoryMeasurement>::iterator it=vTM.begin(); it!=vTM.end(); it++)
00123 {
00124
00125 #ifdef DEBUG
00126 const TransientTrackingRecHit::ConstRecHitPointer rh = (*it).recHit();
00127 if(!(rh->isValid())) {
00128 cout<<" DiMuonSeedGenerator::rechit not valid "<<endl;
00129 } else {
00130 GlobalPoint realhit = (*rh).globalPosition();
00131 cout<<" DiMuonSeedGenerator::Compatible TM: "<<realhit.perp()<<" "
00132 <<realhit.phi()<<" "<<realhit.z()<<endl;
00133 }
00134 #endif
00135
00136 pair<TrajectoryMeasurement,bool> newtmr;
00137
00138 if( bl != 0 )
00139 {
00140 #ifdef DEBUG
00141 cout<<" DiMuonSeedGenerator::Barrel seed "<<endl;
00142 #endif
00143 newtmr = barrelUpdateSeed(theFtsMuon,(*it));
00144
00145 }
00146 else
00147 {
00148 #ifdef DEBUG
00149 cout<<" DiMuonSeedGenerator::Endcap seed "<<endl;
00150 #endif
00151 newtmr = forwardUpdateSeed(theFtsMuon,(*it));
00152 }
00153 #ifdef DEBUG
00154 cout<<" DiMuonSeedGenerator::Estimate seed "<<newtmr.first.estimate()<<" True or false "<<newtmr.second<<endl;
00155 #endif
00156 if(newtmr.second) seedContainer.push_back(DiMuonTrajectorySeed(newtmr.first,theFtsMuon,theLowMult));
00157 }
00158 seedMap[*ml] = seedContainer;
00159 }
00160 delete theLayerMeasurements;
00161 return seedMap;
00162
00163 }
00164
00165 pair<TrajectoryMeasurement,bool> DiMuonSeedGeneratorHIC::barrelUpdateSeed (
00166 const FreeTrajectoryState& FTSOLD,
00167 const TrajectoryMeasurement& tm
00168 ) const
00169 {
00170
00171 bool good=false;
00172 #ifdef DEBUG
00173 std::cout<<" DiMuonSeedGeneratorHIC::barrelUpdateSeed::BarrelSeed "<<std::endl;
00174 #endif
00175 const DetLayer* dl = tm.layer();
00176
00177 const TransientTrackingRecHit::ConstRecHitPointer rh = tm.recHit();
00178
00179 if(!(rh->isValid()))
00180 {
00181 #ifdef DEBUG
00182 std::cout<<" DiMuonSeedGeneratorHIC::barrelUpdateSeed::hit is not valid "<<std::endl;
00183 #endif
00184 return pair<TrajectoryMeasurement,bool>(tm,good);
00185 }
00186 #ifdef DEBUG
00187 std::cout<<" DiMuonSeedGeneratorHIC::barrelUpdateSeed::hit is valid "<<std::endl;
00188 #endif
00189
00190 FreeTrajectoryState FTS = *(tm.forwardPredictedState().freeTrajectoryState());
00191
00192
00193
00194
00195 int imin = 0;
00196 int imax = 0;
00197 int imin1 = 0;
00198 int imax1 = 0;
00199 double phi = FTSOLD.parameters().position().phi();
00200 double pt = FTS.parameters().momentum().perp();
00201 double aCharge = FTS.parameters().charge();
00202 AlgebraicSymMatrix55 e = FTS.curvilinearError().matrix();
00203
00204 double dptup = 0.35*pt;
00205 double dptdown = 0.7*pt;
00206 double ptshift = 0.22*pt;
00207
00208
00209
00210
00211
00212 int imax0 = (int)((pt+ptshift+dptup-theHICConst->ptboun)/theHICConst->step) + 1;
00213 int imin0 = (int)((pt+ptshift-dptdown-theHICConst->ptboun)/theHICConst->step) + 1;
00214 if( imin0 < 1 ) imin0 = 1;
00215 #ifdef DEBUG
00216 std::cout<<" DiMuonSeedGeneratorHIC::barrelUpdateSeed::imin0,imax0 "<<imin0<<" "<<imax0<<" pt,dpt "<<pt+ptshift<<" "<<dptup<<" "<<dptdown<<std::endl;
00217 #endif
00218
00219 double dens,df,ptmax,ptmin;
00220
00221 GlobalPoint realhit = (*rh).globalPosition();
00222 df = fabs(realhit.phi() - phi);
00223
00224 double pi=4.*atan(1.);
00225 double twopi=8.*atan(1.);
00226
00227 if(df > pi) df = twopi-df;
00228 if(df > 1.e-5)
00229 {
00230 dens = 1./df;
00231 }
00232 else
00233 {
00234 dens = 100000.;
00235 }
00236
00237
00238
00239
00240
00241
00242 ptmax = (dens-(double)(theHICConst->phias[26]))/(double)(theHICConst->phibs[26]) + theHICConst->ptbmax;
00243 ptmin = (dens-(double)(theHICConst->phiai[26]))/(double)(theHICConst->phibi[26]) + theHICConst->ptbmax;
00244 #ifdef DEBUG
00245 std::cout<<" Phias,phibs,phiai,phibi "<<theHICConst->phias[26]<<" "<<theHICConst->phibs[26]<<" "<<
00246 theHICConst->phiai[26]<<" "<<theHICConst->phibi[26]<<" "<<theHICConst->ptbmax<<std::endl;
00247 std::cout<<" ptmin= "<<ptmin<<" ptmax "<<ptmax<<std::endl;
00248 std::cout<<" ptboun "<<theHICConst->ptboun<<" "<<theHICConst->step<<std::endl;
00249 #endif
00250 imax = (int)((ptmax-theHICConst->ptboun)/theHICConst->step)+1;
00251 imin = (int)((ptmin-theHICConst->ptboun)/theHICConst->step)+1;
00252 if(imin > imax) {
00253 #ifdef DEBUG
00254 std::cout<<" imin>imax "<<imin<<" "<<imax<<std::endl;
00255 #endif
00256 return pair<TrajectoryMeasurement,bool>(tm,good);}
00257 if(imax < 1) {
00258 #ifdef DEBUG
00259 std::cout<<"imax < 1 "<<imax<<std::endl;
00260 #endif
00261 return pair<TrajectoryMeasurement,bool>(tm,good);}
00262
00263 imin1 = max(imin,imin0);
00264 imax1 = min(imax,imax0);
00265 if(imin1 > imax1) {
00266 #ifdef DEBUG
00267 std::cout<<" imin,imax "<<imin<<" "<<imax<<std::endl;
00268 std::cout<<" imin,imax "<<imin0<<" "<<imax0<<std::endl;
00269 std::cout<<" imin1>imax1 "<<imin1<<" "<<imax1<<std::endl;
00270 #endif
00271 return pair<TrajectoryMeasurement,bool>(tm,good);
00272 }
00273
00274
00275
00276
00277 double ptnew = theHICConst->ptboun + theHICConst->step * (imax1 + imin1)/2. - theHICConst->step/2.;
00278
00279
00280
00281
00282
00283 double dfmax = 1./((double)(theHICConst->phias[26])+(double)(theHICConst->phibs[26])*(ptnew-theHICConst->ptbmax));
00284 double dfmin = 1./((double)(theHICConst->phiai[26])+(double)(theHICConst->phibi[26])*(ptnew-theHICConst->ptbmax));
00285 double dfcalc = fabs(dfmax+dfmin)/2.;
00286 double phinew = phi+aCharge*dfcalc;
00287
00288
00289
00290
00291
00292 double rad = 100.*ptnew/(0.3*4.);
00293 double alf = 2.*asin(realhit.perp()/rad);
00294 double alfnew = phinew - aCharge*alf;
00295
00296
00297
00298
00299
00300 double delx = realhit.z()-theHICConst->zvert;
00301 double delr = sqrt( realhit.y()*realhit.y()+realhit.x()*realhit.x() );
00302 double theta = atan2(delr,delx);
00303
00304
00305
00306
00307
00308
00309 GlobalPoint xnew0( realhit.x(), realhit.y(), realhit.z() );
00310
00311 GlobalVector pnew0(ptnew*cos(alfnew),ptnew*sin(alfnew),ptnew/tan(theta));
00312
00313 AlgebraicSymMatrix55 m;
00314 m(0,0) = 0.5*ptnew; m(1,1) = theHICConst->phiro[12];
00315 m(2,2) = theHICConst->tetro[12];
00316 m(3,3) = theHICConst->phiro[12];
00317 m(4,4) = theHICConst->tetro[12];
00318
00319 TrajectoryStateOnSurface updatedTsosOnDet=TrajectoryStateOnSurface
00320 ( GlobalTrajectoryParameters( xnew0, pnew0, (int)aCharge, &(*magfield) ),
00321 CurvilinearTrajectoryError(m), dl->surface() );
00322
00323 float estimate = 1.;
00324 TrajectoryMeasurement newtm(tm.forwardPredictedState(), updatedTsosOnDet, rh, estimate, dl );
00325 good=true;
00326 pair<TrajectoryMeasurement,bool> newtmr(newtm,good);
00327
00328 return newtmr;
00329 }
00330
00331 pair<TrajectoryMeasurement,bool> DiMuonSeedGeneratorHIC::forwardUpdateSeed (
00332 const FreeTrajectoryState& FTSOLD,
00333 const TrajectoryMeasurement& tm
00334 ) const
00335 {
00336 bool good=false;
00337 #ifdef DEBUG
00338 std::cout<<" DiMuonSeedGeneratorHIC::forwardUpdateSeed::EndcapSeed::start "<<std::endl;
00339 #endif
00340 const DetLayer* dl = tm.layer();
00341
00342 const TransientTrackingRecHit::ConstRecHitPointer rh = tm.recHit();
00343
00344 if(!(rh->isValid()))
00345 {
00346 #ifdef DEBUG
00347 std::cout<<" DiMuonSeedGeneratorHIC::forwardUpdateSeed::EndcapSeed::EndcapSeed::hit is not valid "<<std::endl;
00348 #endif
00349
00350 return pair<TrajectoryMeasurement,bool>(tm,good);
00351 }
00352
00353 #ifdef DEBUG
00354 std::cout<<" DiMuonSeedGeneratorHIC::forwardUpdateSeed::EndcapSeed::EndcapSeed::valid "<<std::endl;
00355 #endif
00356
00357 FreeTrajectoryState FTS = *(tm.forwardPredictedState().freeTrajectoryState());
00358
00359
00360
00361
00362
00363 double phi = FTSOLD.parameters().position().phi();
00364 double aCharge = FTS.parameters().charge();
00365 AlgebraicSymMatrix55 e = FTS.curvilinearError().matrix();
00366 double pt = FTS.parameters().momentum().perp();
00367
00368
00369
00370
00371 double pi=4.*atan(1.);
00372 double twopi=8.*atan(1.);
00373
00374
00375 GlobalPoint realhit = rh->globalPosition();
00376
00377
00378
00379 double df = fabs(realhit.phi() - phi);
00380
00381 if(df > pi) df = twopi-df;
00382
00383 #ifdef DEBUG
00384 cout<<" DiMuonSeedGeneratorHIC::forwardUpdateSeed::phipred::phihit::df "<<phi<<" "<<realhit.phi()<<" "<<df<<endl;
00385 #endif
00386
00387
00388
00389
00390
00391 double delx = realhit.z() - theHICConst->zvert;
00392 double delr = sqrt(realhit.y()*realhit.y()+realhit.x()*realhit.x());
00393 double theta = atan2( delr, delx );
00394 double ptmin = 0.;
00395 double ptmax = 0.;
00396 double ptnew = 0.;
00397 double pznew = 0.;
00398
00399
00400
00401 if( fabs(FTSOLD.parameters().momentum().eta()) > 1.9 )
00402 {
00403 #ifdef DEBUG
00404 cout<<" First parametrization "<<df<<endl;
00405 #endif
00406 pznew = fabs(( df - 0.0191878 )/(-0.0015952))/3.;
00407
00408 if( df > 0.1 ) pznew = 5.;
00409 if( fabs(pznew)<3.) pznew = 3.;
00410
00411 if( FTSOLD.parameters().position().z() < 0. ) pznew = (-1)*pznew;
00412 ptnew = pznew * tan( theta );
00413 }
00414 if( fabs(FTSOLD.parameters().momentum().eta()) > 1.7 && fabs(FTSOLD.parameters().momentum().eta()) < 1.9 )
00415 {
00416 #ifdef DEBUG
00417 cout<<" Second parametrization "<<df<<endl;
00418 #endif
00419 pznew = fabs(( df - 0.38 )/(-0.009))/3.;
00420 if( fabs(pznew)<2.) pznew = 2.;
00421
00422 if( FTSOLD.parameters().position().z() < 0. ) pznew = (-1)*pznew;
00423 ptnew = pznew * tan( theta );
00424 }
00425 if( fabs(FTSOLD.parameters().momentum().eta()) > 1.6 && fabs(FTSOLD.parameters().momentum().eta()) < 1.7 )
00426 {
00427 #ifdef DEBUG
00428 cout<<" Third parametrization "<<df<<endl;
00429 #endif
00430 pznew = fabs(( df - 0.9 )/(-0.02))/3.;
00431 if( fabs(pznew)<1.) pznew = 1.;
00432 if( FTSOLD.parameters().position().z() < 0. ) pznew = (-1)*pznew;
00433 ptnew = pznew * tan( theta );
00434 }
00435 if( fabs(FTSOLD.parameters().momentum().eta()) > 0.7 && fabs(FTSOLD.parameters().momentum().eta()) < 1.6 )
00436 {
00437 #ifdef DEBUG
00438 cout<<" Forth parametrization "<<df<<endl;
00439 #endif
00440 double dfinv = 0.;
00441 if( df < 0.0000001 ) {
00442 dfinv = 1000000.;
00443 }
00444 else
00445 {
00446 dfinv = 1/df;
00447 }
00448 ptmin = (dfinv - 4.)/0.7 + 3.;
00449 if( ptmin < 2. ) ptmin = 2.;
00450 ptmax = (dfinv - 0.5)/0.3 + 3.;
00451 ptnew = ( ptmin + ptmax )/2.;
00452 pznew = ptnew/tan( theta );
00453
00454
00455 #ifdef DEBUG
00456 std::cout<<" Paramters of algorithm "<<df<<" "<<theHICConst->forwparam[1]<<" "<<theHICConst->forwparam[0]<<std::endl;
00457 std::cout<<" dfinv "<<dfinv<<" ptmax "<<ptmax<<" ptmin "<<ptmin<<std::endl;
00458
00459 #endif
00460 }
00461
00462
00463
00464 if( (pt - ptnew)/pt < -2 || (pt - ptnew)/pt > 1 )
00465 {
00466 #ifdef DEBUG
00467 cout<<" Return fake 0 pt::ptnew "<<pt<<" "<<ptnew<<endl;
00468 #endif
00469 return pair<TrajectoryMeasurement,bool>(tm,good);
00470 }
00471
00472
00473
00474
00475 double alf = theHICConst->atra * ( realhit.z() - theHICConst->zvert )/fabs(pznew);
00476 double alfnew = realhit.phi() + aCharge*alf;
00477 GlobalPoint xnew0(realhit.x(), realhit.y(), realhit.z());
00478 GlobalVector pnew0( ptnew*cos(alfnew), ptnew*sin(alfnew), pznew );
00479 #ifdef DEBUG
00480 cout<<" Start recalculation 1 FTSOLD eta, r hit, pt "<<FTSOLD.parameters().momentum().eta()<<" "<<realhit.perp()<<
00481 " "<<FTSOLD.parameters().momentum().perp()<<endl;
00482 #endif
00483 if( fabs(FTSOLD.parameters().momentum().eta()) < 1.7 && fabs(FTSOLD.parameters().momentum().eta()) > 0.8 )
00484 {
00485 if( realhit.perp() < 80. ) {
00486
00487 #ifdef DEBUG
00488 cout<<" Return fake 1 "<<realhit.perp()<<endl;
00489 #endif
00490 return pair<TrajectoryMeasurement,bool>(tm,good);
00491 }
00492 }
00493
00494
00495 if( FTSOLD.parameters().momentum().perp() > 2.0){
00496 if( fabs(FTSOLD.parameters().momentum().eta()) < 2.0 && fabs(FTSOLD.parameters().momentum().eta()) >= 1.7 )
00497 {
00498 if( realhit.perp() > 100. || realhit.perp() < 60. ) {
00499 #ifdef DEBUG
00500 cout<<" Return fake 2 "<<endl;
00501 #endif
00502 return pair<TrajectoryMeasurement,bool>(tm,good);
00503 }
00504 }
00505 if( fabs(FTSOLD.parameters().momentum().eta()) < 2.4 && fabs(FTSOLD.parameters().momentum().eta()) >= 2.0 )
00506 {
00507 if( realhit.perp() > 75. || realhit.perp() < 40. ) {
00508
00509 #ifdef DEBUG
00510 cout<<" Return fake 3 "<<endl;
00511 #endif
00512 return pair<TrajectoryMeasurement,bool>(tm,good);
00513 }
00514 }
00515
00516 }
00517 else
00518 {
00519 if( fabs(FTSOLD.parameters().momentum().eta()) < 2.0 && fabs(FTSOLD.parameters().momentum().eta()) >= 1.7 )
00520 {
00521 if( realhit.perp() > 84. || realhit.perp() < 40. ) {
00522 #ifdef DEBUG
00523 cout<<" Return fake 4 "<<endl;
00524 #endif
00525 return pair<TrajectoryMeasurement,bool>(tm,good);
00526 }
00527 }
00528 if( fabs(FTSOLD.parameters().momentum().eta()) < 2.4 && fabs(FTSOLD.parameters().momentum().eta()) >= 2.0 )
00529 {
00530 if( realhit.perp() > 84. || realhit.perp() < 40. ) {
00531 #ifdef DEBUG
00532 cout<<" Return fake 5 "<<endl;
00533 #endif
00534 return pair<TrajectoryMeasurement,bool>(tm,good);
00535 }
00536 }
00537 }
00538 #ifdef DEBUG
00539 cout<<" Create new TM "<<endl;
00540 #endif
00541 AlgebraicSymMatrix55 m;
00542 m(0,0) = fabs(0.5*pznew);
00543 m(1,1) = theHICConst->phiro[13];
00544 m(2,2) = theHICConst->tetro[13];
00545 m(3,3) = theHICConst->phiro[13];
00546 m(4,4) = theHICConst->tetro[13];
00547
00548 TrajectoryStateOnSurface updatedTsosOnDet=TrajectoryStateOnSurface
00549 (GlobalTrajectoryParameters( xnew0, pnew0, (int)aCharge, &(*magfield) ),
00550 CurvilinearTrajectoryError(m), dl->surface() );
00551
00552 float estimate=1.;
00553 TrajectoryMeasurement newtm(tm.forwardPredictedState(), updatedTsosOnDet, rh,estimate, dl);
00554 good=true;
00555 pair<TrajectoryMeasurement,bool> newtmr(newtm,good);
00556 #ifdef DEBUG
00557 std::cout<<" Endcap newtm estimate= "<<newtmr.first.estimate()<<" "<<newtmr.second<<" pt "<<pnew0.perp()<<" pz "<<pnew0.z()<<std::endl;
00558 #endif
00559 return newtmr;
00560 }
00561 }