00001 #include "RecoTracker/ConversionSeedGenerators/interface/SeedForPhotonConversionFromQuadruplets.h"
00002
00003 #include "RecoTracker/ConversionSeedGenerators/interface/Conv4HitsReco2.h"
00004
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 #include "RecoTracker/TkTrackingRegions/interface/OrderedHitsGenerator.h"
00023 #include "RecoTracker/TkTrackingRegions/interface/TrackingRegion.h"
00024 #include "RecoTracker/TkSeedingLayers/interface/SeedComparitor.h"
00025 #include "RecoTracker/TkSeedGenerator/interface/SeedCreator.h"
00026 #include "RecoTracker/TkSeedingLayers/interface/SeedComparitorFactory.h"
00027 #include "RecoTracker/TkSeedGenerator/interface/SeedCreatorFactory.h"
00028 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateClosestToBeamLine.h"
00029 #include "TrackingTools/PatternTools/interface/TSCBLBuilderNoMaterial.h"
00030 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
00031
00032
00033
00034
00035 template <class T> T sqr( T t) {return t*t;}
00036
00037 const TrajectorySeed * SeedForPhotonConversionFromQuadruplets::trajectorySeed(
00038 TrajectorySeedCollection & seedCollection,
00039 const SeedingHitSet & phits,
00040 const SeedingHitSet & mhits,
00041 const TrackingRegion & region,
00042 const edm::EventSetup& es,
00043 std::stringstream& ss,
00044 std::vector<Quad>& quadV,
00045 edm::ParameterSet& SeedComparitorPSet,
00046 edm::ParameterSet& QuadCutPSet)
00047 {
00048
00049
00051
00052
00053 bool rejectAllQuads=QuadCutPSet.getParameter<bool>("rejectAllQuads");
00054 if(rejectAllQuads) return 0;
00055
00056 bool applyDeltaPhiCuts=QuadCutPSet.getParameter<bool>("apply_DeltaPhiCuts");
00057 bool ClusterShapeFiltering=QuadCutPSet.getParameter<bool>("apply_ClusterShapeFilter");
00058 bool applyArbitration=QuadCutPSet.getParameter<bool>("apply_Arbitration");
00059 bool applydzCAcut=QuadCutPSet.getParameter<bool>("apply_zCACut");
00060 double CleaningmaxRadialDistance=QuadCutPSet.getParameter<double>("Cut_DeltaRho");
00061 double BeamPipeRadiusCut=QuadCutPSet.getParameter<double>("Cut_BeamPipeRadius");
00062 double CleaningMinLegPt = QuadCutPSet.getParameter<double>("Cut_minLegPt");
00063 double maxLegPt = QuadCutPSet.getParameter<double>("Cut_maxLegPt");
00064 double dzcut=QuadCutPSet.getParameter<double>("Cut_zCA");
00065
00066 double toleranceFactorOnDeltaPhiCuts=0.1;
00067
00068
00069
00070 pss = &ss;
00071
00072 if ( phits.size() < 2) return 0;
00073 if ( mhits.size() < 2) return 0;
00074
00075
00076
00077
00078
00079
00080
00081 #ifdef mydebug_sguazz
00082 std::cout << " --------------------------------------------------------------------------" << "\n";
00083 std::cout << " Starting a hit quad fast reco " << "\n";
00084 std::cout << " --------------------------------------------------------------------------" << "\n";
00085 #endif
00086
00087
00088
00089 TransientTrackingRecHit::ConstRecHitPointer ptth1 = phits[0];
00090 TransientTrackingRecHit::ConstRecHitPointer ptth2 = phits[1];
00091 TransientTrackingRecHit::ConstRecHitPointer mtth1 = mhits[0];
00092 TransientTrackingRecHit::ConstRecHitPointer mtth2 = mhits[1];
00093
00094 GlobalPoint vHit[4];
00095 vHit[0]=ptth2->globalPosition();
00096 vHit[1]=ptth1->globalPosition();
00097 vHit[2]=mtth1->globalPosition();
00098 vHit[3]=mtth2->globalPosition();
00099
00100
00101 GlobalPoint vgPhotVertex=region.origin();
00102 math::XYZVector vPhotVertex(vgPhotVertex.x(), vgPhotVertex.y(), vgPhotVertex.z());
00103
00104 math::XYZVector h1(vHit[0].x(),vHit[0].y(),vHit[0].z());
00105 math::XYZVector h2(vHit[1].x(),vHit[1].y(),vHit[1].z());
00106 math::XYZVector h3(vHit[2].x(),vHit[2].y(),vHit[2].z());
00107 math::XYZVector h4(vHit[3].x(),vHit[3].y(),vHit[3].z());
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128 math::XYZVector P1;
00129 math::XYZVector P2;
00130 math::XYZVector M1;
00131 math::XYZVector M2;
00132
00133 if(h1.x()*h1.x()+h1.y()*h1.y() < h2.x()*h2.x()+h2.y()*h2.y()){
00134 P1=h1;
00135 P2=h2;
00136 }
00137 else{
00138 P1=h2;
00139 P2=h1;
00140 }
00141
00142 if(h3.x()*h3.x()+h3.y()*h3.y() < h4.x()*h4.x()+h4.y()*h4.y()){
00143 M1=h3;
00144 M2=h4;
00145 }
00146 else{
00147 M1=h4;
00148 M2=h3;
00149 }
00150
00152
00154
00155
00156
00157
00158
00159
00160
00161
00162 math::XYZVector IP(0,0,0);
00163
00164
00165 double kP=(P1.y()-P2.y())/(P1.x()-P2.x());
00166 double dP=P1.y()-kP*P1.x();
00167
00168 double kM=(M1.y()-M2.y())/(M1.x()-M2.x());
00169 double dM=M1.y()-kM*M1.x();
00170
00171 double IPx=(dM-dP)/(kP-kM);
00172 double IPy=kP*IPx+dP;
00173
00174 IP.SetXYZ(IPx,IPy,0);
00175
00176 double IPrho=std::sqrt(IP.x()*IP.x()+IP.y()*IP.y());
00177 double P1rho2=P1.x()*P1.x()+P1.y()*P1.y();
00178 double M1rho2=M1.x()*M1.x()+M1.y()*M1.y();
00179 double maxIPrho2=IPrho+CleaningmaxRadialDistance; maxIPrho2*=maxIPrho2;
00180
00181 if( IPrho<BeamPipeRadiusCut || P1rho2>maxIPrho2 || M1rho2>maxIPrho2){
00182 return 0;
00183 }
00184
00185 if(applyDeltaPhiCuts) {
00186
00187 kPI_ = std::atan(1.0)*4;
00188
00189 edm::ESHandle<MagneticField> bfield;
00190 es.get<IdealMagneticFieldRecord>().get(bfield);
00191 math::XYZVector QuadMean(0,0,0);
00192 QuadMean.SetXYZ((M1.x()+M2.x()+P1.x()+P2.x())/4.,(M1.y()+M2.y()+P1.y()+P2.y())/4.,(M1.z()+M2.z()+P1.z()+P2.z())/4.);
00193
00194 double fBField = bfield->inTesla(GlobalPoint(QuadMean.x(),QuadMean.y(),QuadMean.z())).z();
00195
00196 double rMax=CleaningMinLegPt/(0.01*0.3*fBField);
00197 double rMax_squared=rMax*rMax;
00198 double Mx=M1.x();
00199 double My=M1.y();
00200
00201 math::XYZVector B(0,0,0);
00202 math::XYZVector C(0,0,0);
00203
00204 if(rMax_squared*4. > Mx*Mx+My*My){
00205
00207
00209
00210
00211
00212
00213
00214 double k=-Mx/My;
00215 double d=My/2.-k*Mx/2.;
00216
00217 #ifdef mydebug_knuenz
00218 std::cout << "k" << k << std::endl;
00219 std::cout << "d" << d << std::endl;
00220 #endif
00221
00222
00223 double CsolutionPart1=-2*k*d;
00224 double CsolutionPart2=std::sqrt(4*k*k*d*d-4*(1+k*k)*(d*d-rMax_squared));
00225 double CsolutionPart3=2*(1+k*k);
00226 double Cx1=(CsolutionPart1+CsolutionPart2)/CsolutionPart3;
00227 double Cx2=(CsolutionPart1-CsolutionPart2)/CsolutionPart3;
00228 double Cy1=k*Cx1+d;
00229 double Cy2=k*Cx2+d;
00230
00231
00232
00233 double Cx,Cy;
00234 math::XYZVector C1(Cx1,Cy1,0);
00235 if(C1.x()*M1.y()-C1.y()*M1.x()<0){
00236 Cx=Cx1;
00237 Cy=Cy1;
00238 }
00239 else{
00240 Cx=Cx2;
00241 Cy=Cy2;
00242 }
00243 C.SetXYZ(Cx,Cy,0);
00244
00245 #ifdef mydebug_knuenz
00246 std::cout << "Cx1" << Cx1 << std::endl;
00247 std::cout << "Cx2" << Cx2 << std::endl;
00248 std::cout << "Cy1" << Cy1 << std::endl;
00249 std::cout << "Cy2" << Cy2 << std::endl;
00250 std::cout << "Cx" << Cx << std::endl;
00251 std::cout << "Cy" << Cy << std::endl;
00252 #endif
00253
00254
00255 k=-Cx/Cy;
00256 d=0;
00257 double Bx1=std::sqrt(Mx*Mx+My*My/(1+k*k));
00258 double Bx2=-Bx1;
00259 double By1=k*Bx1+d;
00260 double By2=k*Bx2+d;
00261
00262 #ifdef mydebug_knuenz
00263 std::cout << "k" << k << std::endl;
00264 std::cout << "d" << d << std::endl;
00265 #endif
00266
00267
00268 double Bx,By;
00269 math::XYZVector B1(Bx1,By1,0);
00270 if(M1.x()*B1.y()-M1.y()*B1.x()<0){
00271 Bx=Bx1;
00272 By=By1;
00273 }
00274 else{
00275 Bx=Bx2;
00276 By=By2;
00277 }
00278 B.SetXYZ(Bx,By,0);
00279
00280 #ifdef mydebug_knuenz
00281 std::cout << "Bx1" << Bx1 << std::endl;
00282 std::cout << "Bx2" << Bx2 << std::endl;
00283 std::cout << "By1" << By1 << std::endl;
00284 std::cout << "By2" << By2 << std::endl;
00285 std::cout << "Bx" << Bx << std::endl;
00286 std::cout << "By" << By << std::endl;
00287 #endif
00288
00289 double DeltaPhiMaxM1P1=DeltaPhiManual(M1,B)*2;
00290
00291 #ifdef mydebug_knuenz
00292 std::cout << "DeltaPhiMaxM1P1 " << DeltaPhiMaxM1P1 << std::endl;
00293 std::cout << "M1.DeltaPhi(P1) " << DeltaPhiManual(M1,P1) << std::endl;
00294 std::cout << "rho P1: " << std::sqrt(P1.x()*P1.x()+P1.y()*P1.y()) << "phi P1: " << P1.Phi() << std::endl;
00295 std::cout << "rho M1: " << std::sqrt(M1.x()*M1.x()+M1.y()*M1.y()) << "phi M1: " << M1.Phi() << std::endl;
00296 #endif
00297
00298
00299
00300 double tol_DeltaPhiMaxM1P1=DeltaPhiMaxM1P1*toleranceFactorOnDeltaPhiCuts;
00301 double DeltaPhiManualM1P1=DeltaPhiManual(M1,P1);
00302
00303 if(DeltaPhiManualM1P1>DeltaPhiMaxM1P1+tol_DeltaPhiMaxM1P1 || DeltaPhiManualM1P1<0-tol_DeltaPhiMaxM1P1){
00304 return 0;
00305 }
00306
00307 }
00308
00309
00311
00313
00314
00315
00316 double rM2_squared=M2.x()*M2.x()+M2.y()*M2.y();
00317 if(rMax_squared*4. > rM2_squared){
00318
00319
00320 double k=-C.x()/C.y();
00321 double d=(rM2_squared-rMax_squared+C.x()*C.x()+C.y()*C.y())/(2*C.y());
00322
00323 double M2solutionPart1=-2*k*d;
00324 double M2solutionPart2=std::sqrt(4*k*k*d*d-4*(1+k*k)*(d*d-rM2_squared));
00325 double M2solutionPart3=2+2*k*k;
00326 double M2xMax1=(M2solutionPart1+M2solutionPart2)/M2solutionPart3;
00327 double M2xMax2=(M2solutionPart1-M2solutionPart2)/M2solutionPart3;
00328 double M2yMax1=k*M2xMax1+d;
00329 double M2yMax2=k*M2xMax2+d;
00330
00331
00332 math::XYZVector M2MaxVec1(M2xMax1,M2yMax1,0);
00333 math::XYZVector M2MaxVec2(M2xMax2,M2yMax2,0);
00334 math::XYZVector M2MaxVec(0,0,0);
00335 if(M2MaxVec1.x()*M2MaxVec2.y()-M2MaxVec1.y()*M2MaxVec2.x()<0){
00336 M2MaxVec.SetXYZ(M2xMax2,M2yMax2,0);
00337 }
00338 else{
00339 M2MaxVec.SetXYZ(M2xMax1,M2yMax1,0);
00340 }
00341
00342 double DeltaPhiMaxM2=DeltaPhiManual(M2MaxVec,M1);
00343
00344 #ifdef mydebug_knuenz
00345 std::cout << "C.x() " << C.x() << std::endl;
00346 std::cout << "C.y() " << C.y() << std::endl;
00347 std::cout << "M1.x() " << M1.x() << std::endl;
00348 std::cout << "M1.y() " << M1.y() << std::endl;
00349 std::cout << "M2.x() " << M2.x() << std::endl;
00350 std::cout << "M2.y() " << M2.y() << std::endl;
00351 std::cout << "k " << k << std::endl;
00352 std::cout << "d " << d << std::endl;
00353 std::cout << "M2xMax1 " << M2xMax1 << std::endl;
00354 std::cout << "M2xMax2 " << M2xMax2 << std::endl;
00355 std::cout << "M2yMax1 " << M2yMax1 << std::endl;
00356 std::cout << "M2yMax2 " << M2yMax2 << std::endl;
00357 std::cout << "M2xMax " << M2MaxVec.x() << std::endl;
00358 std::cout << "M2yMax " << M2MaxVec.y() << std::endl;
00359 std::cout << "rM2_squared " << rM2_squared << std::endl;
00360 std::cout << "rMax " << rMax << std::endl;
00361 std::cout << "DeltaPhiMaxM2 " << DeltaPhiMaxM2 << std::endl;
00362 #endif
00363
00364
00365 double tol_DeltaPhiMaxM2=DeltaPhiMaxM2*toleranceFactorOnDeltaPhiCuts;
00366 double DeltaPhiManualM2M1=DeltaPhiManual(M2,M1);
00367
00368 if(DeltaPhiManualM2M1>DeltaPhiMaxM2+tol_DeltaPhiMaxM2 || DeltaPhiManualM2M1<0-tol_DeltaPhiMaxM2){
00369 return 0;
00370 }
00371
00372
00373 double DeltaPhiManualP1P2=DeltaPhiManual(P1,P2);
00374 if(DeltaPhiManualP1P2>DeltaPhiMaxM2+tol_DeltaPhiMaxM2 || DeltaPhiManualP1P2<0-tol_DeltaPhiMaxM2){
00375 return 0;
00376 }
00377
00378 }
00379
00380 }
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 Conv4HitsReco2 quad(vPhotVertex, h1, h2, h3, h4);
00393 quad.SetMaxNumberOfIterations(100);
00394 #ifdef mydebug_sguazz
00395 quad.Dump();
00396 #endif
00397 math::XYZVector candVtx;
00398 double candPtPlus, candPtMinus;
00399
00400 int nite = quad.ConversionCandidate(candVtx, candPtPlus, candPtMinus);
00401
00402 if ( ! (nite && abs(nite) < 25 && nite != -1000 && nite != -2000) ) return 0;
00403
00404
00405
00406
00407 #ifdef mydebug_sguazz
00408 std::cout << " >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << "\n";
00409 std::cout << " >>>>>>>>>>> Conv Cand: " << " Vertex X: " << candVtx.X() << " [cm] Y: " << candVtx.Y() << " [cm] pt+: " << candPtPlus<< " [GeV] pt-: " << candPtMinus << " [GeV]; #its: " << nite << "\n";
00410 #endif
00411
00412
00413 double minLegPt = CleaningMinLegPt;
00414 double maxRadialDistance = CleaningmaxRadialDistance;
00415
00416
00417
00418 if ( candPtPlus < minLegPt ) return 0;
00419 if ( candPtMinus < minLegPt ) return 0;
00420
00421 if ( candPtPlus > maxLegPt ) return 0;
00422 if ( candPtMinus > maxLegPt ) return 0;
00423
00424
00425 double cr = std::sqrt(candVtx.Perp2());
00426 double maxr2 = (maxRadialDistance + cr); maxr2*=maxr2;
00427 if (h2.Perp2() > maxr2) return 0;
00428 if (h3.Perp2() > maxr2) return 0;
00429
00430
00431
00432
00433
00434 std::string comparitorName = SeedComparitorPSet.getParameter<std::string>("ComponentName");
00435 SeedComparitor * theComparitor = (comparitorName == "none") ? 0 : SeedComparitorFactory::get()->create( comparitorName, SeedComparitorPSet);
00436
00437 if(ClusterShapeFiltering){
00438 if (theComparitor) theComparitor->init(es);
00439
00440 GlobalTrajectoryParameters pkine;
00441 GlobalTrajectoryParameters mkine;
00442
00443 TransientTrackingRecHit::ConstRecHitPointer ptth1 = phits[0];
00444 TransientTrackingRecHit::ConstRecHitPointer ptth2 = phits[1];
00445 TransientTrackingRecHit::ConstRecHitPointer mtth1 = mhits[0];
00446 TransientTrackingRecHit::ConstRecHitPointer mtth2 = mhits[1];
00447
00448 GlobalPoint vertexPos(candVtx.x(),candVtx.y(),candVtx.z());
00449
00450 float ptMinReg=0.1;
00451 GlobalTrackingRegion region(ptMinReg,vertexPos,0,0,true);
00452
00453 FastHelix phelix(ptth2->globalPosition(), mtth1->globalPosition(), vertexPos, es, vertexPos);
00454 pkine = phelix.stateAtVertex().parameters();
00455 FastHelix mhelix(mtth2->globalPosition(), mtth1->globalPosition(), vertexPos, es, vertexPos);
00456 mkine = mhelix.stateAtVertex().parameters();
00457
00458 if(theComparitor&&!theComparitor->compatible(phits, pkine, phelix, region)) { return 0; }
00459 if(theComparitor&&!theComparitor->compatible(mhits, mkine, mhelix, region)) { return 0; }
00460 }
00461
00462
00463
00464 double quadPhotCotTheta = 0.;
00465 double quadZ0 = 0.;
00466 simpleGetSlope(ptth2, ptth1, mtth1, mtth2, region, quadPhotCotTheta, quadZ0);
00467
00468 double quadPhotPhi = (candVtx-vPhotVertex).Phi();
00469
00470 math::XYZVector fittedPrimaryVertex(vgPhotVertex.x(), vgPhotVertex.y(),quadZ0);
00471
00472 candVtx.SetZ(std::sqrt(candVtx.Perp2())*quadPhotCotTheta+quadZ0);
00473 GlobalPoint convVtxGlobalPoint(candVtx.X(),candVtx.Y(),candVtx.Z());
00474
00475
00476
00477
00478
00479
00480 Quad thisQuad;
00481 thisQuad.x = candVtx.X();
00482 thisQuad.y = candVtx.Y();
00483 thisQuad.z = candVtx.Z();
00484 thisQuad.ptPlus = candPtPlus;
00485 thisQuad.ptMinus = candPtMinus;
00486 thisQuad.cot = quadPhotCotTheta;
00487 if ( similarQuadExist(thisQuad, quadV) && applyArbitration ) return 0;
00488
00489
00490
00491
00492 FastHelix helixPlus(ptth2->globalPosition(), ptth1->globalPosition(), convVtxGlobalPoint, es, convVtxGlobalPoint);
00493 GlobalTrajectoryParameters kinePlus = helixPlus.stateAtVertex().parameters();
00494 kinePlus = GlobalTrajectoryParameters(convVtxGlobalPoint,
00495 GlobalVector(candPtPlus*cos(quadPhotPhi),candPtPlus*sin(quadPhotPhi),candPtPlus*quadPhotCotTheta),
00496 1,
00497 & kinePlus.magneticField()
00498 );
00499
00500
00501
00502 FastHelix helixMinus(mtth2->globalPosition(), mtth1->globalPosition(), convVtxGlobalPoint, es, convVtxGlobalPoint);
00503 GlobalTrajectoryParameters kineMinus = helixMinus.stateAtVertex().parameters();
00504 kineMinus = GlobalTrajectoryParameters(convVtxGlobalPoint,
00505 GlobalVector(candPtMinus*cos(quadPhotPhi),candPtMinus*sin(quadPhotPhi),candPtMinus*quadPhotCotTheta),
00506 -1,
00507 & kineMinus.magneticField()
00508 );
00509
00510 float sinThetaPlus = sin(kinePlus.momentum().theta());
00511 float sinThetaMinus = sin(kineMinus.momentum().theta());
00512 float ptmin = region.ptMin();
00513
00514 GlobalVector vertexBounds(region.originRBound(),region.originRBound(),region.originZBound());
00515
00516 CurvilinearTrajectoryError errorPlus = initialError(vertexBounds, ptmin, sinThetaPlus);
00517 CurvilinearTrajectoryError errorMinus = initialError(vertexBounds, ptmin, sinThetaMinus);
00518 FreeTrajectoryState ftsPlus(kinePlus, errorPlus);
00519 FreeTrajectoryState ftsMinus(kineMinus, errorMinus);
00520
00521
00522
00523
00524
00525 #ifdef quadDispLine
00526 double vError = region.originZBound();
00527 if ( vError > 15. ) vError = 1.;
00528 std::cout << "QuadDispLine "
00529 << vgPhotVertex.x() << " " << vgPhotVertex.y() << " " << vgPhotVertex.z() << " " << vError << " "
00530 << vHit[0].x() << " " << vHit[0].y() << " " << vHit[0].z() << " " << sqrt(getSqrEffectiveErrorOnZ(ptth2, region)) << " "
00531 << vHit[1].x() << " " << vHit[1].y() << " " << vHit[1].z() << " " << sqrt(getSqrEffectiveErrorOnZ(ptth1, region)) << " "
00532 << vHit[2].x() << " " << vHit[2].y() << " " << vHit[2].z() << " " << sqrt(getSqrEffectiveErrorOnZ(mtth1, region)) << " "
00533 << vHit[3].x() << " " << vHit[3].y() << " " << vHit[3].z() << " " << sqrt(getSqrEffectiveErrorOnZ(mtth2, region)) << " "
00534 << candVtx.X() << " " << candVtx.Y() << " " << candVtx.Z() << " "
00535 << fittedPrimaryVertex.X() << " " << fittedPrimaryVertex.Y() << " " << fittedPrimaryVertex.Z() << " "
00536
00537
00538 << nite << " " << chi2 << "\n";
00539 #endif
00540 #ifdef mydebug_sguazz
00541 std::cout << " >>>>> Hit quad fast reco done >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>" << "\n";
00542 uint32_t detid;
00543 std::cout << "[SeedForPhotonConversionFromQuadruplets]\n ptth1 " ;
00544 detid=ptth1->geographicalId().rawId();
00545
00546 std::cout << " \t " << detid << " " << ptth1->localPosition() << " " << ptth1->globalPosition() ;
00547 detid=ptth2->geographicalId().rawId();
00548 std::cout << " \n\t ptth2 ";
00549
00550 std::cout << " \t " << detid << " " << ptth2->localPosition() << " " << ptth2->globalPosition()
00551 << "\nhelix momentum " << kinePlus.momentum() << " pt " << kinePlus.momentum().perp() << " radius " << 1/kinePlus.transverseCurvature() << " q " << kinePlus.charge();
00552 std::cout << " \n\t mtth1 ";
00553 detid=mtth1->geographicalId().rawId();
00554 std::cout << " \t " << detid << " " << mtth1->localPosition() << " " << mtth1->globalPosition() ;
00555 std::cout << " \n\t mtth2 ";
00556 detid=mtth2->geographicalId().rawId();
00557
00558 std::cout << " \t " << detid << " " << mtth2->localPosition() << " " << mtth2->globalPosition()
00559 << "\nhelix momentum " << kineMinus.momentum() << " pt " << kineMinus.momentum().perp() << " radius " << 1/kineMinus.transverseCurvature() << " q " << kineMinus.charge();
00560 std::cout << "\n <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << "\n";
00561 #endif
00562
00563
00564
00565 bool buildSeedBoolPos = buildSeedBool(seedCollection,phits,ftsPlus,es,applydzCAcut,region, dzcut);
00566 bool buildSeedBoolNeg = buildSeedBool(seedCollection,mhits,ftsMinus,es,applydzCAcut,region, dzcut);
00567
00568
00569
00570 if( buildSeedBoolPos && buildSeedBoolNeg ){
00571 buildSeed(seedCollection,phits,ftsPlus,es,false,region);
00572 buildSeed(seedCollection,mhits,ftsMinus,es,false,region);
00573 }
00574
00575 return 0;
00576
00577 }
00578
00579
00580 GlobalTrajectoryParameters SeedForPhotonConversionFromQuadruplets::initialKinematic(
00581 const SeedingHitSet & hits,
00582 const GlobalPoint & vertexPos,
00583 const edm::EventSetup& es,
00584 const float cotTheta) const
00585 {
00586 GlobalTrajectoryParameters kine;
00587
00588 TransientTrackingRecHit::ConstRecHitPointer tth1 = hits[0];
00589 TransientTrackingRecHit::ConstRecHitPointer tth2 = hits[1];
00590
00591
00592 FastHelix helix(tth2->globalPosition(), tth1->globalPosition(), vertexPos, es, vertexPos);
00593 kine = helix.stateAtVertex().parameters();
00594
00595
00596 if(fabs(cotTheta)<cotTheta_Max)
00597 kine = GlobalTrajectoryParameters(kine.position(),
00598 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta),
00599 kine.charge(),
00600 & kine.magneticField()
00601 );
00602 else
00603 kine = GlobalTrajectoryParameters(kine.position(),
00604 GlobalVector(kine.momentum().x(),kine.momentum().y(),kine.momentum().perp()*cotTheta_Max),
00605 kine.charge(),
00606 & kine.magneticField()
00607 );
00608
00609 #ifdef mydebug_seed
00610 uint32_t detid;
00611 (*pss) << "[SeedForPhotonConversionFromQuadruplets] initialKinematic tth1 " ;
00612 detid=tth1->geographicalId().rawId();
00613 po.print(*pss, detid );
00614 (*pss) << " \t " << detid << " " << tth1->localPosition() << " " << tth1->globalPosition() ;
00615 detid= tth2->geographicalId().rawId();
00616 (*pss) << " \n\t tth2 ";
00617 po.print(*pss, detid );
00618 (*pss) << " \t " << detid << " " << tth2->localPosition() << " " << tth2->globalPosition()
00619 << "\nhelix momentum " << kine.momentum() << " pt " << kine.momentum().perp() << " radius " << 1/kine.transverseCurvature();
00620 #endif
00621
00622 edm::ESHandle<MagneticField> bfield;
00623 es.get<IdealMagneticFieldRecord>().get(bfield);
00624 bool isBOFF = ( std::abs(bfield->inTesla(GlobalPoint(0,0,0)).z()) < 1e-3 );
00625 if (isBOFF && (theBOFFMomentum > 0)) {
00626 kine = GlobalTrajectoryParameters(kine.position(),
00627 kine.momentum().unit() * theBOFFMomentum,
00628 kine.charge(),
00629 &*bfield);
00630 }
00631 return kine;
00632 }
00633
00634
00635
00636 CurvilinearTrajectoryError SeedForPhotonConversionFromQuadruplets::
00637 initialError(
00638 const GlobalVector& vertexBounds,
00639 float ptMin,
00640 float sinTheta) const
00641 {
00642
00643
00644 GlobalError vertexErr( sqr(vertexBounds.x()), 0,
00645 sqr(vertexBounds.y()), 0, 0,
00646 sqr(vertexBounds.z())
00647 );
00648
00649
00650 AlgebraicSymMatrix55 C = ROOT::Math::SMatrixIdentity();
00651
00652
00653
00654
00655 float sin2th = sqr(sinTheta);
00656 float minC00 = 1.0;
00657 C[0][0] = std::max(sin2th/sqr(ptMin), minC00);
00658 float zErr = vertexErr.czz();
00659 float transverseErr = vertexErr.cxx();
00660 C[3][3] = transverseErr;
00661 C[4][4] = zErr*sin2th + transverseErr*(1-sin2th);
00662
00663 return CurvilinearTrajectoryError(C);
00664 }
00665
00666 const TrajectorySeed * SeedForPhotonConversionFromQuadruplets::buildSeed(
00667 TrajectorySeedCollection & seedCollection,
00668 const SeedingHitSet & hits,
00669 const FreeTrajectoryState & fts,
00670 const edm::EventSetup& es,
00671 bool apply_dzCut,
00672 const TrackingRegion & region) const
00673 {
00674
00675 edm::ESHandle<TrackerGeometry> tracker;
00676 es.get<TrackerDigiGeometryRecord>().get(tracker);
00677
00678
00679 edm::ESHandle<Propagator> propagatorHandle;
00680 es.get<TrackingComponentsRecord>().get(thePropagatorLabel, propagatorHandle);
00681 const Propagator* propagator = &(*propagatorHandle);
00682
00683
00684 KFUpdator updator;
00685
00686
00687
00688 TrajectoryStateOnSurface updatedState;
00689 edm::OwnVector<TrackingRecHit> seedHits;
00690
00691 const TrackingRecHit* hit = 0;
00692 for ( unsigned int iHit = 0; iHit < hits.size() && iHit<2; iHit++) {
00693 hit = hits[iHit]->hit();
00694 TrajectoryStateOnSurface state = (iHit==0) ?
00695 propagator->propagate(fts,tracker->idToDet(hit->geographicalId())->surface())
00696 : propagator->propagate(updatedState, tracker->idToDet(hit->geographicalId())->surface());
00697
00698 TransientTrackingRecHit::ConstRecHitPointer tth = hits[iHit];
00699
00700 TransientTrackingRecHit::RecHitPointer newtth = refitHit( tth, state);
00701
00702 updatedState = updator.update(state, *newtth);
00703
00704 seedHits.push_back(newtth->hit()->clone());
00705 #ifdef mydebug_seed
00706 uint32_t detid = hit->geographicalId().rawId();
00707 (*pss) << "\n[SeedForPhotonConversionFromQuadruplets] hit " << iHit;
00708 po.print(*pss, detid);
00709 (*pss) << " " << detid << "\t lp " << hit->localPosition()
00710 << " tth " << tth->localPosition() << " newtth " << newtth->localPosition() << " state " << state.globalMomentum().perp();
00711 #endif
00712 }
00713
00714 PTrajectoryStateOnDet const & PTraj =
00715 trajectoryStateTransform::persistentState(updatedState, hit->geographicalId().rawId());
00716
00717
00718 seedCollection.push_back( TrajectorySeed(PTraj,seedHits,alongMomentum));
00719 return &seedCollection.back();
00720 }
00721
00722
00723
00724
00725
00726 bool SeedForPhotonConversionFromQuadruplets::buildSeedBool(
00727 TrajectorySeedCollection & seedCollection,
00728 const SeedingHitSet & hits,
00729 const FreeTrajectoryState & fts,
00730 const edm::EventSetup& es,
00731 bool apply_dzCut,
00732 const TrackingRegion & region,
00733 double dzcut) const
00734 {
00735
00736 edm::ESHandle<TrackerGeometry> tracker;
00737 es.get<TrackerDigiGeometryRecord>().get(tracker);
00738
00739
00740 edm::ESHandle<Propagator> propagatorHandle;
00741 es.get<TrackingComponentsRecord>().get(thePropagatorLabel, propagatorHandle);
00742 const Propagator* propagator = &(*propagatorHandle);
00743
00744
00745 KFUpdator updator;
00746
00747
00748
00749 TrajectoryStateOnSurface updatedState;
00750 edm::OwnVector<TrackingRecHit> seedHits;
00751
00752 const TrackingRecHit* hit = 0;
00753 for ( unsigned int iHit = 0; iHit < hits.size() && iHit<2; iHit++) {
00754 hit = hits[iHit]->hit();
00755 TrajectoryStateOnSurface state = (iHit==0) ?
00756 propagator->propagate(fts,tracker->idToDet(hit->geographicalId())->surface())
00757 : propagator->propagate(updatedState, tracker->idToDet(hit->geographicalId())->surface());
00758 if (!state.isValid()) {
00759 return false;}
00760
00761 TransientTrackingRecHit::ConstRecHitPointer tth = hits[iHit];
00762
00763 TransientTrackingRecHit::RecHitPointer newtth = refitHit( tth, state);
00764
00765
00766 if (!checkHit(state,newtth,es)){
00767 return false;
00768 }
00769
00770 updatedState = updator.update(state, *newtth);
00771 if (!updatedState.isValid()){
00772 return false;
00773 }
00774
00775 seedHits.push_back(newtth->hit()->clone());
00776 }
00777
00778 if(apply_dzCut){
00780
00781 double zCA;
00782
00783 math::XYZVector EstMomGam(updatedState.globalMomentum().x(),updatedState.globalMomentum().y(),updatedState.globalMomentum().z());
00784 math::XYZVector EstPosGam(updatedState.globalPosition().x(),updatedState.globalPosition().y(),updatedState.globalPosition().z());
00785
00786 double EstMomGamLength=std::sqrt(EstMomGam.x()*EstMomGam.x()+EstMomGam.y()*EstMomGam.y()+EstMomGam.z()*EstMomGam.z());
00787 math::XYZVector EstMomGamNorm(EstMomGam.x()/EstMomGamLength,EstMomGam.y()/EstMomGamLength,EstMomGam.z()/EstMomGamLength);
00788
00789
00790
00791
00792 const GlobalPoint EstPosGamGlobalPoint(updatedState.globalPosition().x(),updatedState.globalPosition().y(),updatedState.globalPosition().z());
00793 const GlobalVector EstMomGamGlobalVector(updatedState.globalMomentum().x(),updatedState.globalMomentum().y(),updatedState.globalMomentum().z());
00794
00795
00796 edm::ESHandle<MagneticField> bfield;
00797 es.get<IdealMagneticFieldRecord>().get(bfield);
00798 const MagneticField* magField = bfield.product();
00799 TrackCharge qCharge = 0;
00800
00801 const GlobalTrajectoryParameters myGlobalTrajectoryParameter(EstPosGamGlobalPoint, EstMomGamGlobalVector, qCharge, magField);
00802
00803 AlgebraicSymMatrix66 aCovarianceMatrix;
00804
00805 for (int i =0;i<6;++i)
00806 for (int j =0;j<6;++j)
00807 aCovarianceMatrix(i, j) = 1e-4;
00808
00809 CartesianTrajectoryError myCartesianError (aCovarianceMatrix);
00810
00811 const FreeTrajectoryState stateForProjectionToBeamLine(myGlobalTrajectoryParameter,myCartesianError);
00812
00813 const GlobalPoint BeamSpotGlobalPoint(0,0,0);
00814
00815 const reco::BeamSpot::Point BeamSpotPoint(region.origin().x(),region.origin().y(),region.origin().z());
00816
00817 TSCBLBuilderNoMaterial tscblBuilder;
00818
00819 double CovMatEntry=0.;
00820 reco::BeamSpot::CovarianceMatrix cov;
00821 for (int i=0;i<3;++i) {
00822 cov(i,i) = CovMatEntry;
00823 }
00824 reco::BeamSpot::BeamType BeamType_=reco::BeamSpot::Unknown;
00825
00826 reco::BeamSpot myBeamSpot(BeamSpotPoint, 0.,0.,0.,0., cov,BeamType_);
00827
00828 TrajectoryStateClosestToBeamLine tscbl = tscblBuilder(stateForProjectionToBeamLine,myBeamSpot);
00829 if (tscbl.isValid()==false) {
00830 zCA=0;
00831 }
00832 else{
00833 GlobalPoint v = tscbl.trackStateAtPCA().position();
00834 zCA=v.z();
00835 }
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 #ifdef mydebug_knuenz
00870 std::cout<< "zCA: " << zCA <<std::endl;
00871 #endif
00872
00873 if(std::fabs(zCA)>dzcut) return false;
00874
00875
00876 }
00877
00878
00879 return true;
00880 }
00881
00882
00883
00884 TransientTrackingRecHit::RecHitPointer SeedForPhotonConversionFromQuadruplets::refitHit(
00885 const TransientTrackingRecHit::ConstRecHitPointer &hit,
00886 const TrajectoryStateOnSurface &state) const
00887 {
00888
00889
00890
00891
00892
00893
00894
00895 return hit->clone(state);
00896 }
00897
00898
00899
00900
00901
00902 void SeedForPhotonConversionFromQuadruplets::
00903 stupidPrint(std::string s,float* d){
00904 (*pss) << "\n" << s << "\t";
00905 for(size_t i=0;i<2;++i)
00906 (*pss) << std::setw (60) << d[i] << std::setw(1) << " | ";
00907 }
00908
00909 void SeedForPhotonConversionFromQuadruplets::
00910 stupidPrint(std::string s,double* d){
00911 (*pss) << "\n" << s << "\t";
00912 for(size_t i=0;i<2;++i)
00913 (*pss) << std::setw (60) << d[i] << std::setw(1) << " | ";
00914 }
00915
00916 void SeedForPhotonConversionFromQuadruplets::
00917 stupidPrint(const char* s,GlobalPoint* d){
00918 (*pss) << "\n" << s << "\t";
00919 for(size_t i=0;i<2;++i)
00920 (*pss) << std::setw(20) << d[i] << " r " << d[i].perp() << " phi " << d[i].phi() << " | ";
00921 }
00922
00923 void SeedForPhotonConversionFromQuadruplets::
00924 stupidPrint(const char* s, GlobalPoint* d, int n){
00925 (*pss) << "\n" << s << "\n";
00926 for(int i=0;i<n;++i)
00927 (*pss) << std::setw(20) << d[i] << " r " << d[i].perp() << " phi " << d[i].phi() << "\n";
00928 }
00929
00930 #include "DataFormats/Math/interface/deltaPhi.h"
00931
00932 void SeedForPhotonConversionFromQuadruplets::
00933 bubbleSortVsPhi(GlobalPoint arr[], int n, GlobalPoint vtx) {
00934 bool swapped = true;
00935 int j = 0;
00936 GlobalPoint tmp;
00937 while (swapped) {
00938 swapped = false;
00939 j++;
00940 for (int i = 0; i < n - j; i++) {
00941 if ( reco::deltaPhi( (arr[i]-vtx).phi(), (arr[i + 1]-vtx).phi() ) > 0. ) {
00942 tmp = arr[i];
00943 arr[i] = arr[i + 1];
00944 arr[i + 1] = tmp;
00945 swapped = true;
00946 }
00947 }
00948 }
00949 }
00950
00951 void SeedForPhotonConversionFromQuadruplets::
00952 bubbleReverseSortVsPhi(GlobalPoint arr[], int n, GlobalPoint vtx) {
00953 bool swapped = true;
00954 int j = 0;
00955 GlobalPoint tmp;
00956 while (swapped) {
00957 swapped = false;
00958 j++;
00959 for (int i = 0; i < n - j; i++) {
00960 if ( reco::deltaPhi( (arr[i]-vtx).phi(), (arr[i + 1]-vtx).phi() ) < 0. ) {
00961 tmp = arr[i];
00962 arr[i] = arr[i + 1];
00963 arr[i + 1] = tmp;
00964 swapped = true;
00965 }
00966 }
00967 }
00968 }
00969
00970
00971 double SeedForPhotonConversionFromQuadruplets::
00972 simpleGetSlope(const TransientTrackingRecHit::ConstRecHitPointer &ohit, const TransientTrackingRecHit::ConstRecHitPointer &nohit, const TransientTrackingRecHit::ConstRecHitPointer &ihit, const TransientTrackingRecHit::ConstRecHitPointer &nihit, const TrackingRegion & region, double & cotTheta, double & z0){
00973
00974 double x[5], y[5], e2y[5];
00975
00976
00977
00978
00979 x[0] = ohit->globalPosition().perp();
00980 y[0] = ohit->globalPosition().z();
00981 e2y[0] = getSqrEffectiveErrorOnZ(ohit, region);
00982
00983 x[1] = nohit->globalPosition().perp();
00984 y[1] = nohit->globalPosition().z();
00985 e2y[1] = getSqrEffectiveErrorOnZ(nohit, region);
00986
00987 x[2] = nihit->globalPosition().perp();
00988 y[2] = nihit->globalPosition().z();
00989 e2y[2] = getSqrEffectiveErrorOnZ(nihit, region);
00990
00991 x[3] = ihit->globalPosition().perp();
00992 y[3] = ihit->globalPosition().z();
00993 e2y[3] = getSqrEffectiveErrorOnZ(ihit, region);
00994
00995
00996 x[4] = region.origin().perp();
00997 y[4] = region.origin().z();
00998 double vError = region.originZBound();
00999 if ( vError > 15. ) vError = 1.;
01000 e2y[4] = sqr(vError);
01001
01002 double e2z0;
01003 double chi2 = verySimpleFit(5, x, y, e2y, z0, e2z0, cotTheta);
01004
01005 return chi2;
01006
01007 }
01008
01009 double SeedForPhotonConversionFromQuadruplets::verySimpleFit(int size, double* ax, double* ay, double* e2y, double& p0, double& e2p0, double& p1){
01010
01011
01012 return 0;
01013 }
01014
01015 double SeedForPhotonConversionFromQuadruplets::getSqrEffectiveErrorOnZ(const TransientTrackingRecHit::ConstRecHitPointer &hit, const TrackingRegion & region){
01016
01017
01018
01019
01020
01021 double sqrProjFactor = sqr((hit->globalPosition().z()-region.origin().z())/(hit->globalPosition().perp()-region.origin().perp()));
01022 return (hit->globalPositionError().czz()+sqrProjFactor*hit->globalPositionError().rerr(hit->globalPosition()));
01023
01024 }
01025
01026 bool SeedForPhotonConversionFromQuadruplets::similarQuadExist(Quad & thisQuad, std::vector<Quad>& quadV){
01027
01028 BOOST_FOREACH( Quad quad, quadV )
01029 {
01030 double dx = thisQuad.x-quad.x;
01031 double dy = thisQuad.y-quad.y;
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049 if ( sqrt(dx*dx+dy*dy)<1. &&
01050 fabs(thisQuad.ptPlus-quad.ptPlus)<0.5*quad.ptPlus &&
01051 fabs(thisQuad.ptMinus-quad.ptMinus)<0.5*quad.ptMinus
01052 )
01053 {
01054
01055 return true;
01056 }
01057 }
01058 quadV.push_back(thisQuad);
01059 return false;
01060
01061 }
01062
01063 double SeedForPhotonConversionFromQuadruplets::DeltaPhiManual(math::XYZVector v1, math::XYZVector v2){
01064
01065 double kTWOPI = 2.*kPI_;
01066 double DeltaPhiMan=v1.Phi()-v2.Phi();
01067 while (DeltaPhiMan >= kPI_) DeltaPhiMan -= kTWOPI;
01068 while (DeltaPhiMan < -kPI_) DeltaPhiMan += kTWOPI;
01069
01070 return DeltaPhiMan;
01071
01072 }