00001 #include "RecoTracker/ConversionSeedGenerators/interface/SeedForPhotonConversionFromQuadruplets.h"
00002
00003 #include <TVector3.h>
00004 #include "RecoTracker/ConversionSeedGenerators/interface/Conv4HitsReco.h"
00005
00006 #include "TrackingTools/KalmanUpdators/interface/KFUpdator.h"
00007 #include "RecoTracker/TkSeedGenerator/interface/FastHelix.h"
00008 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00009 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
00010 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00011 #include "MagneticField/Engine/interface/MagneticField.h"
00012 #include "MagneticField/Records/interface/IdealMagneticFieldRecord.h"
00013 #include "TrackingTools/Records/interface/TrackingComponentsRecord.h"
00014 #include "TrackingTools/Records/interface/TransientRecHitRecord.h"
00015 #include "TrackingTools/MaterialEffects/interface/PropagatorWithMaterial.h"
00016 #include "FWCore/Framework/interface/ESHandle.h"
00017 #include "TrackingTools/GeomPropagators/interface/PropagationExceptions.h"
00018 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00019 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateOnSurface.h"
00020 #include "RecoTracker/TransientTrackingRecHit/interface/TSiStripRecHit2DLocalPos.h"
00021
00022
00023
00024 template <class T> T sqr( T t) {return t*t;}
00025
00026 const TrajectorySeed * SeedForPhotonConversionFromQuadruplets::trajectorySeed(
00027 TrajectorySeedCollection & seedCollection,
00028 const SeedingHitSet & phits,
00029 const SeedingHitSet & mhits,
00030 const TrackingRegion & region,
00031 const edm::EventSetup& es,
00032 std::stringstream& ss,
00033 std::vector<Quad>& quadV)
00034 {
00035
00036
00037
00038 pss = &ss;
00039
00040 if ( phits.size() < 2) return 0;
00041 if ( mhits.size() < 2) return 0;
00042
00043
00044
00045
00046
00047
00048
00049 #ifdef mydebug_sguazz
00050 std::cout << " --------------------------------------------------------------------------" << "\n";
00051 std::cout << " Starting a hit quad fast reco " << "\n";
00052 std::cout << " --------------------------------------------------------------------------" << "\n";
00053 #endif
00054
00055
00056
00057 TransientTrackingRecHit::ConstRecHitPointer ptth1 = phits[0];
00058 TransientTrackingRecHit::ConstRecHitPointer ptth2 = phits[1];
00059 TransientTrackingRecHit::ConstRecHitPointer mtth1 = mhits[0];
00060 TransientTrackingRecHit::ConstRecHitPointer mtth2 = mhits[1];
00061
00062 GlobalPoint vHit[4];
00063 vHit[0]=ptth2->globalPosition();
00064 vHit[1]=ptth1->globalPosition();
00065 vHit[2]=mtth1->globalPosition();
00066 vHit[3]=mtth2->globalPosition();
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 GlobalPoint vgPhotVertex=region.origin();
00080 TVector3 vPhotVertex(vgPhotVertex.x(), vgPhotVertex.y(), vgPhotVertex.z());
00081
00082 TVector3 h1(vHit[0].x(),vHit[0].y(),vHit[0].z());
00083 TVector3 h2(vHit[1].x(),vHit[1].y(),vHit[1].z());
00084 TVector3 h3(vHit[2].x(),vHit[2].y(),vHit[2].z());
00085 TVector3 h4(vHit[3].x(),vHit[3].y(),vHit[3].z());
00086
00087 Conv4HitsReco quad(vPhotVertex, h1, h2, h3, h4);
00088 quad.SetMaxNumberOfIterations(100);
00089 #ifdef mydebug_sguazz
00090 quad.Dump();
00091 #endif
00092 TVector3 candVtx;
00093 double candPtPlus, candPtMinus;
00094
00095 double rPlus, rMinus;
00096 int nite = quad.ConversionCandidate(candVtx, candPtPlus, candPtMinus);
00097
00098 if ( ! (nite && abs(nite) < 25 && nite != -1000 && nite != -2000) ) return 0;
00099
00100 TVector3 plusCenter = quad.GetPlusCenter(rPlus);
00101 TVector3 minusCenter = quad.GetMinusCenter(rMinus);
00102
00103 #ifdef mydebug_sguazz
00104 std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << "\n";
00105 std::cout << " >>>>>>>>>>> Conv Cand: " << " Vertex X: " << candVtx.X() << " [cm] Y: " << candVtx.Y() << " [cm] pt+: " << candPtPlus<< " [GeV] pt-: " << candPtMinus << " [GeV]; #its: " << nite << "\n";
00106 #endif
00107
00108
00109
00110
00111 double quadPhotCotTheta = 0.;
00112 double quadZ0 = 0.;
00113 simpleGetSlope(ptth2, ptth1, mtth1, mtth2, region, quadPhotCotTheta, quadZ0);
00114
00115
00116 double quadPhotPhi = (candVtx-vPhotVertex).Phi();
00117
00118 TVector3 fittedPrimaryVertex(vgPhotVertex.x(), vgPhotVertex.y(),quadZ0);
00119
00120 candVtx.SetZ(candVtx.Perp()*quadPhotCotTheta+quadZ0);
00121 GlobalPoint convVtxGlobalPoint(candVtx.X(),candVtx.Y(),candVtx.Z());
00122
00123
00124
00125
00126
00127 Quad thisQuad;
00128 thisQuad.x = candVtx.X();
00129 thisQuad.y = candVtx.Y();
00130 thisQuad.z = candVtx.Z();
00131 thisQuad.ptPlus = candPtPlus;
00132 thisQuad.ptMinus = candPtMinus;
00133 thisQuad.cot = quadPhotCotTheta;
00134 if ( similarQuadExist(thisQuad, quadV) ) return 0;
00135
00136
00137
00138
00139 FastHelix helixPlus(ptth2->globalPosition(), ptth1->globalPosition(), convVtxGlobalPoint, es, convVtxGlobalPoint);
00140 GlobalTrajectoryParameters kinePlus = helixPlus.stateAtVertex().parameters();
00141 kinePlus = GlobalTrajectoryParameters(convVtxGlobalPoint,
00142 GlobalVector(candPtPlus*cos(quadPhotPhi),candPtPlus*sin(quadPhotPhi),candPtPlus*quadPhotCotTheta),
00143 1,
00144 & kinePlus.magneticField()
00145 );
00146
00147
00148
00149 FastHelix helixMinus(mtth2->globalPosition(), mtth1->globalPosition(), convVtxGlobalPoint, es, convVtxGlobalPoint);
00150 GlobalTrajectoryParameters kineMinus = helixMinus.stateAtVertex().parameters();
00151 kineMinus = GlobalTrajectoryParameters(convVtxGlobalPoint,
00152 GlobalVector(candPtMinus*cos(quadPhotPhi),candPtMinus*sin(quadPhotPhi),candPtMinus*quadPhotCotTheta),
00153 -1,
00154 & kineMinus.magneticField()
00155 );
00156
00157 float sinThetaPlus = sin(kinePlus.momentum().theta());
00158 float sinThetaMinus = sin(kineMinus.momentum().theta());
00159 float ptmin = region.ptMin();
00160
00161 GlobalVector vertexBounds(region.originRBound(),region.originRBound(),region.originZBound());
00162
00163 CurvilinearTrajectoryError errorPlus = initialError(vertexBounds, ptmin, sinThetaPlus);
00164 CurvilinearTrajectoryError errorMinus = initialError(vertexBounds, ptmin, sinThetaMinus);
00165 FreeTrajectoryState ftsPlus(kinePlus, errorPlus);
00166 FreeTrajectoryState ftsMinus(kineMinus, errorMinus);
00167
00168
00169
00170
00171
00172 #ifdef quadDispLine
00173 double vError = region.originZBound();
00174 if ( vError > 15. ) vError = 1.;
00175 std::cout << "QuadDispLine "
00176 << vgPhotVertex.x() << " " << vgPhotVertex.y() << " " << vgPhotVertex.z() << " " << vError << " "
00177 << vHit[0].x() << " " << vHit[0].y() << " " << vHit[0].z() << " " << sqrt(getSqrEffectiveErrorOnZ(ptth2, region)) << " "
00178 << vHit[1].x() << " " << vHit[1].y() << " " << vHit[1].z() << " " << sqrt(getSqrEffectiveErrorOnZ(ptth1, region)) << " "
00179 << vHit[2].x() << " " << vHit[2].y() << " " << vHit[2].z() << " " << sqrt(getSqrEffectiveErrorOnZ(mtth1, region)) << " "
00180 << vHit[3].x() << " " << vHit[3].y() << " " << vHit[3].z() << " " << sqrt(getSqrEffectiveErrorOnZ(mtth2, region)) << " "
00181 << candVtx.X() << " " << candVtx.Y() << " " << candVtx.Z() << " "
00182 << fittedPrimaryVertex.X() << " " << fittedPrimaryVertex.Y() << " " << fittedPrimaryVertex.Z() << " "
00183 << candPtPlus << " " << rPlus << " " << plusCenter.X() << " " << plusCenter.Y() << " "
00184 << candPtMinus << " " << rMinus << " " << minusCenter.X() << " " << minusCenter.Y() << " "
00185 << nite << " " << chi2 << "\n";
00186 #endif
00187 #ifdef mydebug_sguazz
00188 std::cout << " >>>>> Hit quad fast reco done >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << "\n";
00189 uint32_t detid;
00190 std::cout << "[SeedForPhotonConversionFromQuadruplets]\n ptth1 " ;
00191 detid=ptth1->geographicalId().rawId();
00192
00193 std::cout << " \t " << detid << " " << ptth1->localPosition() << " " << ptth1->globalPosition() ;
00194 detid=ptth2->geographicalId().rawId();
00195 std::cout << " \n\t ptth2 ";
00196
00197 std::cout << " \t " << detid << " " << ptth2->localPosition() << " " << ptth2->globalPosition()
00198 << "\nhelix momentum " << kinePlus.momentum() << " pt " << kinePlus.momentum().perp() << " radius " << 1/kinePlus.transverseCurvature() << " q " << kinePlus.charge();
00199 std::cout << " \n\t mtth1 ";
00200 detid=mtth1->geographicalId().rawId();
00201 std::cout << " \t " << detid << " " << mtth1->localPosition() << " " << mtth1->globalPosition() ;
00202 std::cout << " \n\t mtth2 ";
00203 detid=mtth2->geographicalId().rawId();
00204
00205 std::cout << " \t " << detid << " " << mtth2->localPosition() << " " << mtth2->globalPosition()
00206 << "\nhelix momentum " << kineMinus.momentum() << " pt " << kineMinus.momentum().perp() << " radius " << 1/kineMinus.transverseCurvature() << " q " << kineMinus.charge();
00207 std::cout << "\n <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << "\n";
00208 #endif
00209
00210 buildSeed(seedCollection,phits,ftsPlus,es);
00211 return buildSeed(seedCollection,mhits,ftsMinus,es);
00212
00213 }
00214
00215
00216 GlobalTrajectoryParameters SeedForPhotonConversionFromQuadruplets::initialKinematic(
00217 const SeedingHitSet & hits,
00218 const GlobalPoint & vertexPos,
00219 const edm::EventSetup& es,
00220 const float cotTheta) const
00221 {
00222 GlobalTrajectoryParameters kine;
00223
00224 TransientTrackingRecHit::ConstRecHitPointer tth1 = hits[0];
00225 TransientTrackingRecHit::ConstRecHitPointer tth2 = hits[1];
00226
00227
00228 FastHelix helix(tth2->globalPosition(), tth1->globalPosition(), vertexPos, es, vertexPos);
00229 kine = helix.stateAtVertex().parameters();
00230
00231
00232 if(fabs(cotTheta)<cotTheta_Max)
00233 kine = GlobalTrajectoryParameters(kine.position(),
00234 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta),
00235 kine.charge(),
00236 & kine.magneticField()
00237 );
00238 else
00239 kine = GlobalTrajectoryParameters(kine.position(),
00240 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta_Max),
00241 kine.charge(),
00242 & kine.magneticField()
00243 );
00244
00245 #ifdef mydebug_seed
00246 uint32_t detid;
00247 (*pss) << "[SeedForPhotonConversionFromQuadruplets] initialKinematic tth1 " ;
00248 detid=tth1->geographicalId().rawId();
00249 po.print(*pss, detid );
00250 (*pss) << " \t " << detid << " " << tth1->localPosition() << " " << tth1->globalPosition() ;
00251 detid= tth2->geographicalId().rawId();
00252 (*pss) << " \n\t tth2 ";
00253 po.print(*pss, detid );
00254 (*pss) << " \t " << detid << " " << tth2->localPosition() << " " << tth2->globalPosition()
00255 << "\nhelix momentum " << kine.momentum() << " pt " << kine.momentum().perp() << " radius " << 1/kine.transverseCurvature();
00256 #endif
00257
00258 edm::ESHandle<MagneticField> bfield;
00259 es.get<IdealMagneticFieldRecord>().get(bfield);
00260 bool isBOFF = ( std::abs(bfield->inTesla(GlobalPoint(0,0,0)).z()) < 1e-3 );
00261 if (isBOFF && (theBOFFMomentum > 0)) {
00262 kine = GlobalTrajectoryParameters(kine.position(),
00263 kine.momentum().unit() * theBOFFMomentum,
00264 kine.charge(),
00265 &*bfield);
00266 }
00267 return kine;
00268 }
00269
00270
00271
00272 CurvilinearTrajectoryError SeedForPhotonConversionFromQuadruplets::
00273 initialError(
00274 const GlobalVector& vertexBounds,
00275 float ptMin,
00276 float sinTheta) const
00277 {
00278
00279
00280 GlobalError vertexErr( sqr(vertexBounds.x()), 0,
00281 sqr(vertexBounds.y()), 0, 0,
00282 sqr(vertexBounds.z())
00283 );
00284
00285
00286 AlgebraicSymMatrix55 C = ROOT::Math::SMatrixIdentity();
00287
00288
00289
00290
00291 float sin2th = sqr(sinTheta);
00292 float minC00 = 1.0;
00293 C[0][0] = std::max(sin2th/sqr(ptMin), minC00);
00294 float zErr = vertexErr.czz();
00295 float transverseErr = vertexErr.cxx();
00296 C[3][3] = transverseErr;
00297 C[4][4] = zErr*sin2th + transverseErr*(1-sin2th);
00298
00299 return CurvilinearTrajectoryError(C);
00300 }
00301
00302 const TrajectorySeed * SeedForPhotonConversionFromQuadruplets::buildSeed(
00303 TrajectorySeedCollection & seedCollection,
00304 const SeedingHitSet & hits,
00305 const FreeTrajectoryState & fts,
00306 const edm::EventSetup& es) const
00307 {
00308
00309 edm::ESHandle<TrackerGeometry> tracker;
00310 es.get<TrackerDigiGeometryRecord>().get(tracker);
00311
00312
00313 edm::ESHandle<Propagator> propagatorHandle;
00314 es.get<TrackingComponentsRecord>().get(thePropagatorLabel, propagatorHandle);
00315 const Propagator* propagator = &(*propagatorHandle);
00316
00317
00318 KFUpdator updator;
00319
00320
00321
00322 TrajectoryStateOnSurface updatedState;
00323 edm::OwnVector<TrackingRecHit> seedHits;
00324
00325 const TrackingRecHit* hit = 0;
00326 for ( unsigned int iHit = 0; iHit < hits.size() && iHit<1; iHit++) {
00327 hit = hits[iHit]->hit();
00328 TrajectoryStateOnSurface state = (iHit==0) ?
00329 propagator->propagate(fts,tracker->idToDet(hit->geographicalId())->surface())
00330 : propagator->propagate(updatedState, tracker->idToDet(hit->geographicalId())->surface());
00331 if (!state.isValid()) return 0;
00332
00333 TransientTrackingRecHit::ConstRecHitPointer tth = hits[iHit];
00334
00335 TransientTrackingRecHit::RecHitPointer newtth = refitHit( tth, state);
00336
00337
00338 if (!checkHit(state,newtth,es)) return 0;
00339
00340 updatedState = updator.update(state, *newtth);
00341 if (!updatedState.isValid()) return 0;
00342
00343 seedHits.push_back(newtth->hit()->clone());
00344 #ifdef mydebug_seed
00345 uint32_t detid = hit->geographicalId().rawId();
00346 (*pss) << "\n[SeedForPhotonConversionFromQuadruplets] hit " << iHit;
00347 po.print(*pss, detid);
00348 (*pss) << " " << detid << "\t lp " << hit->localPosition()
00349 << " tth " << tth->localPosition() << " newtth " << newtth->localPosition() << " state " << state.globalMomentum().perp();
00350 #endif
00351 }
00352
00353
00354 PTrajectoryStateOnDet const & PTraj =
00355 trajectoryStateTransform::persistentState(updatedState, hit->geographicalId().rawId());
00356
00357 seedCollection.push_back( TrajectorySeed(PTraj,seedHits,alongMomentum));
00358 return &seedCollection.back();
00359 }
00360
00361 TransientTrackingRecHit::RecHitPointer SeedForPhotonConversionFromQuadruplets::refitHit(
00362 const TransientTrackingRecHit::ConstRecHitPointer &hit,
00363 const TrajectoryStateOnSurface &state) const
00364 {
00365
00366
00367
00368
00369
00370
00371
00372 return hit->clone(state);
00373 }
00374
00375
00376
00377
00378
00379 void SeedForPhotonConversionFromQuadruplets::
00380 stupidPrint(std::string s,float* d){
00381 (*pss) << "\n" << s << "\t";
00382 for(size_t i=0;i<2;++i)
00383 (*pss) << std::setw (60) << d[i] << std::setw(1) << " | ";
00384 }
00385
00386 void SeedForPhotonConversionFromQuadruplets::
00387 stupidPrint(std::string s,double* d){
00388 (*pss) << "\n" << s << "\t";
00389 for(size_t i=0;i<2;++i)
00390 (*pss) << std::setw (60) << d[i] << std::setw(1) << " | ";
00391 }
00392
00393 void SeedForPhotonConversionFromQuadruplets::
00394 stupidPrint(const char* s,GlobalPoint* d){
00395 (*pss) << "\n" << s << "\t";
00396 for(size_t i=0;i<2;++i)
00397 (*pss) << std::setw(20) << d[i] << " r " << d[i].perp() << " phi " << d[i].phi() << " | ";
00398 }
00399
00400 void SeedForPhotonConversionFromQuadruplets::
00401 stupidPrint(const char* s, GlobalPoint* d, int n){
00402 (*pss) << "\n" << s << "\n";
00403 for(int i=0;i<n;++i)
00404 (*pss) << std::setw(20) << d[i] << " r " << d[i].perp() << " phi " << d[i].phi() << "\n";
00405 }
00406
00407 #include "DataFormats/Math/interface/deltaPhi.h"
00408
00409 void SeedForPhotonConversionFromQuadruplets::
00410 bubbleSortVsPhi(GlobalPoint arr[], int n, GlobalPoint vtx) {
00411 bool swapped = true;
00412 int j = 0;
00413 GlobalPoint tmp;
00414 while (swapped) {
00415 swapped = false;
00416 j++;
00417 for (int i = 0; i < n - j; i++) {
00418 if ( reco::deltaPhi( (arr[i]-vtx).phi(), (arr[i + 1]-vtx).phi() ) > 0. ) {
00419 tmp = arr[i];
00420 arr[i] = arr[i + 1];
00421 arr[i + 1] = tmp;
00422 swapped = true;
00423 }
00424 }
00425 }
00426 }
00427
00428 void SeedForPhotonConversionFromQuadruplets::
00429 bubbleReverseSortVsPhi(GlobalPoint arr[], int n, GlobalPoint vtx) {
00430 bool swapped = true;
00431 int j = 0;
00432 GlobalPoint tmp;
00433 while (swapped) {
00434 swapped = false;
00435 j++;
00436 for (int i = 0; i < n - j; i++) {
00437 if ( reco::deltaPhi( (arr[i]-vtx).phi(), (arr[i + 1]-vtx).phi() ) < 0. ) {
00438 tmp = arr[i];
00439 arr[i] = arr[i + 1];
00440 arr[i + 1] = tmp;
00441 swapped = true;
00442 }
00443 }
00444 }
00445 }
00446
00447
00448 double SeedForPhotonConversionFromQuadruplets::
00449 simpleGetSlope(const TransientTrackingRecHit::ConstRecHitPointer &ohit, const TransientTrackingRecHit::ConstRecHitPointer &nohit, const TransientTrackingRecHit::ConstRecHitPointer &ihit, const TransientTrackingRecHit::ConstRecHitPointer &nihit, const TrackingRegion & region, double & cotTheta, double & z0){
00450
00451 double x[5], y[5], e2y[5];
00452
00453
00454
00455
00456 x[0] = ohit->globalPosition().perp();
00457 y[0] = ohit->globalPosition().z();
00458 e2y[0] = getSqrEffectiveErrorOnZ(ohit, region);
00459
00460 x[1] = nohit->globalPosition().perp();
00461 y[1] = nohit->globalPosition().z();
00462 e2y[1] = getSqrEffectiveErrorOnZ(nohit, region);
00463
00464 x[2] = nihit->globalPosition().perp();
00465 y[2] = nihit->globalPosition().z();
00466 e2y[2] = getSqrEffectiveErrorOnZ(nihit, region);
00467
00468 x[3] = ihit->globalPosition().perp();
00469 y[3] = ihit->globalPosition().z();
00470 e2y[3] = getSqrEffectiveErrorOnZ(ihit, region);
00471
00472
00473 x[4] = region.origin().perp();
00474 y[4] = region.origin().z();
00475 double vError = region.originZBound();
00476 if ( vError > 15. ) vError = 1.;
00477 e2y[4] = sqr(vError);
00478
00479 double e2z0;
00480 double chi2 = verySimpleFit(5, x, y, e2y, z0, e2z0, cotTheta);
00481
00482 return chi2;
00483
00484 }
00485
00486 double SeedForPhotonConversionFromQuadruplets::verySimpleFit(int size, double* ax, double* ay, double* e2y, double& p0, double& e2p0, double& p1){
00487
00488
00489 return 0;
00490 }
00491
00492 double SeedForPhotonConversionFromQuadruplets::getSqrEffectiveErrorOnZ(const TransientTrackingRecHit::ConstRecHitPointer &hit, const TrackingRegion & region){
00493
00494
00495
00496
00497
00498 double sqrProjFactor = sqr((hit->globalPosition().z()-region.origin().z())/(hit->globalPosition().perp()-region.origin().perp()));
00499 return (hit->globalPositionError().czz()+sqrProjFactor*hit->globalPositionError().rerr(hit->globalPosition()));
00500
00501 }
00502
00503 bool SeedForPhotonConversionFromQuadruplets::similarQuadExist(Quad & thisQuad, std::vector<Quad>& quadV){
00504
00505 BOOST_FOREACH( Quad quad, quadV )
00506 {
00507 double dx = thisQuad.x-quad.x;
00508 double dy = thisQuad.y-quad.y;
00509 double dz = abs(thisQuad.z-quad.z);
00510 if ( sqrt(dx*dx+dy*dy)<1. &&
00511 dz<3. &&
00512 abs(thisQuad.ptPlus-quad.ptPlus)<0.5*quad.ptPlus &&
00513 abs(thisQuad.ptMinus-quad.ptMinus)<0.5*quad.ptMinus &&
00514 abs(thisQuad.cot-quad.cot)<0.3*quad.cot
00515 ) return true;
00516 }
00517
00518 quadV.push_back(thisQuad);
00519 return false;
00520
00521 }