00001 #include "RecoEgamma/EgammaPhotonAlgos/interface/OutInConversionSeedFinder.h"
00002 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionBarrelEstimator.h"
00003 #include "RecoEgamma/EgammaPhotonAlgos/interface/ConversionForwardEstimator.h"
00004
00005 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00006
00007 #include "MagneticField/Engine/interface/MagneticField.h"
00008
00009 #include "DataFormats/CLHEP/interface/AlgebraicObjects.h"
00010
00011 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00012 #include "Geometry/CaloGeometry/interface/CaloSubdetectorGeometry.h"
00013
00014 #include "TrackingTools/TrajectoryParametrization/interface/GlobalTrajectoryParameters.h"
00015 #include "TrackingTools/TrajectoryState/interface/TrajectoryStateTransform.h"
00016 #include "TrackingTools/DetLayers/interface/DetLayer.h"
00017 #include "TrackingTools/MeasurementDet/interface/LayerMeasurements.h"
00018
00019 #include "RecoTracker/TkDetLayers/interface/GeometricSearchTracker.h"
00020 #include "RecoTracker/MeasurementDet/interface/MeasurementTracker.h"
00021
00022
00023 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00024 #include "CLHEP/Geometry/Point3D.h"
00025 #include "CLHEP/Geometry/Vector3D.h"
00026 #include "CLHEP/Geometry/Transform3D.h"
00027 #include <cfloat>
00028
00029
00030 OutInConversionSeedFinder::OutInConversionSeedFinder( const edm::ParameterSet& conf ): ConversionSeedFinder( conf ), conf_(conf)
00031 {
00032
00033 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder CTOR " << "\n";
00034
00035 maxNumberOfOutInSeedsPerBC_ = conf_.getParameter<int>("maxNumOfSeedsOutIn");
00036
00037 the2ndHitdphi_ = 0.03;
00038 the2ndHitdzConst_ = 5.;
00039 the2ndHitdznSigma_ = 2.;
00040
00041
00042
00043 }
00044
00045
00046
00047
00048 OutInConversionSeedFinder::~OutInConversionSeedFinder() {
00049 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder DTOR " << "\n";
00050
00051 }
00052
00053
00054
00055 void OutInConversionSeedFinder::makeSeeds( const edm::Handle<edm::View<reco::CaloCluster> > & allBC ) const {
00056
00057 theSeeds_.clear();
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067 findLayers();
00068
00069
00070
00071
00072 float theSCPhi=theSCPosition_.phi();
00073 float theSCEta=theSCPosition_.eta();
00074
00075
00076
00077
00078 reco::CaloClusterCollection::const_iterator bcItr;
00079 LogDebug("OutInConversionSeedFinder") << " OutInConversionSeedFinder::makeSeeds() All BC in the event " << "\n";
00080 for (unsigned i = 0; i < allBC->size(); ++i ) {
00081
00082
00083 nSeedsPerBC_=0;
00084
00085 theBCEnergy_=allBC->ptrAt(i)->energy();
00086 theBCPosition_ = GlobalPoint(allBC->ptrAt(i)->position().x(), allBC->ptrAt(i)->position().y(), allBC->ptrAt(i)->position().z() ) ;
00087 float theBcEta= theBCPosition_.eta();
00088 float theBcPhi= theBCPosition_.phi();
00089
00090
00091
00092
00093 if ( theBCEnergy_ < 1.5 ) continue;
00094
00095 LogDebug("OutInConversionSeedFinder") << " OutInConversionSeedFinder::makeSeeds() Passing the >=1.5 GeV cut BC eta " << theBcEta << " phi " << theBcPhi << " BC energy " << theBCEnergy_ << "\n";
00096
00097 if ( fabs(theBcEta-theSCEta) < 0.015 && fabs(theBcPhi-theSCPhi) < 0.3 ) {
00098 LogDebug("OutInConversionSeedFinder") << " OutInConversionSeedFinder::makeSeeds() in et and phi range passed to the analysis " << "\n";
00099 fillClusterSeeds( allBC->ptrAt(i) );
00100 }
00101
00102
00103 }
00104
00105
00106
00107
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144 }
00145
00146
00147
00148 void OutInConversionSeedFinder::makeSeeds( const reco::CaloClusterPtr& aBC ) const {
00149
00150 theSeeds_.clear();
00151
00152 findLayers();
00153
00154 float theSCPhi=theSCPosition_.phi();
00155 float theSCEta=theSCPosition_.eta();
00156
00157 nSeedsPerBC_=0;
00158
00159 theBCEnergy_=aBC->energy();
00160 theBCPosition_ = GlobalPoint(aBC->position().x(), aBC->position().y(), aBC->position().z() ) ;
00161 float theBcEta= theBCPosition_.eta();
00162 float theBcPhi= theBCPosition_.phi();
00163
00164
00165 if ( theBCEnergy_ < 1.5 ) return;
00166
00167 if ( fabs(theBcEta-theSCEta) < 0.015 && fabs(theBcPhi-theSCPhi) < 0.25 ) {
00168 fillClusterSeeds( aBC);
00169 }
00170
00171 }
00172
00173
00174
00175
00176
00177 void OutInConversionSeedFinder::fillClusterSeeds(const reco::CaloClusterPtr& bc) const {
00178
00179
00180 theFirstMeasurements_.clear();
00181 FreeTrajectoryState fts;
00182
00184 if ( makeTrackState(-1).second ) {
00185 fts = makeTrackState(-1).first;
00186 startSeed(fts);
00187 }
00189
00190 if ( makeTrackState(1).second ) {
00191 fts = makeTrackState(1).first;
00192 startSeed(fts);
00193 }
00194 theFirstMeasurements_.clear();
00195 }
00196
00197
00198
00199 std::pair<FreeTrajectoryState,bool> OutInConversionSeedFinder::makeTrackState(int charge) const {
00200
00201 std::pair<FreeTrajectoryState,bool> result;
00202 result.second=false;
00203
00204
00205
00206
00207
00208
00209
00210
00211 GlobalPoint gpOrigine(theBeamSpot_.position().x(),theBeamSpot_.position().y(),theBeamSpot_.position().z());
00212 GlobalVector gvBcRadius = theBCPosition_ - gpOrigine ;
00213 HepGeom::Point3D<double> radiusBc(gvBcRadius.x(),gvBcRadius.y(),gvBcRadius.z()) ;
00214 HepGeom::Point3D<double> momentumWithoutCurvature = radiusBc.unit() * theBCEnergy_ ;
00215
00216
00217 double curvature = theMF_->inTesla(theBCPosition_).z() * c_light * 1.e-3 / momentumWithoutCurvature.perp() ;
00218 curvature /= 100. ;
00219
00220 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState gpOrigine " << gpOrigine.x() << " " << gpOrigine.y() << " " << gpOrigine.z() << " momentumWithoutCurvature " << momentumWithoutCurvature.mag() << " curvature " << curvature << "\n";
00221
00222
00223 float R = theBCPosition_.perp();
00224 float r = gpOrigine.perp();
00225 float rho = 1./curvature;
00226
00227
00228 float d = sqrt(r*r+rho*rho);
00229 float u = rho + rho/d/d*(R*R-rho*rho) - r/d/d*sqrt((R*R-r*r+2*rho*R)*(R*R-r*r+2*rho*R));
00230
00231 if ( u <=R ) result.second=true;
00232
00233 double sinAlpha = 0.5*u/R;
00234 if ( sinAlpha>(1.-10*DBL_EPSILON) ) sinAlpha = 1.-10*DBL_EPSILON;
00235 else if ( sinAlpha<-(1.-10*DBL_EPSILON) ) sinAlpha = -(1.-10*DBL_EPSILON);
00236
00237 double newdphi = charge * asin( sinAlpha) ;
00238
00239 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState charge " << charge << " R " << R << " u/R " << u/R << " asin(0.5*u/R) " << asin(sinAlpha) << "\n";
00240
00241 HepGeom::Transform3D rotation = HepGeom::Rotate3D(newdphi, HepGeom::Vector3D<double> (0., 0. ,1.));
00242
00243
00244 HepGeom::Point3D<double> momentumInTracker = momentumWithoutCurvature.transform(rotation) ;
00245 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState R " << R << " r " << r << " rho " << rho << " d " << d << " u " << u << " newdphi " << newdphi << " momentumInTracker " << momentumInTracker << "\n";
00246
00247 HepGeom::Point3D<double> hepStartingPoint(gpOrigine.x(), gpOrigine.y(), gpOrigine.z()) ;
00248
00249 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState hepStartingPoint " << hepStartingPoint << "\n";
00250
00251 hepStartingPoint.transform(rotation);
00252
00253 GlobalPoint startingPoint(hepStartingPoint.x(), hepStartingPoint.y(), hepStartingPoint.z());
00254
00255 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeTrackState startingPoint " << startingPoint << " calo position " << theBCPosition_ << "\n";
00256 GlobalVector gvTracker(momentumInTracker.x(), momentumInTracker.y(), momentumInTracker.z());
00257 GlobalTrajectoryParameters gtp(startingPoint, gvTracker, charge, &(*theMF_) );
00258
00259 AlgebraicSymMatrix55 m = AlgebraicMatrixID();
00260 m(0,0) = 0.1; m(1,1) = 0.1 ; m(2,2) = 0.1 ;
00261 m(3,3) = 0.1 ; m(4,4) = 0.1;
00262
00263
00264
00265 result.first= FreeTrajectoryState(gtp, CurvilinearTrajectoryError(m) ) ;
00266 return result;
00267
00268 }
00269
00270
00271 void OutInConversionSeedFinder::startSeed(const FreeTrajectoryState & fts) const {
00272
00273
00274
00275
00276
00277 std::vector<const DetLayer*> myLayers=layerList();
00278 if ( myLayers.size() > 3 ) {
00279
00280 for(unsigned int ilayer = myLayers.size()-1; ilayer >= myLayers.size()-2; --ilayer) {
00281 const DetLayer * layer = myLayers[ilayer];
00282
00283
00284
00285
00286
00287 float dphi = 0.030;
00288
00289 MeasurementEstimator * newEstimator = makeEstimator(layer, dphi);
00290
00291
00292
00293
00294 TSOS tsos(fts, layer->surface() );
00295
00296 LogDebug("OutInConversionSeedFinder") << "OutInSeedFinder::startSeed after TSOS tsos(fts, layer->surface() ) " << "\n";
00297
00298 LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00299 theFirstMeasurements_ = theLayerMeasurements_.measurements( *layer, tsos, *thePropagatorAlongMomentum_, *newEstimator);
00300
00301
00302
00303 if(theFirstMeasurements_.size() > 1)
00304 LogDebug("OutInConversionSeedFinder") << " Found " << theFirstMeasurements_.size()-1 << " 1st hits in seed" << "\n";
00305
00306 delete newEstimator;
00307
00308 LogDebug("OutInConversionSeedFinder") << "OutInSeedFinder::startSeed Layer " << ilayer << " theFirstMeasurements_.size " << theFirstMeasurements_.size() << "\n";
00309
00310 for(unsigned int i = 0; i < theFirstMeasurements_.size(); ++i) {
00311 TrajectoryMeasurement m1 = theFirstMeasurements_[i];
00312 if(m1.recHit()->isValid()) {
00313
00314
00315
00316 GlobalPoint hitPoint = m1.recHit()->globalPosition();
00317 LogDebug("OutInConversionSeedFinder") << " Valid hit at R " << m1.recHit()->globalPosition().perp() << " Z " << m1.recHit()->globalPosition().z() << " eta " << m1.recHit()->globalPosition().eta() << " phi " << m1.recHit()->globalPosition().phi() << " xyz " << m1.recHit()->globalPosition() << "\n";
00318
00319
00320 FreeTrajectoryState newfts = trackStateFromClusters(fts.charge(), hitPoint, alongMomentum, 0.8);
00321 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::startSeed newfts " << newfts << "\n";
00322 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::startSeed propagationDirection after switching " << int(thePropagatorOppositeToMomentum_->propagationDirection() ) << "\n";
00323
00324
00325
00326 completeSeed(m1, newfts, thePropagatorOppositeToMomentum_, ilayer-1);
00327
00328 if(ilayer == myLayers.size()-1) {
00329 completeSeed(m1, newfts, thePropagatorOppositeToMomentum_, ilayer-2);
00330 }
00331 }
00332 }
00333
00334 }
00335 }
00336
00337
00338
00339
00340 }
00341
00342
00343
00344 MeasurementEstimator * OutInConversionSeedFinder::makeEstimator(const DetLayer * layer, float dphi) const {
00345
00346
00347
00348 MeasurementEstimator * newEstimator=0;
00349
00350 if (layer->location() == GeomDetEnumerators::barrel ) {
00351
00352 const BarrelDetLayer * barrelLayer = dynamic_cast<const BarrelDetLayer*>(layer);
00353 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeEstimator Barrel r = " << barrelLayer->specificSurface().radius() << " " << "\n";
00354 float r = barrelLayer->specificSurface().radius();
00355 float zrange = 15.* (1.-r/theBCPosition_.perp());
00356 newEstimator = new ConversionBarrelEstimator(-dphi, dphi, -zrange, zrange);
00357 }
00358
00359
00360
00361 if (layer->location() == GeomDetEnumerators::endcap ) {
00362
00363 const ForwardDetLayer * forwardLayer = dynamic_cast<const ForwardDetLayer*>(layer);
00364 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::makeEstimator Endcap r = " << forwardLayer->specificSurface().innerRadius() << " R " << forwardLayer->specificSurface().outerRadius() << " Z " << forwardLayer->specificSurface().position().z() << "\n";
00365
00366 float zc = fabs(theBCPosition_.z());
00367 float z = fabs(forwardLayer->surface().position().z());
00368
00369 float rrange = 15. * theBCPosition_.perp() * (zc - z) / (zc*zc - 15.*zc);
00370 newEstimator = new ConversionForwardEstimator(-dphi, dphi, rrange);
00371 }
00372
00373
00374
00375
00376 return newEstimator;
00377 }
00378
00379
00380
00381
00382 void OutInConversionSeedFinder::completeSeed(const TrajectoryMeasurement & m1,
00383 FreeTrajectoryState & fts,
00384 const Propagator* propagator, int ilayer) const {
00385
00386
00387
00388 MeasurementEstimator * newEstimator=0;
00389 const DetLayer * layer = theLayerList_[ilayer];
00390
00391
00392 if ( layer->location() == GeomDetEnumerators::barrel ) {
00393
00394 LogDebug("OutInConversionSeedFinder") << " Barrel OutInConversionSeedFinder::completeSeed " << the2ndHitdznSigma_ << " " << the2ndHitdzConst_ << " " << the2ndHitdphi_ << "\n";
00395 float dz = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1.recHit()->globalPositionError().czz()
00396 + the2ndHitdzConst_*the2ndHitdzConst_);
00397 newEstimator =
00398 new ConversionBarrelEstimator(-the2ndHitdphi_, the2ndHitdphi_, -dz, dz);
00399 }
00400 else {
00401 LogDebug("OutInConversionSeedFinder") << " EndCap OutInConversionSeedFinder::completeSeed " << the2ndHitdznSigma_ << " " << the2ndHitdzConst_ << " " << the2ndHitdphi_ << "\n";
00402
00403
00404 float m1dr = sqrt(m1.recHit()->localPositionError().yy());
00405 float dr = sqrt(the2ndHitdznSigma_*the2ndHitdznSigma_*m1dr*m1dr
00406 + the2ndHitdzConst_*the2ndHitdznSigma_);
00407
00408 newEstimator =
00409 new ConversionForwardEstimator(-the2ndHitdphi_, the2ndHitdphi_, dr);
00410 }
00411
00412 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed ilayer " << ilayer << "\n";
00413
00414
00415 TSOS tsos(fts, layer->surface() );
00416 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed propagationDirection " << int(propagator->propagationDirection() ) << "\n";
00417 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::completeSeed pointer to estimator " << newEstimator << "\n";
00418
00419 LayerMeasurements theLayerMeasurements_(this->getMeasurementTracker() );
00420 std::vector<TrajectoryMeasurement> measurements = theLayerMeasurements_.measurements( *layer, tsos, *propagator, *newEstimator);
00421
00422 delete newEstimator;
00423
00424 for(unsigned int i = 0; i < measurements.size(); ++i) {
00425 if( measurements[i].recHit()->isValid() ) {
00426 createSeed(m1, measurements[i]);
00427 }
00428 }
00429
00430
00431
00432
00433 }
00434
00435
00436
00437 void OutInConversionSeedFinder::createSeed(const TrajectoryMeasurement & m1,
00438 const TrajectoryMeasurement & m2) const {
00439
00440
00441
00442
00443 FreeTrajectoryState fts = createSeedFTS(m1, m2);
00444
00445
00446 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed First point errors " <<m1.recHit()->parametersError() << "\n";
00447 LogDebug("OutInConversionSeedFinder") << "original cluster FTS " << fts <<"\n";
00448
00449
00450
00451
00452 TrajectoryStateOnSurface state1 = thePropagatorOppositeToMomentum_->propagate(fts, m1.recHit()->det()->surface());
00453
00454
00455
00456
00457
00458
00459 if ( state1.isValid() ) {
00460 TrajectoryStateOnSurface updatedState1 = theUpdator_.update(state1, *m1.recHit() );
00461
00462 if ( updatedState1.isValid() ) {
00463 TrajectoryStateOnSurface state2 = thePropagatorOppositeToMomentum_->propagate(*updatedState1.freeTrajectoryState(), m2.recHit()->det()->surface());
00464
00465 if ( state2.isValid() ) {
00466
00467 TrajectoryStateOnSurface updatedState2 = theUpdator_.update(state2, *m2.recHit() );
00468 TrajectoryMeasurement meas1(state1, updatedState1, m1.recHit() , m1.estimate(), m1.layer());
00469 TrajectoryMeasurement meas2(state2, updatedState2, m2.recHit() , m2.estimate(), m2.layer());
00470
00471 edm::OwnVector<TrackingRecHit> myHits;
00472 myHits.push_back(meas1.recHit()->hit()->clone());
00473 myHits.push_back(meas2.recHit()->hit()->clone());
00474
00475 if ( nSeedsPerBC_ >= maxNumberOfOutInSeedsPerBC_ ) return;
00476
00477 TrajectoryStateTransform tsTransform;
00478 PTrajectoryStateOnDet* ptsod= tsTransform.persistentState(state2, meas2.recHit()->hit()->geographicalId().rawId() );
00479
00480 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed new seed from state " << state2.globalPosition() << "\n";
00481 LogDebug("OutInConversionSeedFinder") << "OutInConversionSeedFinder::createSeed new seed ptsod " << ptsod->parameters().position() << " R " << ptsod->parameters().position().perp() << " phi " << ptsod->parameters().position().phi() << " eta " << ptsod->parameters().position().eta() << "\n" ;
00482
00483
00484
00485 theSeeds_.push_back(TrajectorySeed( *ptsod, myHits, oppositeToMomentum ));
00486 nSeedsPerBC_++;
00487
00488 delete ptsod;
00489
00490
00491 }
00492 }
00493 }
00494
00495
00496
00497
00498
00499 }
00500
00501
00502
00503
00504
00505 FreeTrajectoryState OutInConversionSeedFinder::createSeedFTS(const TrajectoryMeasurement & m1,
00506 const TrajectoryMeasurement & m2) const {
00507
00508
00509
00510 GlobalPoint xmeas = fixPointRadius(m1);
00511 GlobalPoint xvert = fixPointRadius(m2);
00512
00513
00514 float pt = theSCenergy_ * sin(theSCPosition_.theta());
00515 float pz = theSCenergy_ * cos(theSCPosition_.theta());
00516
00517
00518
00519
00520
00521
00522 int charge = m2.predictedState().charge();
00523
00524 double BInTesla = theMF_->inTesla(xmeas).z();
00525 GlobalVector xdiff = xmeas -xvert;
00526
00527 double phi= xdiff.phi();
00528 double pxOld = pt*cos(phi);
00529 double pyOld = pt*sin(phi);
00530 double RadCurv = 100*pt/(BInTesla*0.29979);
00531 double alpha = asin(0.5*xdiff.perp()/RadCurv);
00532 float ca = cos(charge*alpha);
00533 float sa = sin(charge*alpha);
00534 double pxNew = ca*pxOld + sa*pyOld;
00535 double pyNew = -sa*pxOld + ca*pyOld;
00536 GlobalVector pNew(pxNew, pyNew, pz);
00537
00538 GlobalTrajectoryParameters gp(xmeas, pNew, charge, &(*theMF_) );
00539
00540 AlgebraicSymMatrix55 m = AlgebraicMatrixID();
00541 m(0,0) = 0.05; m(1,1) = 0.02 ; m(2,2) = 0.007 ;
00542 m(3,3) = 10. ; m(4,4) = 10. ;
00543 return FreeTrajectoryState(gp, CurvilinearTrajectoryError(m));
00544
00545
00546 }
00547
00548
00549
00550
00551 GlobalPoint OutInConversionSeedFinder::fixPointRadius(const TrajectoryMeasurement& m1) const {
00552 GlobalPoint p1 = m1.recHit()->globalPosition();
00553 GlobalPoint p2;
00554 if(m1.layer()->location() == GeomDetEnumerators::barrel) {
00555 p2 = p1;
00556 } else {
00557 float z = p1.z();
00558 float phi = p1.phi();
00559 float theta = theSCPosition_.theta();
00560 float r = p1.z() * tan(theta);
00561 p2 = GlobalPoint(r*cos(phi), r*sin(phi), z);
00562
00563 }
00564 return p2;
00565 }
00566
00567
00568
00569
00570