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 (" \n Done for {} events {}\n " , total_evt_seen, outfile);
197+ }
0 commit comments