7 #include <EVENT/LCCollection.h>
8 #include <EVENT/MCParticle.h>
9 #include <EVENT/ReconstructedParticle.h>
10 #include <IMPL/LCCollectionVec.h>
11 #include <IMPL/ReconstructedParticleImpl.h>
14 #include "marlin/VerbosityLevels.h"
21 using namespace lcio ;
22 using namespace marlin ;
31 _description =
"Tau Jet Finding" ;
34 registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
36 "PandoraPFA PFO collection",
38 std::string(
"PandoraPFOs") );
40 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
41 "OutputTauCollection",
42 "Tau output collection",
44 std::string(
"TaJets") );
46 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
47 "RemainPFOCollection",
48 "Remained PFO collection",
50 std::string(
"RemainPFOs") );
57 registerProcessorParameter(
"TauMass",
58 "Tau mass for tau clustering [GeV]",
61 registerProcessorParameter(
"TauCosAngle",
62 "Allowed cosine angle to be clustered",
67 registerProcessorParameter(
"NoSelection",
68 "Neither primary nor cone cut at all if true. Only clustering.",
72 registerProcessorParameter(
"MinimumTrackEnergy",
73 "Minimum track energy to be accepted as taus",
76 registerProcessorParameter(
"MinimumJetEnergy",
77 "Minimum jet energy to be accepted as taus",
80 registerProcessorParameter(
"MinimumTrackEnergyAssoc",
81 "Minimum track energy to be counted",
84 registerProcessorParameter(
"MaximumNeutralEnergyIn3Prong",
85 "Reject 3-prong taus if including neutral energy more than this number in GeV",
88 registerProcessorParameter(
"AcceptFlexibleLowEnergyTrack",
89 "Low energy tracks can be accepted as either charged and neutral if true",
94 registerProcessorParameter(
"ConeMinCosAngle",
95 "Minimum cosine angle for cone",
98 registerProcessorParameter(
"ConeMaxCosAngle",
99 "Maximum cosine angle for cone",
102 registerProcessorParameter(
"ConeMaxEnergyFrac",
103 "Energy fraction of cone compared to central",
162 streamlog_out(DEBUG) <<
" init called "
178 bool compareEnergy( ReconstructedParticle *
const &p1, ReconstructedParticle *
const &p2 )
180 return p1->getEnergy() > p2->getEnergy();
187 int nPart = col->getNumberOfElements();
192 pRemainCol->setSubset(
true);
194 vector< ReconstructedParticle * > parts;
195 vector< ReconstructedParticle * > tajets;
197 for(
int i = 0; i < nPart; i++ ) {
198 parts.push_back( dynamic_cast< ReconstructedParticle* >( col->getElementAt(i) ) );
211 for(
int i = 0; i < nPart; i++ )
213 ReconstructedParticle *pCur = parts[i];
214 if( pCur == NULL )
continue;
215 if( !pCur->getCharge() )
continue;
221 vector< ReconstructedParticle * > jetTracks, jetNeutrals;
223 jetTracks.push_back( pCur );
225 double jetEnergy = pCur->getEnergy();
226 TVector3 jetMomentum(pCur->getMomentum());
227 double jetCharge = pCur->getCharge();
229 double eneutral = 0.;
234 int nPartAssoc = 1, nPartAssocPriv = 0;
236 while( nPartAssoc != nPartAssocPriv ){
237 for(
int j = 0; j < nPart; j++ )
239 ReconstructedParticle *pCur2 = parts[j];
242 if( pCur2 == NULL )
continue;
243 if( pCur2->getCharge() && find( jetTracks.begin(), jetTracks.end(), pCur2 ) != jetTracks.end() )
continue;
244 if( !pCur2->getCharge() && find( jetNeutrals.begin(), jetNeutrals.end(), pCur2 ) != jetNeutrals.end() )
continue;
246 TVector3 vec2( pCur2->getMomentum() );
248 double cosangle = vec2.Unit().Dot( jetMomentum.Unit() );
249 double invmass2 = pow( pCur2->getEnergy() + jetEnergy, 2 ) - ( jetMomentum + vec2 ).Mag2();
261 jetEnergy += pCur2->getEnergy();
264 if( pCur2->getCharge() != 0. ){
268 jetCharge += pCur2->getCharge();
269 jetTracks.push_back( pCur2 );
273 jetNeutrals.push_back( pCur2 );
277 eneutral += pCur2->getEnergy();
278 jetNeutrals.push_back( pCur2 );
281 nPartAssocPriv = nPartAssoc;
282 nPartAssoc = jetTracks.size() + jetNeutrals.size();
292 while( ( ntracks != 1 && ntracks != 3 ) || abs(
int( jetCharge ) ) != 1 ){
293 ReconstructedParticle *p = jetTracks[ jetTracks.size()-1 ];
297 jetCharge -= p->getCharge();
300 jetTracks.pop_back();
303 jetNeutrals.push_back(p);
310 if( ( ntracks != 1 && ntracks != 3 ) || abs(
int( jetCharge ) ) != 1 ){
continue; }
313 ReconstructedParticleImpl *pJet =
new ReconstructedParticleImpl;
315 pJet->setEnergy( jetEnergy );
317 mom[0] = jetMomentum.x();
318 mom[1] = jetMomentum.y();
319 mom[2] = jetMomentum.z();
320 pJet->setMomentum( mom );
321 pJet->setCharge( jetCharge );
324 for(
unsigned int n = 0; n < jetTracks.size(); n++ )
325 pJet->addParticle( jetTracks[n] );
326 for(
unsigned int n = 0; n < jetNeutrals.size(); n++ )
327 pJet->addParticle( jetNeutrals[n] );
337 for(
int j = 0; j < nPart; j++ ) {
338 ReconstructedParticle *p =
dynamic_cast< ReconstructedParticle*
>( col->getElementAt(j) );
341 if( find( pJet->getParticles().begin(), pJet->getParticles().end(), p ) != pJet->getParticles().end() )
continue;
343 TVector3 v( p->getMomentum() );
344 double cosangle = cos( v.Angle( jetMomentum ) );
347 econe += p->getEnergy();
437 pTaJetsCol->addElement( pJet );
439 for(
int j = 0; j < nPart; j++ ) {
440 ReconstructedParticle *p = parts[j];
444 if( find( pJet->getParticles().begin(), pJet->getParticles().end(), p ) != pJet->getParticles().end() ) parts[j] = 0;
452 for(
int j = 0; j < nPart; j++ ) {
453 ReconstructedParticle *p = parts[j];
456 pRemainCol->addElement(p);
461 streamlog_out(DEBUG) <<
" processing event: " << evt->getEventNumber()
462 <<
" in run: " << evt->getRunNumber()
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
std::string _remainCollectionName
virtual void check(LCEvent *evt)
std::string _pfoCollectionName
Input collection name.
int _acceptFlexibleLowEnergyTrack
double _coneMaxEnergyFrac
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
double _maximumNeutralEnergyInThreeProng
double _minimumTrackEnergyAssoc
TaJetClustering aTaJetClustering
virtual void init()
Called at the begin of the job before anything is read.
std::string _tauCollectionName
double _minimumTrackEnergy
std::vector< LCCollection * > LCCollectionVec
virtual void end()
Called after data processing for clean up.
bool compareEnergy(ReconstructedParticle *const &p1, ReconstructedParticle *const &p2)