Skip to content

Commit 05ea153

Browse files
committed
CSV reco DIS convert + docs
1 parent 69dba8f commit 05ea153

File tree

6 files changed

+301
-44
lines changed

6 files changed

+301
-44
lines changed

csv_convert/CMakeLists.txt

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,12 @@ find_package(nlohmann_json)
2222
# -----------------------------------------------------------------------------#
2323
# Build executable #
2424
# -----------------------------------------------------------------------------#
25-
add_executable(csv_mcdis csv_mcdis.cxx)
2625

27-
target_link_libraries(csv_mcdis
26+
27+
28+
add_executable(csv_mcpart_lambda csv_mcpart_lambda.cxx)
29+
30+
target_link_libraries(csv_mcpart_lambda
2831
PRIVATE
2932
ROOT::Core ROOT::RIO ROOT::Tree ROOT::Hist ROOT::Gpad
3033
podio::podio podio::podioRootIO podio::podioDict
@@ -33,12 +36,22 @@ target_link_libraries(csv_mcdis
3336
fmt::fmt)
3437

3538

36-
add_executable(csv_mcpart_lambda csv_mcpart_lambda.cxx)
39+
add_executable(csv_mc_dis csv_mc_dis.cxx)
3740

38-
target_link_libraries(csv_mcpart_lambda
41+
target_link_libraries(csv_mc_dis
3942
PRIVATE
4043
ROOT::Core ROOT::RIO ROOT::Tree ROOT::Hist ROOT::Gpad
4144
podio::podio podio::podioRootIO podio::podioDict
4245
EDM4HEP::edm4hep EDM4HEP::edm4hepDict
4346
EDM4EIC::edm4eic EDM4EIC::edm4eicDict
4447
fmt::fmt)
48+
49+
add_executable(csv_reco_dis csv_reco_dis.cxx)
50+
51+
target_link_libraries(csv_reco_dis
52+
PRIVATE
53+
ROOT::Core ROOT::RIO ROOT::Tree ROOT::Hist ROOT::Gpad
54+
podio::podio podio::podioRootIO podio::podioDict
55+
EDM4HEP::edm4hep EDM4HEP::edm4hepDict
56+
EDM4EIC::edm4eic EDM4EIC::edm4eicDict
57+
fmt::fmt)

csv_convert/convert_campaign.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,9 @@
2626

2727
indir = Path(sys.argv[1])
2828
macros = [
29+
"csv_mc_dis.cxx"
30+
"csv_reco_dis.cxx"
2931
"csv_mcpart_lambda.cxx",
30-
"csv_mcdis.cxx"
3132
]
3233

3334

@@ -41,12 +42,12 @@
4142

4243
# ------------------------------------------------------------------ run loop
4344
for idx, f in enumerate(root_files, start=1):
44-
print(f"[{idx}/{file_count}] processing...")
45+
print(f"[{idx}/{file_count}] ============================================")
4546
for macro in macros:
4647
macro_base_name = macro.replace("csv_", "").replace(".cxx", "")
4748
out_file = f.with_name(f.name.replace(".edm4eic.root", f".{macro_base_name}.csv"))
4849

49-
print(f" {macro} {f.name}{out_file.name}")
50+
print(f"|{macro}| {f.name}{out_file.name}")
5051
cmd = [
5152
"root", "-x", "-l", "-b", "-q",
5253
f'{macro}("{f}","{out_file}")'
@@ -56,5 +57,5 @@
5657
except subprocess.CalledProcessError as e:
5758
print(f"[ERROR] Failed on {f.name}: exit code {e.returncode}")
5859
sys.exit(1)
59-
60+
print(f"---> Finished converting: {f.name}")
6061
print(f"\n[OK] Successfully processed {file_count} files. Output CSVs are alongside the ROOT files.")
Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -170,14 +170,14 @@ void process_event(const podio::Frame& event, int event_number) {
170170

171171
// ---------------------------------------------------------------------------
172172
// ROOT-macro entry point.
173-
// Call it from the prompt: root -x -l -b -q 'csv_mcdis.cxx("file.root", "output.csv", 100)'
173+
// Call it from the prompt: root -x -l -b -q 'csv_mc_dis.cxx("file.root", "output.csv", 100)'
174174
// ---------------------------------------------------------------------------
175-
void csv_mcdis(const char* infile, const char* outfile = "dis_parameters.csv", int events = -1) {
175+
void csv_mc_dis(const char* infile, const char* outfile = "dis_parameters.csv", int events = -1) {
176176

177-
fmt::print("'csv_mcdis' entry point is used\n");
178-
fmt::print(" infile: {}\n", infile);
179-
fmt::print(" outfile: {}\n", outfile);
180-
fmt::print(" events: {}\n", events);
177+
fmt::print("'csv_mc_dis' entry point is used. Arguments:\n");
178+
fmt::print(" infile: {}\n", infile);
179+
fmt::print(" outfile: {}\n", outfile);
180+
fmt::print(" events: {} {}\n", events, (events == -1 ? "(process all)" : ""));
181181

182182
csv_file.open(outfile);
183183
if (!csv_file) {

csv_convert/csv_mcpart_lambda.cxx

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@ std::string make_particle_header(const std::string&prefix) {
9494
//------------------------------------------------------------------------------
9595
// event processing
9696
//------------------------------------------------------------------------------
97-
void process_event(const podio::Frame&evt, int evt_id) {
98-
const auto&parts = evt.get<MCParticleCollection>("MCParticles");
97+
void process_event(const podio::Frame&event, int evt_id) {
98+
const auto&parts = event.get<MCParticleCollection>("MCParticles");
9999

100100
for (const auto&lam: parts) {
101101
if (lam.getPDG() != 3122) continue; // not Λ⁰
@@ -146,7 +146,7 @@ void process_event(const podio::Frame&evt, int evt_id) {
146146
// output
147147
// -----------------------------------------------------------------
148148
if (!header_written) {
149-
csv << "evt,"
149+
csv << "event,"
150150
<< make_particle_header("lam") << ','
151151
<< make_particle_header("prot") << ','
152152
<< make_particle_header("pimin") << ','
@@ -242,10 +242,10 @@ int main(int argc, char* argv[]) {
242242
// ---------------------------------------------------------------------------
243243
void csv_mcpart_lambda(const char* infile, const char* outfile, int events = -1)
244244
{
245-
fmt::print("'csv_mcpart_lambda' entry point is used\n");
246-
fmt::print(" infile: {}\n", infile);
247-
fmt::print(" outfile: {}\n", outfile);
248-
fmt::print(" events: {}\n", events);
245+
fmt::print("'csv_mcpart_lambda' entry point is used. Arguments:\n");
246+
fmt::print(" infile: {}\n", infile);
247+
fmt::print(" outfile: {}\n", outfile);
248+
fmt::print(" events: {} {}\n", events, (events == -1 ? "(process all)" : ""));
249249

250250
csv.open(outfile);
251251
if (!csv) {

csv_convert/csv_reco_dis.cxx

Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
#ifdef __CLING__
2+
R__LOAD_LIBRARY(podioDict)
3+
R__LOAD_LIBRARY(podioRootIO)
4+
R__LOAD_LIBRARY(libedm4hepDict)
5+
R__LOAD_LIBRARY(libedm4eicDict)
6+
#endif
7+
8+
// lambdas_to_csv.cxx
9+
#include "podio/Frame.h"
10+
#include "podio/ROOTReader.h"
11+
#include <edm4hep/MCParticleCollection.h>
12+
#include <edm4eic/InclusiveKinematicsCollection.h>
13+
14+
#include <fmt/core.h>
15+
#include <fmt/ostream.h>
16+
17+
#include <TFile.h>
18+
19+
#include <fstream>
20+
#include <string>
21+
#include <vector>
22+
#include <cstdlib>
23+
24+
using namespace edm4hep;
25+
26+
//------------------------------------------------------------------------------
27+
// globals & helpers
28+
//------------------------------------------------------------------------------
29+
int events_limit = -1; // -n <N>
30+
long total_evt_seen = 0;
31+
std::ofstream csv;
32+
bool header_written = false;
33+
34+
//------------------------------------------------------------------------------
35+
// event processing
36+
//------------------------------------------------------------------------------
37+
void process_event(const podio::Frame& event, int evt_id) {
38+
using IKColl = edm4eic::InclusiveKinematicsCollection;
39+
40+
/*---------------------------------------------------------------------------
41+
Grab the collections
42+
---------------------------------------------------------------------------*/
43+
const auto& kinDA = event.get<IKColl>("InclusiveKinematicsDA");
44+
const auto& kinESigma = event.get<IKColl>("InclusiveKinematicsESigma");
45+
const auto& kinElectron= event.get<IKColl>("InclusiveKinematicsElectron");
46+
const auto& kinJB = event.get<IKColl>("InclusiveKinematicsJB");
47+
const auto& kinML = event.get<IKColl>("InclusiveKinematicsML");
48+
const auto& kinSigma = event.get<IKColl>("InclusiveKinematicsSigma");
49+
50+
/*---------------------------------------------------------------------------
51+
Dictionary: { name , &collection }
52+
---------------------------------------------------------------------------*/
53+
const std::vector<std::pair<std::string_view,const IKColl*>> kinDict = {
54+
{ "da" , &kinDA },
55+
{ "esigma" , &kinESigma },
56+
{ "electron", &kinElectron },
57+
{ "jb" , &kinJB },
58+
{ "ml" , &kinML },
59+
{ "sigma" , &kinSigma },
60+
};
61+
62+
// Write csv header?
63+
if (!header_written) {
64+
csv << "evt";
65+
for (const auto&name: kinDict | std::views::keys) {
66+
67+
csv << "," << fmt::format("{}_x", name);
68+
csv << "," << fmt::format("{}_q2", name);
69+
csv << "," << fmt::format("{}_y", name);
70+
csv << "," << fmt::format("{}_nu", name);
71+
csv << "," << fmt::format("{}_w", name);
72+
}
73+
// For Meson-structure analysis we taking true variables from different place, not "InclusiveKinematics*" tables, so put these column names manually
74+
csv << "," << "mc_x";
75+
csv << "," << "mc_q2";
76+
csv << "," << "mc_y";
77+
csv << "," << "mc_nu";
78+
csv << "," << "mc_w";
79+
csv << '\n';
80+
header_written = true;
81+
}
82+
83+
csv << evt_id;
84+
for (const auto& [name, coll] : kinDict)
85+
{
86+
if (coll->size() != 1) {
87+
csv << ",,,,,"; // Empty CSV value (null-s)
88+
continue;
89+
}
90+
91+
csv << "," << coll->at(0).getX();
92+
csv << "," << coll->at(0).getQ2();
93+
csv << "," << coll->at(0).getY();
94+
csv << "," << coll->at(0).getNu();
95+
csv << "," << coll->at(0).getW();
96+
}
97+
98+
// Here we add truth information saved in parameters
99+
csv << "," << event.getParameter<std::string>("dis_xbj").value_or("");
100+
csv << "," << event.getParameter<std::string>("dis_q2").value_or("");
101+
csv << "," << event.getParameter<std::string>("dis_y_d").value_or("");
102+
csv << "," << event.getParameter<std::string>("dis_nu").value_or("");
103+
csv << "," << event.getParameter<std::string>("dis_w").value_or("");
104+
105+
csv << '\n';
106+
}
107+
108+
//------------------------------------------------------------------------------
109+
// file loop
110+
//------------------------------------------------------------------------------
111+
void process_file(const std::string&fname) {
112+
podio::ROOTReader rdr;
113+
try {
114+
rdr.openFile(fname);
115+
}
116+
catch (const std::runtime_error&e) {
117+
fmt::print(stderr, "Error opening file {}: {}\n", fname, e.what());
118+
return;
119+
}
120+
121+
const auto nEv = rdr.getEntries(podio::Category::Event);
122+
123+
for (unsigned ie = 0; ie < nEv; ++ie) {
124+
if (events_limit > 0 && total_evt_seen >= events_limit) return;
125+
126+
podio::Frame evt(rdr.readNextEntry(podio::Category::Event));
127+
process_event(evt, total_evt_seen);
128+
++total_evt_seen;
129+
}
130+
}
131+
132+
//------------------------------------------------------------------------------
133+
// main
134+
//------------------------------------------------------------------------------
135+
int main(int argc, char* argv[]) {
136+
std::vector<std::string> infiles;
137+
std::string out_name = "mcpart_lambdas.csv";
138+
139+
for (int i = 1; i < argc; ++i) {
140+
std::string a = argv[i];
141+
if (a == "-n" && i + 1 < argc) events_limit = std::atoi(argv[++i]);
142+
else if (a == "-o" && i + 1 < argc) out_name = argv[++i];
143+
else if (a == "-h" || a == "--help") {
144+
fmt::print("usage: {} [-n N] [-o file] input1.root [...]\n", argv[0]);
145+
return 0;
146+
}
147+
else if (!a.empty() && a[0] != '-') infiles.emplace_back(a);
148+
else {
149+
fmt::print(stderr, "unknown option {}\n", a);
150+
return 1;
151+
}
152+
}
153+
if (infiles.empty()) {
154+
fmt::print(stderr, "error: no input files\n");
155+
return 1;
156+
}
157+
158+
csv.open(out_name);
159+
if (!csv) {
160+
fmt::print(stderr, "error: cannot open output file {}\n", out_name);
161+
return 1;
162+
}
163+
164+
for (auto&f: infiles) {
165+
process_file(f);
166+
if (events_limit > 0 && total_evt_seen >= events_limit) break;
167+
}
168+
169+
csv.close();
170+
fmt::print("Wrote data for {} events to {}\n", total_evt_seen, out_name);
171+
return 0;
172+
}
173+
174+
175+
// ---------------------------------------------------------------------------
176+
// ROOT-macro entry point.
177+
// Call it from the prompt: root -x -l -b -q 'csv_reco_dis.cxx("file.root", "output.csv", 100)'
178+
// ---------------------------------------------------------------------------
179+
void csv_reco_dis(const char* infile, const char* outfile, int events = -1)
180+
{
181+
fmt::print("'csv_reco_dis' entry point is used. Arguments:\n");
182+
fmt::print(" infile: {}\n", infile);
183+
fmt::print(" outfile: {}\n", outfile);
184+
fmt::print(" events: {} {}\n", events, (events == -1 ? "(process all)" : ""));
185+
186+
csv.open(outfile);
187+
if (!csv) {
188+
fmt::print(stderr, "error: cannot open output file {}\n", outfile);
189+
exit(1);
190+
}
191+
192+
events_limit = events; // reuse the global controls
193+
process_file(infile);
194+
195+
csv.close();
196+
fmt::print("\nDone for {} events {}\n", total_evt_seen, outfile);
197+
}

0 commit comments

Comments
 (0)