Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] import FCCAnalyses #293

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions examples/FCCee/import/AddAnalyzers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#include "edm4hep/MCParticleData.h"

ROOT::VecOps::RVec<edm4hep::MCParticleData> gen_particles() {
ROOT::VecOps::RVec<edm4hep::MCParticleData> result;
edm4hep::MCParticleData mcPart;
mcPart.momentum.x = 11;
result.push_back(mcPart);

return result;
}
28 changes: 28 additions & 0 deletions examples/FCCee/import/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import FCCAnalyses
import ROOT

ROOT.gROOT.SetBatch(True)

def main():
'''
Example analysis entry point
'''

fccana = FCCAnalyses.Analysis('Test Analysis', 7)

fccana.add_analyzers('examples/FCCee/import/AddAnalyzers.h')

# fccana.add_files('examples/FCCee/import/test.root')

dframe = fccana.get_dataframe()
dframe2 = dframe.Define("particles", "gen_particles()")
dframe3 = dframe2.Define("particles_pt", "MCParticle::get_pt(particles)")
hist = dframe3.Histo1D("particles_pt")
hist.Print()

canvas = ROOT.TCanvas("canvas", "", 450, 450)
hist.Draw()
canvas.Print('test.pdf')

if __name__ == '__main__':
main()
109 changes: 109 additions & 0 deletions python/FCCAnalyses.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
'''@package FCCAnalyses
Provides FCCAnalysis facilities as a Python import.
'''

import os
import sys
import ROOT

class Analysis:
'''
The main class holding analysis settings
'''
def __init__(self, name, datasource='local_files'):
self.name = name
self.description = ''
self.datasource = datasource
if isinstance(datasource, int):
self.n_events = datasource
self.datasource = 'n_events'
if datasource == 'local_files':
self.local_files = []

self.additional_analyzers = []

def set_description(self, description):
'''
Set Analysis description.
'''
self.description = description

def get_dataframe(self):
'''
Create and return ROOT RDataFrame
'''
print('----> INFO: Loading standard FCCAnalyses analyzers...')
# TODO: find out which are actually needed
ROOT.gSystem.Load("libedm4hep")
ROOT.gSystem.Load("libpodio")
ROOT.gSystem.Load("libFCCAnalyses")
ROOT.gInterpreter.Declare("using namespace FCCAnalyses;")
_pod = ROOT.podio.ObjectID()
_edm = ROOT.edm4hep.ReconstructedParticleData()
_fcc = ROOT.dummyLoader()

print('----> INFO: Loading additional analyzers from:')
for path in self.additional_analyzers:
print(' -', path)

for path in self.additional_analyzers:
ROOT.gInterpreter.Declare(f'#include "{path}"')

if self.datasource == 'local_files':
if not self.local_files:
print('----> ERROR: No input files provided. Aborting...')
sys.exit(3)
print('----> INFO: Analysis will run over the following input '
'files:')
for path in self.local_files:
print(' -', path)

dframe = ROOT.RDataFrame('events', self.local_files)

elif self.datasource == 'n_events':
print('----> INFO: Creating clear ROOT RDataFrame from '
f'{self.n_events} events')
dframe = ROOT.RDataFrame(self.n_events)

return dframe

def add_files(self, infile_paths):
'''
Adds file paths of local input files
'''
if isinstance(infile_paths, str):
infile_paths = [infile_paths]
if isinstance(infile_paths, list):
for path in infile_paths:
if os.path.exists(path):
self.local_files.append(os.path.abspath(path))
else:
print('----> ERROR: Input file not found!')
print(' ' + os.path.abspath(path))
sys.exit(3)
else:
print('----> ERROR: Input files object is not a string nor a list')
sys.exit(3)

def add_analyzers(self, add_analyzers_paths):
'''
Loads additional analyzers to the ROOT gInterpreter.
The analyzers are JITed every time the analysis is run.

Accepts either string or list of string.
'''
if isinstance(add_analyzers_paths, str):
add_analyzers_paths = [add_analyzers_paths]
if isinstance(add_analyzers_paths, list):
for path in add_analyzers_paths:
if os.path.exists(path):
self.additional_analyzers.append(os.path.abspath(path))
else:
print('----> ERROR: File with additional analyzers not '
'found!')
print(' ' + os.path.abspath(path))
sys.exit(3)
else:
print('----> ERROR: Additional analyzer object is not a string nor '
'a list')
sys.exit(3)
Loading