00001 #include "RecoParticleFlow/PFProducer/interface/PFConversionAlgo.h"
00002 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
00003 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementCluster.h"
00004 #include "DataFormats/ParticleFlowReco/interface/PFBlockElementBrem.h"
00005 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFraction.h"
00006 #include "DataFormats/ParticleFlowReco/interface/PFRecHitFwd.h"
00007 #include "DataFormats/ParticleFlowReco/interface/PFRecHit.h"
00008 #include "DataFormats/ParticleFlowReco/interface/PFCluster.h"
00009 #include "DataFormats/ParticleFlowReco/interface/PFConversion.h"
00010 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00011 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
00012 #include "DataFormats/CaloRecHit/interface/CaloClusterFwd.h"
00013 #include "RecoParticleFlow/PFProducer/interface/Utils.h"
00014 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyCalibration.h"
00015 #include "RecoParticleFlow/PFClusterTools/interface/PFEnergyResolution.h"
00016 #include "CLHEP/Units/GlobalPhysicalConstants.h"
00017
00018 using namespace std;
00019 using namespace reco;
00020 PFConversionAlgo::PFConversionAlgo( ) {
00021
00022 }
00023
00024 void PFConversionAlgo::runPFConversion(const reco::PFBlockRef& blockRef,
00025 std::vector<bool>& active) {
00026
00027
00028
00029 AssMap elemAssociatedToConv;
00030
00031 bool blockHasConversion = setLinks(blockRef,elemAssociatedToConv, active );
00032
00033 if ( blockHasConversion ) {
00034 conversionCandidate_.clear();
00035 setCandidates(blockRef,elemAssociatedToConv);
00036 if (conversionCandidate_.size() > 0 ){
00037 isvalid_ = true;
00038
00039
00040
00041 setActive(blockRef,elemAssociatedToConv, active);
00042
00043 std::vector<reco::PFCandidate>::iterator it;
00044 for ( it = conversionCandidate_.begin(); it != conversionCandidate_.end(); ++it ) {
00045 reco::PFCandidate::ParticleType type = (*it).particleId();
00046 bool isConverted = (*it).flag( reco::PFCandidate::GAMMA_TO_GAMMACONV );
00047 if ( type == reco::PFCandidate::gamma && isConverted ) {
00048
00049 }
00050 }
00051 }
00052
00053 }
00054
00055 }
00056
00057
00058 bool PFConversionAlgo::setLinks(const reco::PFBlockRef& blockRef,
00059 AssMap& elemAssociatedToConv,
00060 std::vector<bool>& active ) {
00061
00062 bool conversionFound = false;
00063 typedef std::multimap<double, unsigned>::iterator IE;
00064 const reco::PFBlock& block = *blockRef;
00065
00066 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00067 PFBlock::LinkData linkData = block.linkData();
00068
00069
00070
00071
00072
00073 unsigned convTrack1Ind=100;
00074 unsigned convTrack2Ind=100;
00075 unsigned convEcal1Ind=200;
00076 unsigned convEcal2Ind=200;
00077 unsigned convHcal1Ind=200;
00078 unsigned convHcal2Ind=200;
00079
00080 for(unsigned iElem=0; iElem<elements.size(); iElem++) {
00081 bool trackFromConv = elements[iElem].trackType( PFBlockElement::T_FROM_GAMMACONV);
00082
00083 if (!active[iElem]) continue;
00084 if ( !trackFromConv ) continue;
00085 conversionFound = true;
00086
00087
00088 convTrack1Ind= iElem;
00089
00090 std::multimap<unsigned, std::vector<unsigned> >::iterator found = elemAssociatedToConv.find(iElem);
00091 if ( found!= elemAssociatedToConv.end()) {
00092
00093 continue;
00094 }
00095
00096
00097 bool alreadyTaken=false;
00098 for ( std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin();
00099 i!= elemAssociatedToConv.end(); ++i) {
00100 for (unsigned int j=0; j< (i->second).size(); ++j ) {
00101 if ( iElem == (i->second)[j] ) alreadyTaken=true;
00102 }
00103 }
00104 if ( alreadyTaken ) {
00105
00106 continue;
00107 }
00108
00109
00110 vector<unsigned> assElements(0);
00111 vector<unsigned>::iterator iVec;
00112
00113 std::multimap<double, unsigned> ecalElems;
00114 block.associatedElements(iElem , linkData,
00115 ecalElems ,
00116 reco::PFBlockElement::ECAL );
00117
00118 std::multimap<double, unsigned> hcalElems;
00119 block.associatedElements( iElem , linkData,
00120 hcalElems,
00121 reco::PFBlockElement::HCAL,
00122 reco::PFBlock::LINKTEST_ALL );
00123
00124 std::multimap<double, unsigned> trackElems;
00125 block.associatedElements( iElem, linkData,
00126 trackElems ,
00127 reco::PFBlockElement::TRACK,
00128 reco::PFBlock::LINKTEST_RECHIT);
00129
00130
00131 if(trackElems.empty() ) {
00132
00133 }
00134
00135 if(ecalElems.empty() ) {
00136
00137 }
00138
00139 if(hcalElems.empty() ) {
00140
00141 }
00142
00143
00144
00145
00146
00147
00148 for(IE iTk = hcalElems.begin(); iTk != hcalElems.end(); ++iTk ) {
00149 unsigned index = iTk->second;
00150 PFBlockElement::Type type = elements[index].type();
00151 if ( type == reco::PFBlockElement::HCAL) {
00152
00153 convHcal1Ind=index;
00154
00155
00156 }
00157 }
00158
00159
00160
00161
00162 for(IE iTk = ecalElems.begin(); iTk != ecalElems.end(); ++iTk ) {
00163 unsigned index = iTk->second;
00164 PFBlockElement::Type type = elements[index].type();
00165 if ( type == reco::PFBlockElement::ECAL) {
00166
00167 convEcal1Ind=index;
00168
00169 iVec = find ( assElements.begin(), assElements.end(), index) ;
00170 if ( index< 100 && iVec == assElements.end() ) assElements.push_back(index);
00171 }
00172 }
00173
00174
00175
00176 for(IE iTk = trackElems.begin(); iTk != trackElems.end(); ++iTk ) {
00177 unsigned index = iTk->second;
00178
00179
00180 convTrack2Ind=index;
00181 if ( index< 100) assElements.push_back(index);
00182
00183 std::multimap<double, unsigned> ecalElems2;
00184 block.associatedElements(convTrack2Ind , linkData,
00185 ecalElems2 ,
00186 reco::PFBlockElement::ECAL );
00187
00188
00189 for(IE iTk = ecalElems2.begin(); iTk != ecalElems2.end(); ++iTk ) {
00190 unsigned index = iTk->second;
00191 PFBlockElement::Type type = elements[index].type();
00192 if ( type == reco::PFBlockElement::ECAL) {
00193 convEcal2Ind=index;
00194
00195 iVec = find ( assElements.begin(), assElements.end(), index) ;
00196 if ( index< 100 && iVec== assElements.end() ) assElements.push_back(index);
00197
00198 }
00199 }
00200
00201 std::multimap<double, unsigned> hcalElems2;
00202 block.associatedElements(convTrack2Ind , linkData,
00203 hcalElems2 ,
00204 reco::PFBlockElement::HCAL );
00205 for(IE iTk = hcalElems.begin(); iTk != hcalElems.end(); ++iTk ) {
00206 unsigned index = iTk->second;
00207 PFBlockElement::Type type = elements[index].type();
00208 if ( type == reco::PFBlockElement::HCAL) {
00209
00210 convHcal2Ind=index;
00211 std::cout << " Hcal-Track link found with " << convHcal2Ind << std::endl;
00212
00213 }
00214 }
00215
00216 }
00217
00218
00219 elemAssociatedToConv.insert(make_pair(convTrack1Ind, assElements));
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235 }
00236
00237
00238 return conversionFound;
00239
00240 }
00241
00242
00243 void PFConversionAlgo::setCandidates(const reco::PFBlockRef& blockRef,
00244 AssMap& elemAssociatedToConv ) {
00245
00246
00247 vector<unsigned int> elementsToAdd(0);
00248 const reco::PFBlock& block = *blockRef;
00249 PFBlock::LinkData linkData = block.linkData();
00250 const edm::OwnVector< reco::PFBlockElement >& elements = block.elements();
00251
00254 float EcalEne=0;
00255 float pairPx=0;
00256 float pairPy=0;
00257 float pairPz=0;
00258 const reco::PFBlockElementTrack* elTrack=0;
00259 reco::TrackRef convTrackRef;
00260 for ( std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin();
00261 i!= elemAssociatedToConv.end(); ++i) {
00262
00263 unsigned int iTrack = i->first;
00264 elementsToAdd.push_back(iTrack);
00265
00266 elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iTrack]));
00267 convTrackRef= elTrack->trackRef();
00268 pairPx+=convTrackRef->innerMomentum().x();
00269 pairPy+=convTrackRef->innerMomentum().y();
00270 pairPz+=convTrackRef->innerMomentum().z();
00271
00272 ConversionRef origConv = elements[iTrack].convRef();
00273
00274
00275
00276 unsigned int nEl= (i->second).size();
00277
00278 for (unsigned int j=0; j< nEl; ++j ) {
00279 unsigned int iEl = (i->second)[j];
00280
00281 PFBlockElement::Type typeassCalo = elements[iEl].type();
00282
00284 if ( typeassCalo == reco::PFBlockElement::TRACK) {
00285 const reco::PFBlockElementTrack * elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEl]));
00286 elTrack = dynamic_cast<const reco::PFBlockElementTrack*>((&elements[iEl]));
00287 convTrackRef= elTrack->trackRef();
00288 pairPx+=convTrackRef->innerMomentum().x();
00289 pairPy+=convTrackRef->innerMomentum().y();
00290 pairPz+=convTrackRef->innerMomentum().z();
00291 }
00292
00293 if ( typeassCalo == reco::PFBlockElement::ECAL) {
00294 const reco::PFBlockElementCluster * clu = dynamic_cast<const reco::PFBlockElementCluster*>((&elements[iEl]));
00295 reco::PFCluster cl=*clu->clusterRef();
00296 EcalEne+= cl.energy();
00297 }
00298
00299 elementsToAdd.push_back(iEl);
00300 }
00301
00302
00303 reco::PFCandidate::ParticleType particleType = reco::PFCandidate::gamma;
00304
00305
00306
00307 math::XYZTLorentzVector momentum;
00308 momentum.SetPxPyPzE(pairPx , pairPy, pairPz, EcalEne);
00309
00311
00312 float deltaCotTheta=origConv->pairCotThetaSeparation();
00313 float phiTk1= origConv->tracks()[0]->innerMomentum().phi();
00314 float phiTk2= origConv->tracks()[1]->innerMomentum().phi();
00315 float deltaPhi = phiTk1-phiTk2;
00316 if(deltaPhi > pi) {deltaPhi = deltaPhi - twopi;}
00317 if(deltaPhi < -pi) {deltaPhi = deltaPhi + twopi;}
00318
00320 if ( fabs(deltaCotTheta) < 0.05 && abs(deltaPhi<0.1) ) {
00321
00322
00324 reco::PFCandidate aCandidate = PFCandidate(0, momentum,particleType);
00325 for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
00326 aCandidate.addElementInBlock(blockRef,elementsToAdd[elad]);
00327 }
00328
00329
00330 aCandidate.setFlag( reco::PFCandidate::GAMMA_TO_GAMMACONV, true);
00331 aCandidate.setConversionRef(origConv);
00332 aCandidate.setEcalEnergy(EcalEne,EcalEne);
00333 aCandidate.setHcalEnergy(0.,0.);
00334 aCandidate.setPs1Energy(0.);
00335 aCandidate.setPs2Energy(0.);
00336
00337
00338 conversionCandidate_.push_back( aCandidate);
00339 }
00340
00341
00342 }
00343
00344
00345
00346 return;
00347 }
00348
00349
00350
00351
00352 void PFConversionAlgo::setActive(const reco::PFBlockRef& blockRef,
00353 AssMap& elemAssociatedToConv, std::vector<bool>& active ) {
00354
00355
00356 for ( std::multimap<unsigned, std::vector<unsigned> >::iterator i=elemAssociatedToConv.begin();
00357 i!= elemAssociatedToConv.end(); ++i) {
00358 unsigned int iConvTrk = i->first;
00359 active[iConvTrk]=false;
00360
00361 for (unsigned int j=0; j< (i->second).size(); ++j ) {
00362 active[(i->second)[j]]=false;
00363
00364 }
00365 }
00366
00367
00368 return;
00369 }
00370