ATLAS Offline Software
Loading...
Searching...
No Matches
runLayerRecalibration.py
Go to the documentation of this file.
1#!/usr/bin/env python
2
3# Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
4
5""" To compute corrected layer energies """
6
7from glob import glob
8import os.path
9import os
10from array import array
11from itertools import izip
12import logging
13logging.basicConfig(level=logging.DEBUG)
14
15import ROOT
16ROOT.PyConfig.IgnoreCommandLineOptions = True
17
18try:
19 ROOT.gROOT.Macro("$ROOTCOREDIR/scripts/load_packages.C")
20except RuntimeError:
21 print("""you have to compile egammaLayerRecalibTool first:
22rc find_packages
23rc compile
24""")
25
26
27def LayerRecalibratedGenerator(input_tree, branches):
28 ""
29 tool = ROOT.egammaLayerRecalibTool("2012_alt_with_layer2")
30
31 def _rec(eta, e0, e1, e2, e3):
32 std_calibration_input = ROOT.StdCalibrationInputs(0, eta, e0, e1, e2, e3, 0)
33 tool.scale_inputs(std_calibration_input)
34 return std_calibration_input.E0raw, std_calibration_input.E1raw, std_calibration_input.E2raw, std_calibration_input.E3raw
35 fcn = _rec
36 entries = input_tree.GetEntries()
37 for i in range(entries):
38 input_tree.GetEntry(i)
39 # check if branch exists
40 try:
41 inputs = list(map(input_tree.__getattr__, branches))
42 except AttributeError:
43 raise AttributeError("cannot find branches %s" % branches)
44
45 try:
46 yield fcn(*inputs) # scalar
47 except TypeError:
48 result = [fcn(*ii) for ii in izip(*inputs)] # vectors
49 yield list(zip(*result))
50
51if __name__ == "__main__":
52 from optparse import OptionParser
53
54 def foo_callback(option, opt, value, parser):
55 setattr(parser.values, option.dest, value.split(','))
56
57 parser = OptionParser()
58 parser.add_option("-i", "--input", help="input file or directory")
59 parser.add_option("--nevents", type=int, help="number of events")
60 parser.add_option("-t", "--tree", help="input tree name")
61 parser.add_option("-p", "--particle", type="choice", help="particle type (electron|photon)", choices=("electron","photon"))
62 parser.add_option("-b", "--branches-to-copy", type='string',
63 action='callback',
64 callback=foo_callback,
65 help=r"comma separated list of branches to copy from the input tree, you can use \*, do not use spaces")
66
67 (options, args) = parser.parse_args()
68
69 input_filenames = None
70 if os.path.isdir(options.input):
71 input_filenames = glob(os.path.join(options.input, "*.root*"))
72 else:
73 input_filenames = [options.input]
74 if not input_filenames:
75 print("ERROR: no files found")
76
77 if not options.particle:
78 raise ValueError("you need to specify a value of --particle")
79
80 logging.info("found %s files", len(input_filenames))
81
82 try:
83 ROOT.egammaLayerRecalibTool
84 except Exception:
85 raise AttributeError('You have to load egammaLayerRecalibTool package')
86
87 prefix = 'el_' if options.particle == 'electron' else 'ph_'
88
89 for filename in input_filenames:
90 print("patching file %s" % filename)
91
92 f = ROOT.TFile.Open(filename, "update")
93 tree = f.Get(options.tree)
94 if not tree:
95 raise IOError("cannot find %s" % options.tree)
96
97
98 branches = [prefix + 'cl_eta'] + [prefix + 'rawcl_Es%d' % i for i in range(4)]
99 if not all(tree.GetBranch(i) for i in branches):
100 logging.info("skipping %s*", prefix)
101 continue
102
103 branches_to_copy = options.branches_to_copy or []
104 logging.info("copying these branches: %s", ",".join(branches_to_copy) if branches_to_copy else "None")
105
106 new_branch_names = [prefix + 'rawcl_Es%d' % i for i in range(4)]
107 if set(new_branch_names).intersection(branches_to_copy):
108 logging.warning("raw_clE* variables in the copy list -> going to rename. PROBABILY YOU DON'T WANT TO DO IT!")
109 new_branch_names = [prefix + 'rawcl_Es%d_new' % i for i in range(4)]
110
111 tree.SetBranchStatus("*", 0)
112 for branch in branches_to_copy:
113 tree.SetBranchStatus(branch, 1)
114 newtree = tree.CloneTree(0)
115 newtree.SetName("layerRecalibratedTree")
116 newtree.SetTitle("layerRecalibratedTree")
117
118 # Disable all branches but the needed ones
119 tree.SetBranchStatus('*', 0)
120 for br in set(branches + branches_to_copy):
121 logging.info("activating branch %s", br)
122 tree.SetBranchStatus(br, 1)
123
124 # Create new branch, the same type as the old one
125 isVector = 'vector' in tree.GetLeaf(prefix + 'rawcl_Es0').GetTypeName()
126 new_storages = []
127 if isVector:
128 for new_branch_name in new_branch_names:
129 new_storage = ROOT.vector(float)()
130 new_storages.append(new_storage)
131 newtree.Branch(new_branch_name, new_storage)
132 else:
133 for new_branch_name in new_branch_names:
134 new_storage = array('f', [0.])
135 new_storages.append(new_storage)
136 newtree.Branch(new_branch_name, new_storage, new_branch_name + '/F')
137
138 for i, new_value in enumerate(LayerRecalibratedGenerator(tree, branches)):
139 if i % 1000 == 0:
140 print(i)
141 if options.nevents and i >= options.nevents:
142 break
143
144 if isVector:
145 for s, d in zip(new_storages, new_value):
146 s.clear()
147 map(s.push_back, d)
148 else:
149 for s, v in zip(new_storages, new_value):
150 s[0] = v
151 newtree.Fill()
152 print("loop ended after %d events" % i)
153
154 logging.debug("all events done")
155 tree.SetBranchStatus('*', 1)
156 logging.debug("adding friend")
157 tree.AddFriend(newtree)
158 logging.info("updating old tree")
159 tree.GetCurrentFile().Write("", ROOT.TObject.kOverwrite)
160 logging.info("writing new tree")
161 if f.Get("layerRecalibratedTree"):
162 newtree.GetCurrentFile().Write("", ROOT.TObject.kOverwrite)
163 else:
164 newtree.GetCurrentFile().Write()
165 logging.debug("closing file")
166
167 # this is because ROOT is stupid
168 tree.SetDirectory(0)
169 newtree.SetDirectory(0)
170
171 f.Close()
172 logging.debug("closed")
173
174 logging.info("creating check plots")
175 chain = ROOT.TChain(options.tree)
176 for filename in input_filenames:
177 chain.Add(filename)
178
179 for old_branch_name, new_branch_name in zip([prefix + 'rawcl_Es%d' % i for i in range(4)], new_branch_names):
180 canvas = ROOT.TCanvas()
181 chain.Draw("layerRecalibratedTree.%s/%s:%scl_eta>>(100, -2.5, 2.5, 100, 0.9, 1.1)" % (new_branch_name, old_branch_name, prefix),
182 "abs(%scl_eta) < 2.5 && %s != 0" % (prefix, old_branch_name), "", options.nevents or 1000000000)
183 canvas.SaveAs("canvas_check_%s.png" % new_branch_name)
void print(char *figname, TCanvas *c1)
STL class.
STL class.
STL class.
std::vector< std::string > intersection(std::vector< std::string > &v1, std::vector< std::string > &v2)
LayerRecalibratedGenerator(input_tree, branches)
foo_callback(option, opt, value, parser)