8 #include <EVENT/LCCollection.h>
9 #include <IMPL/LCCollectionVec.h>
10 #include <EVENT/ReconstructedParticle.h>
11 #include <EVENT/Cluster.h>
12 #include <UTIL/LCTypedVector.h>
13 #include <EVENT/Track.h>
14 #include <marlin/Exceptions.h>
15 #include <EVENT/Vertex.h>
16 #include <UTIL/LCIterator.h>
19 #include "marlin/VerbosityLevels.h"
24 #include "TMVA/Reader.h"
31 using namespace lcio ;
32 using namespace marlin ;
36 using namespace isolep;
44 _description =
"IsolatedLeptonTaggingProcessor does whatever it does ..." ;
49 registerInputCollection( LCIO::RECONSTRUCTEDPARTICLE,
50 "InputPandoraPFOsCollection" ,
51 "Name of the PandoraPFOs collection" ,
53 std::string(
"PandoraPFOs") ) ;
55 registerInputCollection( LCIO::VERTEX,
56 "InputPrimaryVertexCollection" ,
57 "Name of the Primary Vertex collection" ,
59 std::string(
"PrimaryVertex") ) ;
61 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
62 "OutputPFOsWithoutIsoLepCollection",
63 "Name of the new PFOs collection without isolated lepton",
65 std::string(
"PandoraPFOsWithoutIsoLep") );
67 registerOutputCollection( LCIO::RECONSTRUCTEDPARTICLE,
68 "OutputIsoLeptonsCollection",
69 "Name of collection with the selected isolated lepton",
71 std::string(
"ISOLeptons") );
73 registerProcessorParameter(
"DirOfISOElectronWeights",
74 "Directory of Weights for the Isolated Electron MVA Classification" ,
76 std::string(
"isolated_electron_weights") ) ;
78 registerProcessorParameter(
"DirOfISOMuonWeights",
79 "Directory of Weights for the Isolated Muon MVA Classification" ,
81 std::string(
"isolated_muon_weights") ) ;
83 registerProcessorParameter(
"CutOnTheISOElectronMVA",
84 "Cut on the mva output of isolated electron selection" ,
88 registerProcessorParameter(
"CutOnTheISOMuonMVA",
89 "Cut on the mva output of isolated muon selection" ,
93 registerProcessorParameter(
"IsSelectingOneIsoLep",
94 "flag to select one most like isolated lepton" ,
98 registerProcessorParameter(
"MinEOverPForElectron",
99 "minimum ratio of energy in calorimeters over momentum for electron" ,
103 registerProcessorParameter(
"MaxEOverPForElectron",
104 "Maximum ratio of energy in calorimeters over momentum for electron" ,
108 registerProcessorParameter(
"MinEecalOverTotEForElectron",
109 "minimum ratio of energy in ecal over energy in ecal+hcal" ,
113 registerProcessorParameter(
"MaxD0SigForElectron",
114 "Maximum d0 significance for electron" ,
118 registerProcessorParameter(
"MaxZ0SigForElectron",
119 "Maximum Z0 significance for electron" ,
123 registerProcessorParameter(
"MinPForElectron",
124 "Minimum momentum for electron" ,
128 registerProcessorParameter(
"MaxEOverPForMuon",
129 "Maximum ratio of energy in calorimeters over momentum for muon" ,
133 registerProcessorParameter(
"MinEyokeForMuon",
134 "Minimum energy in yoke for electron" ,
138 registerProcessorParameter(
"MaxD0SigForMuon",
139 "Maximum D0 significance for muon" ,
143 registerProcessorParameter(
"MaxZ0SigForMuon",
144 "Maximum Z0 significance for muon" ,
148 registerProcessorParameter(
"MinPForMuon",
149 "Minimum momentum for muon" ,
153 registerProcessorParameter(
"CosConeSmall",
154 "cosine of the smaller cone" ,
158 registerProcessorParameter(
"CosConeLarge",
159 "cosine of the larger cone" ,
163 registerProcessorParameter(
"UseYokeForMuonID",
164 "use yoke for muon ID" ,
168 registerProcessorParameter(
"UseIP",
169 "use impact parameters" ,
176 streamlog_out(DEBUG) <<
"IsolatedLeptonTagging init called "
184 for (Int_t i=0;i<2;i++) {
185 TMVA::Reader *reader =
new TMVA::Reader(
"Color:Silent" );
188 reader->AddVariable(
"coneec", &
_coneec );
189 reader->AddVariable(
"coneen", &
_coneen );
190 reader->AddVariable(
"momentum", &
_momentum );
191 reader->AddVariable(
"coslarcon", &
_coslarcon );
193 reader->AddVariable(
"ratioecal", &
_ratioecal );
196 reader->AddVariable(
"nsigd0", &
_nsigd0 );
197 reader->AddVariable(
"nsigz0", &
_nsigz0 );
201 reader->AddVariable(
"coneec", &
_coneec );
202 reader->AddVariable(
"coneen", &
_coneen );
203 reader->AddVariable(
"momentum", &
_momentum );
204 reader->AddVariable(
"coslarcon", &
_coslarcon );
208 reader->AddVariable(
"nsigd0", &
_nsigd0 );
209 reader->AddVariable(
"nsigz0", &
_nsigz0 );
217 TString prefix =
"TMVAClassification";
218 TString methodName =
"MLP method";
219 TString weightfile = dir +
"/" + prefix +
"_" +
"MLP.weights.xml";
220 reader->BookMVA( methodName, weightfile );
231 streamlog_out(DEBUG) <<
"Hello, Isolated Lepton Tagging!" << endl;
235 auto pPFOsWithoutIsoLepCollection = std::make_unique<LCCollectionVec>(LCIO::RECONSTRUCTEDPARTICLE);
236 auto pIsoLepCollection = std::make_unique<LCCollectionVec>(LCIO::RECONSTRUCTEDPARTICLE);
237 pPFOsWithoutIsoLepCollection->setSubset(
true);
238 pIsoLepCollection->setSubset(
true);
242 LCCollection *colPFO = evt->getCollection(
_colPFOs);
247 LCCollection *colPVtx = evt->getCollection(
_colPVtx);
248 if (colPVtx->getNumberOfElements() == 0) {
249 streamlog_out(DEBUG5) <<
"Vertex collection (" <<
_colPVtx <<
") is empty!" << std::endl;
253 auto collIter = lcio::LCIterator<lcio::ReconstructedParticle>(colPFO);
254 while (
auto* obj = collIter.next()) {
255 pPFOsWithoutIsoLepCollection->addElement(obj);
257 addOutputColls(evt, pPFOsWithoutIsoLepCollection.release(), pIsoLepCollection.release());
261 Vertex *pvtx =
dynamic_cast<Vertex*
>(colPVtx->getElementAt(0));
262 Double_t z_pvtx = pvtx->getPosition()[2];
264 Int_t nPFOs = colPFO->getNumberOfElements();
265 std::vector<lcio::ReconstructedParticle*> newPFOs;
266 std::vector<lcio::ReconstructedParticle*> isoLeptons;
267 FloatVec isoLepTagging;
271 float _mva_lep_max = -1.;
273 for (Int_t i=0;i<nPFOs;i++) {
274 ReconstructedParticle *recPart =
dynamic_cast<ReconstructedParticle*
>(colPFO->getElementAt(i));
275 Double_t energy = recPart->getEnergy();
276 Double_t charge = recPart->getCharge();
278 TrackVec tckvec = recPart->getTracks();
279 Int_t ntracks = tckvec.size();
280 Double_t d0=0.,z0=0.,deltad0=0.,deltaz0=0.,nsigd0=0.,nsigz0=0.;
282 d0 = tckvec[0]->getD0();
283 z0 = tckvec[0]->getZ0();
285 deltad0 = TMath::Sqrt(tckvec[0]->getCovMatrix()[0]);
286 deltaz0 = TMath::Sqrt(tckvec[0]->getCovMatrix()[9]);
291 newPFOs.push_back(recPart);
293 Double_t ecalEnergy = 0;
294 Double_t hcalEnergy = 0;
295 Double_t yokeEnergy = 0;
296 Double_t totalCalEnergy = 0;
297 std::vector<lcio::Cluster*> clusters = recPart->getClusters();
298 for (std::vector<lcio::Cluster*>::const_iterator iCluster=clusters.begin();iCluster!=clusters.end();++iCluster) {
299 ecalEnergy += (*iCluster)->getSubdetectorEnergies()[0];
300 hcalEnergy += (*iCluster)->getSubdetectorEnergies()[1];
301 yokeEnergy += (*iCluster)->getSubdetectorEnergies()[2];
302 ecalEnergy += (*iCluster)->getSubdetectorEnergies()[3];
303 hcalEnergy += (*iCluster)->getSubdetectorEnergies()[4];
305 totalCalEnergy = ecalEnergy + hcalEnergy;
306 TVector3 momentum = TVector3(recPart->getMomentum());
307 Double_t momentumMagnitude = momentum.Mag();
310 Bool_t woFSR = kTRUE;
311 Double_t coneEnergy0[3] = {0.,0.,0.};
312 Double_t pFSR[4] = {0.,0.,0.,0.};
313 Double_t pLargeCone[4] = {0.,0.,0.,0.};
314 Int_t nConePhoton = 0;
316 Double_t coneEN = coneEnergy0[1];
317 Double_t coneEC = coneEnergy0[2];
318 TLorentzVector lortzLargeCone = TLorentzVector(pLargeCone[0],pLargeCone[1],pLargeCone[2],pLargeCone[3]);
319 TVector3 momentumLargeCone = lortzLargeCone.Vect();
320 Double_t cosThetaWithLargeCone = 1.;
321 if (momentumLargeCone.Mag() > 0.0000001) {
322 cosThetaWithLargeCone = momentum.Dot(momentumLargeCone)/momentumMagnitude/momentumLargeCone.Mag();
324 Double_t energyRatioWithLargeCone = energy/(energy+lortzLargeCone.E());
325 Double_t ratioECal = 0., ratioTotalCal = 0.;
326 if (ecalEnergy > 0.) ratioECal = ecalEnergy/totalCalEnergy;
327 ratioTotalCal = totalCalEnergy/momentumMagnitude;
330 Double_t mva_electron = -1.,mva_muon = -1.;
342 Double_t fEpsilon = 1.E-10;
349 mva_electron =
_readers[0]->EvaluateMVA(
"MLP method" );
357 mva_muon =
_readers[1]->EvaluateMVA(
"MLP method" );
360 mva_muon =
_readers[1]->EvaluateMVA(
"MLP method" );
368 isoLeptons.push_back(recPart);
369 isoLepTagging.push_back(mva_electron);
371 isoLepType.push_back(_lep_type);
374 if (mva_electron > _mva_lep_max) {
376 _mva_lep_max = mva_electron;
378 isoLeptons.push_back(recPart);
384 isoLeptons.push_back(recPart);
385 isoLepTagging.push_back(mva_muon);
387 isoLepType.push_back(_lep_type);
390 if (mva_muon > _mva_lep_max) {
392 _mva_lep_max = mva_muon;
394 isoLeptons.push_back(recPart);
402 for (
auto* obj : isoLeptons) {
403 pIsoLepCollection->addElement(obj);
407 for (
auto* obj : newPFOs) {
409 if (std::find(isoLeptons.cbegin(), isoLeptons.cend(), obj) == isoLeptons.cend()) {
410 pPFOsWithoutIsoLepCollection->addElement(obj);
417 pIsoLepCollection->parameters().setValue(
"ISOLepTagging", _mva_lep_max );
418 pIsoLepCollection->parameters().setValue(
"ISOLepType", _lep_type );
422 pIsoLepCollection->parameters().setValues(
"ISOLepTagging", isoLepTagging );
423 pIsoLepCollection->parameters().setValues(
"ISOLepType", isoLepType );
427 addOutputColls(evt, pPFOsWithoutIsoLepCollection.release(), pIsoLepCollection.release());
438 for (std::vector<TMVA::Reader*>::const_iterator ireader=
_readers.begin();ireader!=
_readers.end();++ireader) {
445 evt->addCollection(pfosWithoutIsoLepColl,
_colNewPFOs);
virtual void end()
Called after data processing for clean up.
float _maxZ0SigForElectron
std::string _isolated_muon_weights
IsolatedLeptonTaggingProcessor()
virtual void init()
Called at the begin of the job before anything is read.
float _maxD0SigForElectron
virtual void check(LCEvent *evt)
IsolatedLeptonTaggingProcessor aIsolatedLeptonTaggingProcessor
Double_t getConeEnergy(ReconstructedParticle *recPart, LCCollection *colPFO, Double_t cosCone)
virtual void processEvent(LCEvent *evt)
Called for every event - the working horse.
float _minEecalOverTotEForElectron
virtual void processRunHeader(LCRunHeader *run)
Called for every run.
processor for isolated lepton tagging.
virtual void addOutputColls(LCEvent *evt, LCCollection *pfosWithoutIsoLepColl, LCCollection *isoLepColl)
Add the expected output collections.
std::vector< TMVA::Reader * > _readers
float _minEOverPForElectron
std::string _isolated_electron_weights
std::string _colPFOs
Input collection name.
float _maxEOverPForElectron