00001 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
00002 #include "DataFormats/TrackReco/interface/Track.h"
00003 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00004 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00005
00006
00007
00008
00009
00010
00011
00012 #if defined(__GNUC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 4
00013 # pragma GCC diagnostic ignored "-Warray-bounds"
00014 #endif
00015
00016 using namespace reco;
00017
00018
00019 Conversion::Conversion( const reco::CaloClusterPtrVector sc,
00020 const std::vector<reco::TrackRef> tr,
00021 const std::vector<math::XYZPointF> trackPositionAtEcal,
00022 const reco::Vertex & convVtx,
00023 const std::vector<reco::CaloClusterPtr> & matchingBC,
00024 const float DCA,
00025 const std::vector<math::XYZPointF> & innPoint,
00026 const std::vector<math::XYZVectorF> & trackPin,
00027 const std::vector<math::XYZVectorF> & trackPout,
00028 const float mva,
00029 ConversionAlgorithm algo):
00030
00031
00032 caloCluster_(sc), tracks_(tr),
00033 thePositionAtEcal_(trackPositionAtEcal),
00034 theConversionVertex_(convVtx),
00035 theMatchingBCs_(matchingBC),
00036 theMinDistOfApproach_(DCA),
00037 theTrackInnerPosition_(innPoint),
00038 theTrackPin_(trackPin),
00039 theTrackPout_(trackPout),
00040 nSharedHits_(0),
00041 theMVAout_(mva),
00042 algorithm_(algo),
00043 qualityMask_(0)
00044 {
00045
00046 }
00047
00048
00049
00050
00051 Conversion::Conversion( const reco::CaloClusterPtrVector sc,
00052 const std::vector<edm::RefToBase<reco::Track> > tr,
00053 const std::vector<math::XYZPointF> trackPositionAtEcal,
00054 const reco::Vertex & convVtx,
00055 const std::vector<reco::CaloClusterPtr> & matchingBC,
00056 const float DCA,
00057 const std::vector<math::XYZPointF> & innPoint,
00058 const std::vector<math::XYZVectorF> & trackPin,
00059 const std::vector<math::XYZVectorF> & trackPout,
00060 const std::vector<uint8_t> nHitsBeforeVtx,
00061 const std::vector<Measurement1DFloat> & dlClosestHitToVtx,
00062 uint8_t nSharedHits,
00063 const float mva,
00064 ConversionAlgorithm algo):
00065
00066
00067 caloCluster_(sc), trackToBaseRefs_(tr),
00068 thePositionAtEcal_(trackPositionAtEcal),
00069 theConversionVertex_(convVtx),
00070 theMatchingBCs_(matchingBC),
00071 theMinDistOfApproach_(DCA),
00072 theTrackInnerPosition_(innPoint),
00073 theTrackPin_(trackPin),
00074 theTrackPout_(trackPout),
00075 nHitsBeforeVtx_(nHitsBeforeVtx),
00076 dlClosestHitToVtx_(dlClosestHitToVtx),
00077 nSharedHits_(nSharedHits),
00078 theMVAout_(mva),
00079 algorithm_(algo),
00080 qualityMask_(0)
00081 {
00082
00083 }
00084
00085
00086
00087
00088 Conversion::Conversion( const reco::CaloClusterPtrVector sc,
00089 const std::vector<reco::TrackRef> tr,
00090 const reco::Vertex & convVtx,
00091 ConversionAlgorithm algo):
00092 caloCluster_(sc), tracks_(tr),
00093 theConversionVertex_(convVtx),
00094 nSharedHits_(0),
00095 algorithm_(algo),
00096 qualityMask_(0)
00097 {
00098
00099
00100 theMinDistOfApproach_ = 9999.;
00101 theMVAout_ = 9999.;
00102 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00103 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00104 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00105 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00106 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00107 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00108 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00109 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00110
00111
00112 }
00113
00114
00115 Conversion::Conversion( const reco::CaloClusterPtrVector sc,
00116 const std::vector<edm::RefToBase<reco::Track> > tr,
00117 const reco::Vertex & convVtx,
00118 ConversionAlgorithm algo):
00119 caloCluster_(sc), trackToBaseRefs_(tr),
00120 theConversionVertex_(convVtx),
00121 nSharedHits_(0),
00122 algorithm_(algo),
00123 qualityMask_(0)
00124 {
00125
00126
00127 theMinDistOfApproach_ = 9999.;
00128 theMVAout_ = 9999.;
00129 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00130 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00131 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00132 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00133 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00134 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00135 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00136 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00137
00138
00139 }
00140
00141
00142
00143 Conversion::Conversion() {
00144
00145 algorithm_=0;
00146 qualityMask_=0;
00147 theMinDistOfApproach_ = 9999.;
00148 nSharedHits_ = 0;
00149 theMVAout_ = 9999.;
00150 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00151 thePositionAtEcal_.push_back(math::XYZPointF(0.,0.,0.));
00152 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00153 theTrackInnerPosition_.push_back(math::XYZPointF(0.,0.,0.));
00154 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00155 theTrackPin_.push_back(math::XYZVectorF(0.,0.,0.));
00156 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00157 theTrackPout_.push_back(math::XYZVectorF(0.,0.,0.));
00158
00159 }
00160
00161
00162 Conversion::~Conversion() { }
00163
00164
00165 std::string const Conversion::algoNames[] = { "undefined","ecalSeeded","trackerOnly","mixed"};
00166
00167 Conversion::ConversionAlgorithm Conversion::algoByName(const std::string &name){
00168 ConversionAlgorithm size = algoSize;
00169 int index = std::find(algoNames, algoNames+size, name)-algoNames;
00170 if(index == size) return undefined;
00171
00172 return ConversionAlgorithm(index);
00173 }
00174
00175 Conversion * Conversion::clone() const {
00176 return new Conversion( * this );
00177 }
00178
00179
00180 std::vector<edm::RefToBase<reco::Track> > Conversion::tracks() const {
00181 if (trackToBaseRefs_.size() ==0 ) {
00182
00183 for (std::vector<reco::TrackRef>::const_iterator ref=tracks_.begin(); ref!=tracks_.end(); ref++ )
00184 {
00185 edm::RefToBase<reco::Track> tt(*ref);
00186 trackToBaseRefs_.push_back(tt);
00187
00188 }
00189 }
00190
00191 return trackToBaseRefs_;
00192 }
00193
00194
00195
00196 bool Conversion::isConverted() const {
00197
00198 if ( this->nTracks() == 2 )
00199 return true;
00200 else
00201 return false;
00202 }
00203
00204 double Conversion::pairInvariantMass() const{
00205 double invMass=-99.;
00206 const float mElec= 0.000511;
00207 if ( nTracks()==2 ) {
00208 double px= tracksPin()[0].x() + tracksPin()[1].x();
00209 double py= tracksPin()[0].y() + tracksPin()[1].y();
00210 double pz= tracksPin()[0].z() + tracksPin()[1].z();
00211 double mom1= tracksPin()[0].Mag2();
00212 double mom2= tracksPin()[1].Mag2();
00213 double e = sqrt( mom1+ mElec*mElec ) + sqrt( mom2 + mElec*mElec );
00214 invMass= ( e*e - px*px -py*py - pz*pz);
00215 if ( invMass>0) invMass = sqrt(invMass);
00216 else
00217 invMass = -1;
00218 }
00219
00220 return invMass;
00221 }
00222
00223 double Conversion::pairCotThetaSeparation() const {
00224 double dCotTheta=-99.;
00225
00226 if ( nTracks()==2 ) {
00227 double theta1=this->tracksPin()[0].Theta();
00228 double theta2=this->tracksPin()[1].Theta();
00229 dCotTheta = 1./tan(theta1) - 1./tan(theta2) ;
00230 }
00231
00232 return dCotTheta;
00233
00234 }
00235
00236
00237 math::XYZVectorF Conversion::pairMomentum() const {
00238
00239 if ( nTracks()==2 ) {
00240 return this->tracksPin()[0] + this->tracksPin()[1];
00241 }
00242 return math::XYZVectorF(0.,0.,0.);
00243
00244
00245
00246 }
00247
00248
00249 math::XYZTLorentzVectorF Conversion::refittedPair4Momentum() const {
00250
00251 math::XYZTLorentzVectorF p4;
00252 if ( this->conversionVertex().isValid() )
00253 p4 = this->conversionVertex().p4( 0.000511, 0.5);
00254
00255 return p4;
00256
00257
00258 }
00259
00260
00261
00262 math::XYZVectorF Conversion::refittedPairMomentum() const {
00263
00264 if ( this->conversionVertex().isValid() ) {
00265 return this->refittedPair4Momentum().Vect();
00266 }
00267 return math::XYZVectorF(0.,0.,0.);
00268
00269 }
00270
00271
00272
00273 double Conversion::EoverP() const {
00274
00275
00276 double ep=-99.;
00277
00278 if ( nTracks() > 0 ) {
00279 unsigned int size= this->caloCluster().size();
00280 float etot=0.;
00281 for ( unsigned int i=0; i<size; i++) {
00282 etot+= caloCluster()[i]->energy();
00283 }
00284 if (this->pairMomentum().Mag2() !=0) ep= etot/sqrt(this->pairMomentum().Mag2());
00285 }
00286
00287
00288
00289 return ep;
00290
00291 }
00292
00293
00294
00295 double Conversion::EoverPrefittedTracks() const {
00296
00297
00298 double ep=-99.;
00299
00300 if ( nTracks() > 0 ) {
00301 unsigned int size= this->caloCluster().size();
00302 float etot=0.;
00303 for ( unsigned int i=0; i<size; i++) {
00304 etot+= caloCluster()[i]->energy();
00305 }
00306 if (this->refittedPairMomentum().Mag2() !=0) ep= etot/sqrt(this->refittedPairMomentum().Mag2());
00307 }
00308
00309
00310
00311 return ep;
00312
00313 }
00314
00315
00316
00317 std::vector<double> Conversion::tracksSigned_d0() const {
00318 std::vector<double> result;
00319
00320 for (unsigned int i=0; i< nTracks(); i++)
00321 result.push_back(tracks()[i]->d0()* tracks()[i]->charge()) ;
00322
00323 return result;
00324
00325
00326 }
00327
00328 double Conversion::dPhiTracksAtVtx() const {
00329 double result=-99;
00330 if ( nTracks()==2 ) {
00331 result = tracksPin()[0].phi() - tracksPin()[1].phi();
00332 if( result > pi) { result = result - twopi;}
00333 if( result < -pi) { result = result + twopi;}
00334 }
00335
00336 return result;
00337
00338
00339 }
00340
00341 double Conversion::dPhiTracksAtEcal() const {
00342 double result =-99.;
00343
00344 if ( nTracks()==2 && bcMatchingWithTracks()[0].isNonnull() && bcMatchingWithTracks()[1].isNonnull() ) {
00345
00346 float recoPhi1 = ecalImpactPosition()[0].phi();
00347 if( recoPhi1 > pi) { recoPhi1 = recoPhi1 - twopi;}
00348 if( recoPhi1 < -pi) { recoPhi1 = recoPhi1 + twopi;}
00349
00350 float recoPhi2 = ecalImpactPosition()[1].phi();
00351 if( recoPhi2 > pi) { recoPhi2 = recoPhi2 - twopi;}
00352 if( recoPhi2 < -pi) { recoPhi2 = recoPhi2 + twopi;}
00353
00354 result = recoPhi1 -recoPhi2;
00355
00356 if( result > pi) { result = result - twopi;}
00357 if( result < -pi) { result = result + twopi;}
00358
00359 }
00360
00361 return result;
00362
00363
00364 }
00365
00366 double Conversion::dEtaTracksAtEcal() const {
00367 double result=-99.;
00368
00369
00370 if ( nTracks()==2 && bcMatchingWithTracks()[0].isNonnull() && bcMatchingWithTracks()[1].isNonnull() ) {
00371
00372 result =ecalImpactPosition()[0].eta() - ecalImpactPosition()[1].eta();
00373
00374 }
00375
00376
00377
00378 return result;
00379
00380
00381 }
00382
00383 double Conversion::dxy(const math::XYZPoint& myBeamSpot) const {
00384
00385 const reco::Vertex &vtx = conversionVertex();
00386 if (!vtx.isValid()) return -9999.;
00387
00388 math::XYZVectorF mom = refittedPairMomentum();
00389
00390 double dxy = (-(vtx.x() - myBeamSpot.x())*mom.y() + (vtx.y() - myBeamSpot.y())*mom.x())/mom.rho();
00391 return dxy;
00392
00393 }
00394
00395 double Conversion::dz(const math::XYZPoint& myBeamSpot) const {
00396
00397 const reco::Vertex &vtx = conversionVertex();
00398 if (!vtx.isValid()) return -9999.;
00399
00400 math::XYZVectorF mom = refittedPairMomentum();
00401
00402 double dz = (vtx.z()-myBeamSpot.z()) - ((vtx.x()-myBeamSpot.x())*mom.x()+(vtx.y()-myBeamSpot.y())*mom.y())/mom.rho() * mom.z()/mom.rho();
00403 return dz;
00404
00405 }
00406
00407 double Conversion::lxy(const math::XYZPoint& myBeamSpot) const {
00408
00409 const reco::Vertex &vtx = conversionVertex();
00410 if (!vtx.isValid()) return -9999.;
00411
00412 math::XYZVectorF mom = refittedPairMomentum();
00413
00414 double dbsx = vtx.x() - myBeamSpot.x();
00415 double dbsy = vtx.y() - myBeamSpot.y();
00416 double lxy = (mom.x()*dbsx + mom.y()*dbsy)/mom.rho();
00417 return lxy;
00418
00419 }
00420
00421 double Conversion::lz(const math::XYZPoint& myBeamSpot) const {
00422
00423 const reco::Vertex &vtx = conversionVertex();
00424 if (!vtx.isValid()) return -9999.;
00425
00426 math::XYZVectorF mom = refittedPairMomentum();
00427
00428 double lz = (vtx.z() - myBeamSpot.z())*mom.z()/std::abs(mom.z());
00429 return lz;
00430
00431 }
00432