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