1 |
#include "TrkUpgradeAnalysis/VHbb/interface/LightweightAnalyser.h"
|
2 |
|
3 |
#include <sstream>
|
4 |
|
5 |
#include "TrkUpgradeAnalysis/VHbb/interface/VHbbCandidateCutSets.h"
|
6 |
#include "TrkUpgradeAnalysis/VHbb/interface/AdditionalJetStudyCutSets.h"
|
7 |
#include "TrkUpgradeAnalysis/VHbb/interface/tools.h" // required for trkupgradeanalysis::tools::createDirectory
|
8 |
#include "FWCore/Utilities/interface/EDMException.h"
|
9 |
|
10 |
#include "VHbbAnalysis/VHbbDataFormats/interface/VHbbEventAuxInfo.h"
|
11 |
#include "VHbbAnalysis/VHbbDataFormats/src/HbbCandidateFinderAlgo.cc" // Not entirely sure why this is included and not linked to
|
12 |
#include "DataFormats/FWLite/interface/Event.h"
|
13 |
#include "DataFormats/FWLite/interface/Handle.h"
|
14 |
#include "DataFormats/PatCandidates/interface/Muon.h"
|
15 |
|
16 |
|
17 |
#include <TFile.h>
|
18 |
#include <TH1.h>
|
19 |
#include <TH2.h>
|
20 |
|
21 |
|
22 |
const bool trkupgradeanalysis::LightweightAnalyser::verbose_=false;
|
23 |
const double trkupgradeanalysis::LightweightAnalyser::jetPtThresholdZ_=30;
|
24 |
const double trkupgradeanalysis::LightweightAnalyser::jetPtThresholdW_=30;
|
25 |
const bool trkupgradeanalysis::LightweightAnalyser::useHighestPtHiggsZ_=false;
|
26 |
const bool trkupgradeanalysis::LightweightAnalyser::useHighestPtHiggsW_=true;
|
27 |
|
28 |
|
29 |
trkupgradeanalysis::LightweightAnalyser::LightweightAnalyser( const std::string& outputFilename )
|
30 |
: zFinder_( verbose_, jetPtThresholdZ_, useHighestPtHiggsZ_ ),
|
31 |
wFinder_( verbose_, jetPtThresholdW_, useHighestPtHiggsW_ ),
|
32 |
numberOfEvents_(0),
|
33 |
numberOfEventsWithAtLeastOneZOrWCandidate_(0),
|
34 |
pPlotsForEverything_(NULL)
|
35 |
{
|
36 |
// All of these are empty smart pointers, so I need to call reset on them
|
37 |
pOutputFile_.reset( new TFile( outputFilename.c_str(), "RECREATE" ) );
|
38 |
|
39 |
|
40 |
using namespace trkupgradeanalysis; // Don't really need this but I like to be explicit (ooh err..)
|
41 |
// cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new SignalSelectionZee(120)) );
|
42 |
// cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new SignalSelectionZmumu(120)) );
|
43 |
cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new AllVariables) );
|
44 |
// cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new SignalSelectionStdGeom50PUZmumuWithoutAdditionalJetsCut(125)) );
|
45 |
// cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new SignalSelectionPhase150PUZmumuWithoutAdditionalJetsCut(125)) );
|
46 |
cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new InitialSignalSelectionZee) );
|
47 |
cutsToApply_.push_back( boost::shared_ptr<VHbbCandidateCutSet>(new InitialSignalSelectionZmumu) );
|
48 |
}
|
49 |
|
50 |
trkupgradeanalysis::LightweightAnalyser::~LightweightAnalyser()
|
51 |
{
|
52 |
save();
|
53 |
pOutputFile_->Close();
|
54 |
}
|
55 |
|
56 |
void trkupgradeanalysis::LightweightAnalyser::changeDirectory( const std::string& directory )
|
57 |
{
|
58 |
std::map<std::string,PlotsSplitByMCType>::iterator iPlots=plotsForEventTypes_.find(directory);
|
59 |
|
60 |
if( iPlots==plotsForEventTypes_.end() )
|
61 |
{
|
62 |
pPlotsForEverything_=&plotsForEventTypes_[directory]; // This will create a new entry in the map
|
63 |
|
64 |
// Only book the histograms for all MC event types now. I don't know what MC event types there
|
65 |
// until I look at the events so I need to wait until then
|
66 |
bookHistograms( pPlotsForEverything_->allEventTypes_, directory+"/allEvents" );
|
67 |
}
|
68 |
else pPlotsForEverything_=&iPlots->second; // This directory has already been created and the histograms booked, so reuse those
|
69 |
|
70 |
currentDirectory_=directory;
|
71 |
}
|
72 |
|
73 |
void trkupgradeanalysis::LightweightAnalyser::save()
|
74 |
{
|
75 |
pOutputFile_->Write(0,TObject::kOverwrite);
|
76 |
}
|
77 |
|
78 |
void trkupgradeanalysis::LightweightAnalyser::bookHistograms( trkupgradeanalysis::LightweightAnalyser::AllPlots& plots, const std::string& directoryName )
|
79 |
{
|
80 |
TDirectory* pRootDirectory=pOutputFile_->GetDirectory("/");
|
81 |
TDirectory* pDirectory=trkupgradeanalysis::tools::createDirectory( directoryName, pRootDirectory );
|
82 |
// TDirectory* pDirectory=pRootDirectory->GetDirectory( directoryName.c_str() );
|
83 |
// if( pDirectory==NULL ) pDirectory=pRootDirectory->mkdir( directoryName.c_str() );
|
84 |
|
85 |
TDirectory* pSubDirectory=pDirectory->mkdir( "VHbbCandidates" );
|
86 |
|
87 |
plots.pNumberOfCandidates_=new TH2F( "numberOfCandidates","Number of candidates",5,-0.5,4.5,5,-0.5,4.5);
|
88 |
plots.pNumberOfCandidates_->SetDirectory(pSubDirectory);
|
89 |
plots.candidateHistogramsForAllEvents_.book( pSubDirectory );
|
90 |
plots.pNumberOfCandidates_->GetXaxis()->SetTitle( "Z candidates" );
|
91 |
plots.pNumberOfCandidates_->GetYaxis()->SetTitle( "W candidates" );
|
92 |
|
93 |
pSubDirectory=pDirectory->mkdir( "MuonInfos" );
|
94 |
plots.allMuons_.book( pSubDirectory );
|
95 |
|
96 |
pSubDirectory=pDirectory->mkdir( "ElectronInfos" );
|
97 |
plots.allElectrons_.book( pSubDirectory );
|
98 |
|
99 |
pSubDirectory=pDirectory->mkdir( "HiggsCandidateJets" );
|
100 |
plots.higgsCandidateJets_.book( pSubDirectory );
|
101 |
|
102 |
pSubDirectory=pDirectory->mkdir( "AdditionalJets" );
|
103 |
plots.additionalJets_.book( pSubDirectory );
|
104 |
|
105 |
pSubDirectory=pDirectory->mkdir( "SimpleJets2" );
|
106 |
plots.simpleJets2_.book( pSubDirectory );
|
107 |
|
108 |
pSubDirectory=pDirectory->mkdir( "IsolationStudy" );
|
109 |
plots.isolationStudy_.book( pSubDirectory );
|
110 |
|
111 |
pSubDirectory=pDirectory->mkdir( "MonteCarloTruth" );
|
112 |
plots.monteCarloInfo_.book( pSubDirectory );
|
113 |
|
114 |
pSubDirectory=pDirectory->mkdir( "Cuts" );
|
115 |
|
116 |
for( std::vector< boost::shared_ptr<trkupgradeanalysis::VHbbCandidateCutSet> >::const_iterator iCutSet=cutsToApply_.begin();
|
117 |
iCutSet!=cutsToApply_.end(); ++iCutSet )
|
118 |
{
|
119 |
TDirectory* pSubSubDirectory=pSubDirectory->mkdir( (*iCutSet)->name().c_str() );
|
120 |
|
121 |
CutSetPlotSet newPlotSet( *iCutSet );
|
122 |
newPlotSet.book( pSubSubDirectory );
|
123 |
plots.cutCollectionPlotSets_.push_back( newPlotSet );
|
124 |
}
|
125 |
}
|
126 |
|
127 |
void trkupgradeanalysis::LightweightAnalyser::fillAllPlotsStructure( AllPlots* pPlotsToFill, const VHbbEvent& vhbbEvent, const VHbbEventAuxInfo* pVHbbEventAuxInfo, const std::vector<VHbbCandidate>& zCandidates, const std::vector<VHbbCandidate>& wCandidates )
|
128 |
{
|
129 |
pPlotsToFill->allMuons_.fill( vhbbEvent.muInfo, pVHbbEventAuxInfo );
|
130 |
pPlotsToFill->allElectrons_.fill( vhbbEvent.eleInfo );
|
131 |
if( pVHbbEventAuxInfo ) pPlotsToFill->monteCarloInfo_.fill( *pVHbbEventAuxInfo );
|
132 |
pPlotsToFill->isolationStudy_.fill( vhbbEvent, pVHbbEventAuxInfo ); // This class checks if is null itself
|
133 |
pPlotsToFill->simpleJets2_.fill( vhbbEvent.simpleJets2, pVHbbEventAuxInfo );
|
134 |
|
135 |
for( std::vector<VHbbCandidate>::const_iterator iCandidate=zCandidates.begin(); iCandidate!=zCandidates.end(); ++iCandidate )
|
136 |
{
|
137 |
pPlotsToFill->candidateHistogramsForAllEvents_.fill( *iCandidate );
|
138 |
pPlotsToFill->higgsCandidateJets_.fill( iCandidate->H.jets, pVHbbEventAuxInfo );
|
139 |
pPlotsToFill->additionalJets_.fill( iCandidate->additionalJets, pVHbbEventAuxInfo );
|
140 |
|
141 |
// Loop over all of the cuts. If this candidate passes the cuts then fill the plots
|
142 |
for( std::vector<CutSetPlotSet>::iterator iCutPlotSet=pPlotsToFill->cutCollectionPlotSets_.begin();
|
143 |
iCutPlotSet!=pPlotsToFill->cutCollectionPlotSets_.end(); ++iCutPlotSet )
|
144 |
{
|
145 |
iCutPlotSet->fill( *iCandidate );
|
146 |
}
|
147 |
}
|
148 |
|
149 |
pPlotsToFill->pNumberOfCandidates_->Fill( zCandidates.size(), wCandidates.size() );
|
150 |
}
|
151 |
|
152 |
void trkupgradeanalysis::LightweightAnalyser::processEvent( const fwlite::Event& event )
|
153 |
{
|
154 |
std::vector<VHbbCandidate> zCandidates;
|
155 |
std::vector<VHbbCandidate> wCandidates;
|
156 |
|
157 |
fwlite::Handle<VHbbEvent> vhbbHandle;
|
158 |
vhbbHandle.getByLabel( event, "HbbAnalyzerNew" );
|
159 |
const VHbbEvent* pVHbbEvent=vhbbHandle.product();
|
160 |
if( pVHbbEvent == 0 )
|
161 |
{
|
162 |
std::cerr << "Couldn't get the VHbbEvent" << std::endl;
|
163 |
return;
|
164 |
}
|
165 |
|
166 |
AllPlots* pCurrentPlotsForThisEventType=NULL;
|
167 |
fwlite::Handle<VHbbEventAuxInfo> vhbbAuxInfoHandle;
|
168 |
vhbbAuxInfoHandle.getByLabel( event, "HbbAnalyzerNew" );
|
169 |
const VHbbEventAuxInfo* pVHbbEventAuxInfo=vhbbAuxInfoHandle.product();
|
170 |
if( pVHbbEventAuxInfo == 0 ) std::cerr << "Couldn't get the VHbbEventAuxInfo" << std::endl;
|
171 |
else
|
172 |
{
|
173 |
std::string eventType=eventTypeFromMC( *pVHbbEventAuxInfo );
|
174 |
|
175 |
std::map<std::string,AllPlots>::iterator iPlotsForThisEventType=pPlotsForEverything_->mcEventTypePlots_.find(eventType);
|
176 |
|
177 |
if( iPlotsForThisEventType==pPlotsForEverything_->mcEventTypePlots_.end() )
|
178 |
{
|
179 |
// This event type hasn't been encountered before so I need to book the histograms
|
180 |
AllPlots& plotsForThisEventType=pPlotsForEverything_->mcEventTypePlots_[eventType];
|
181 |
bookHistograms( plotsForThisEventType, currentDirectory_+"/"+eventType );
|
182 |
pCurrentPlotsForThisEventType=&plotsForThisEventType;
|
183 |
}
|
184 |
else pCurrentPlotsForThisEventType=&(iPlotsForThisEventType->second);
|
185 |
}
|
186 |
|
187 |
++numberOfEvents_;
|
188 |
|
189 |
bool applyMuonIsolation=false;
|
190 |
// Apply isolation to the muons. Need to modify so use a very naughty const cast
|
191 |
if( applyMuonIsolation )
|
192 |
{
|
193 |
std::vector<VHbbEvent::MuonInfo>& muonInfos=const_cast< std::vector<VHbbEvent::MuonInfo>& >( pVHbbEvent->muInfo );
|
194 |
bool allMuonsPassIsolationCut=false;
|
195 |
while( !allMuonsPassIsolationCut )
|
196 |
{
|
197 |
// I'm worried about looping using invalidated iterators, so whenever I erase an element I'll
|
198 |
// start looping from the start. Not the most efficient way but these vectors typically have
|
199 |
// at most 3 entries.
|
200 |
std::vector<VHbbEvent::MuonInfo>::iterator iMuon;
|
201 |
for( iMuon=muonInfos.begin(); iMuon!=muonInfos.end(); ++iMuon )
|
202 |
{
|
203 |
float isolation=MuonInfoPlotSet::thirdRho25CorrectedIsolation( *iMuon, pVHbbEventAuxInfo->puInfo.rho25 );
|
204 |
if( isolation>=0.15 ) break;
|
205 |
}
|
206 |
if( iMuon!=muonInfos.end() ) muonInfos.erase( iMuon );
|
207 |
else allMuonsPassIsolationCut=true;
|
208 |
}
|
209 |
}
|
210 |
|
211 |
zFinder_.run( pVHbbEvent, zCandidates );
|
212 |
wFinder_.run( pVHbbEvent, wCandidates );
|
213 |
|
214 |
fillAllPlotsStructure( &pPlotsForEverything_->allEventTypes_, *pVHbbEvent, pVHbbEventAuxInfo, zCandidates, wCandidates );
|
215 |
if( pCurrentPlotsForThisEventType!=NULL ) fillAllPlotsStructure( pCurrentPlotsForThisEventType, *pVHbbEvent, pVHbbEventAuxInfo, zCandidates, wCandidates );
|
216 |
|
217 |
|
218 |
if( !zCandidates.empty() || !wCandidates.empty() ) ++numberOfEventsWithAtLeastOneZOrWCandidate_;
|
219 |
|
220 |
}
|
221 |
|
222 |
void trkupgradeanalysis::LightweightAnalyser::processFile( TFile* pInputFile, size_t numberOfEvents )
|
223 |
{
|
224 |
if( pPlotsForEverything_==NULL ) changeDirectory("allEvents");
|
225 |
|
226 |
fwlite::Event event( pInputFile );
|
227 |
|
228 |
size_t eventCount=0;
|
229 |
for( event.toBegin(); !event.atEnd(); ++event )
|
230 |
{
|
231 |
try
|
232 |
{
|
233 |
processEvent( event );
|
234 |
++eventCount;
|
235 |
}
|
236 |
catch( edm::Exception& error )
|
237 |
{
|
238 |
std::cerr << error.what() << std::endl;
|
239 |
}
|
240 |
|
241 |
if( numberOfEvents!=0 && eventCount>=numberOfEvents )
|
242 |
{
|
243 |
std::cout << "Breaking after " << eventCount << " events" << std::endl;
|
244 |
break;
|
245 |
}
|
246 |
}
|
247 |
|
248 |
std::cout << "There were " << numberOfEventsWithAtLeastOneZOrWCandidate_ << " events with a Z or W candidate out of " << numberOfEvents_ << " events." << std::endl;
|
249 |
}
|
250 |
|
251 |
std::string trkupgradeanalysis::LightweightAnalyser::eventTypeFromMC( const VHbbEventAuxInfo& eventAuxInfo )
|
252 |
{
|
253 |
std::stringstream eventStringStream;
|
254 |
|
255 |
std::vector<VHbbEventAuxInfo::ParticleMCInfo> zMCInfo=eventAuxInfo.mcZ;
|
256 |
std::vector<VHbbEventAuxInfo::ParticleMCInfo> higgsMCInfo=eventAuxInfo.mcH;
|
257 |
|
258 |
for( std::vector<VHbbEventAuxInfo::ParticleMCInfo>::const_iterator higgsInfo=higgsMCInfo.begin(); higgsInfo!=higgsMCInfo.end(); ++higgsInfo )
|
259 |
{
|
260 |
if( higgsInfo->dauid.size()==1 && std::abs(higgsInfo->dauid[0])==25 ) continue;
|
261 |
|
262 |
eventStringStream << "H->(";
|
263 |
for( std::vector<int>::const_iterator daughterID=higgsInfo->dauid.begin(); daughterID!=higgsInfo->dauid.end(); ++daughterID )
|
264 |
{
|
265 |
if( daughterID!=higgsInfo->dauid.begin() ) eventStringStream << ",";
|
266 |
eventStringStream << *daughterID;
|
267 |
}
|
268 |
eventStringStream << ") ";
|
269 |
}
|
270 |
|
271 |
for( std::vector<VHbbEventAuxInfo::ParticleMCInfo>::const_iterator zInfo=zMCInfo.begin(); zInfo!=zMCInfo.end(); ++zInfo )
|
272 |
{
|
273 |
if( zInfo->dauid.empty() ) continue;
|
274 |
if( zInfo->dauid.size()==1 && std::abs(zInfo->dauid[0])==23 ) continue;
|
275 |
if( zInfo->dauid.size()==2 && std::abs(zInfo->dauid[0])==23 && std::abs(zInfo->dauid[1])==25 ) continue;
|
276 |
|
277 |
eventStringStream << "Z->(";
|
278 |
for( std::vector<int>::const_iterator daughterID=zInfo->dauid.begin(); daughterID!=zInfo->dauid.end(); ++daughterID )
|
279 |
{
|
280 |
if( *daughterID==23 ) continue;
|
281 |
if( zInfo->dauid.size()>2 && *daughterID==22 ) continue;
|
282 |
if( daughterID!=zInfo->dauid.begin() ) eventStringStream << ",";
|
283 |
eventStringStream << *daughterID;
|
284 |
}
|
285 |
eventStringStream << ") ";
|
286 |
}
|
287 |
|
288 |
if( eventStringStream.str().empty() ) return "otherBackground";
|
289 |
else return eventStringStream.str();
|
290 |
}
|
291 |
|