ATLAS Offline Software
Loading...
Searching...
No Matches
skim.cxx
Go to the documentation of this file.
1
9
10// cppcheck-suppress-file stlIfStrFind; cannot use C++20 starts_with in this standalone code
11
12#include <stdlib.h>
13
14#include <iostream>
15#include <vector>
16#include <set>
17#include <string>
18#include <regex>
19#include <algorithm>
20#include <cstdio>
21
22#include "simpletimer.h"
23
24#include "TChain.h"
25#include "TFile.h"
26#include "TTree.h"
27#include "TH1D.h"
28
30
31#include "utils.h"
32
33template<class T>
34void remove_duplicates(std::vector<T>& vec) {
35 std::sort(vec.begin(), vec.end());
36 vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
37}
38
39std::string time_str() {
40 time_t t;
41 time(&t);
42 std::string s(ctime(&t));
43 return s.substr(0,s.find('\n'));
44}
45
46int usage(int e=0) {
47 std::cerr << "usage: skim <filename> [OPTIONS]" << std::endl;
48 std::cerr << "\nremoves chains from the ntple\n";
49 std::cerr << "\nOptions:\n";
50 std::cerr << "\t-d | --delete\tremoves specified chains\n";
51 std::cerr << "\t-o | --output\toutput filename (default tree.root)\n";
52 std::cerr << "\t-r | --require\trequire that this chain has tracks\n";
53 std::cerr << "\t-f | --force\tforce processing even if no chains specified\n";
54 std::cerr << "\t --pt value\tremove offline tracks pt < value\n";
55 std::cerr << "\t --roi \tfilter offline tracks by roi phi\n";
56 std::cerr << "\nIf option -d is not given, the specified chains are retained and all others are removed" << std::endl;
57 std::cerr << "\nIf no chains are specifed simply all events with no L2 or EF chains are excluded" << std::endl;
58 return e;
59}
60
61template<class T>
62std::ostream& operator<<( std::ostream& os, const std::set<T>& s ) {
63 typename std::set<T>::const_iterator sitr = s.begin();
64 os << "[ ";
65 while ( sitr!=s.end() ) os << (*sitr++) << "\t";
66 os << " ]";
67 return os;
68}
69
70
71template<class T>
72std::ostream& operator<<( std::ostream& s, const std::vector<T>& v ) {
73 typename std::vector<T>::const_iterator sitr = v.begin();
74 s << "[ ";
75 while ( sitr!=v.end() ) s << (*sitr++) << "\t";
76 s << " ]";
77 return s;
78}
79
80
81
82void copyReleaseInfo( TFile* finput, TFile* foutdir ) {
83
84 if ( finput && foutdir ) {
85
86 TTree* tree = (TTree*)finput->Get("dataTree");
87 TTree* clone = tree->CloneTree();
88
89 foutdir->cd();
90 clone->Write("", TObject::kOverwrite);
91
92 delete clone;
93
94 }
95
96}
97
98
99
100//coverity[root_function]
101int main(int argc, char** argv) {
102
103 if ( argc<1 ) return usage(-1);
104
105 std::set<std::string> require_chains;
106 std::vector<std::string> rchains;
107
108 bool require = false;
109 bool deleting = false;
110
111 std::string outfile = "tree.root";
112
113 std::string infile="";
114
115 bool force = false;
116
117 double ptmin = 0;
118
119 bool roi_filter = false;
120
121 bool verbose = false;
122
123 for ( int i=1 ; i<argc ; i++ ) {
124
125 std::string arg(argv[i]);
126
128
129 if ( arg.find('-')!=0 ) {
130 if ( !deleting && infile!="" ) {
131 require = true;
132 require_chains.insert(argv[i]);
133 rchains.push_back(argv[i]);
134 continue;
135 }
136 else {
137 if ( infile=="" ) infile = std::move(arg);
138 else {
139 std::cerr << "more than one file specified: " << arg << std::endl;
140 return usage(-2);
141 }
142 }
143 }
144 else {
145 if ( arg=="-h" || arg=="--help" ) return usage(0);
146 else if ( arg=="-o" || arg=="--output" ) {
147 if ( (i+1)<argc ) outfile = argv[++i];
148 else return usage(-1);
149 }
150 else if ( arg=="-r" || arg=="--require" ) {
151 if ( deleting ) {
152 std::cerr << "cannot require and delete chains" << std::endl;
153 return usage(-4);
154 }
155 require = true;
156 }
157 else if ( arg=="-d" || arg=="--delete" ) {
158 if ( require ) {
159 std::cerr << "cannot require and delete chains" << std::endl;
160 return usage(-3);
161 }
162 deleting = true;
163 }
164 else if ( arg=="--pt" ) {
165 if ( (i+1)<argc ) ptmin = std::atof(argv[++i])*1000;
166 else return usage(-1);
167 force = true;
168 }
169 else if ( arg=="-v" || arg=="--verbose" ) verbose = true;
170 else if ( arg=="-f" || arg=="--force" ) force = true;
171 else if ( arg=="--roi" ) { force=true; roi_filter = true; }
172 else if ( infile=="" ) infile = std::move(arg);
173 else {
174 std::cerr << "more than one file specified: " << arg << std::endl;
175 return usage(-2);
176 }
177 }
178 }
179
180 std::cout << "required chains " << require_chains << std::endl;
181
182 if ( require_chains.size()>0 ) require = true;
183
184 if ( !force && require_chains.size()==0 ) {
185 std::cout << "no chains requested - not doing anything" << std::endl;
186 return 0;
187 }
188
189 std::cout << "chains: " << rchains << std::endl;
190
191
192 std::cout << "skim::start " << time_str() << std::endl;
193
194
195 if ( require ) std::cout << "require chains " << require_chains << std::endl;
196 if ( deleting ) std::cout << "delete chains " << require_chains << std::endl;
197
198
199 if ( infile=="" ) {
200 std::cerr << "no files specified" << std::endl;
201 return usage(-1);
202 }
203
204 std::cout << "reading from file: " << infile << std::endl;
205 std::cout << "writing to file: " << outfile << std::endl;
206
207
209 TIDA::Event* track_ev = new TIDA::Event();
210 TIDA::Event* h = track_ev;
211
212 std::cout << "opening outfile: " << outfile << std::endl;
213
214 TFile fout( outfile.c_str(), "recreate");
215
216 fout.cd();
217
219
220 TTree *tree = new TTree("tree","tree");
221
222 tree->Branch("TIDA::Event", "TIDA::Event", &h, 6400, 1);
223
224 h->clear();
225
227
228 int ev_in = 0;
229 int ev_out = 0;
230
231 {
232
234 TFile finput( infile.c_str() );
235 if (!finput.IsOpen()) {
236 std::cerr << "Error: could not open output file" << std::endl;
237 exit(-1);
238 }
239
240
241 copyReleaseInfo( &finput, &fout );
242
243 finput.cd();
244
246
247 // TChain* data = new TChain("tree");
248
249 TTree* data = (TTree*)finput.Get("tree");
250
251 TIDA::Event* track_iev = new TIDA::Event();
252
253 data->SetBranchAddress("TIDA::Event",&track_iev);
254 // data->AddFile( argv[i] );
255
256
257 unsigned entries = data->GetEntries();
258
259 std::cout << "input has " << entries << " events" << std::endl;
260
261 std::string cck = "|/-\\";
262
263 int ii=0;
264
265 struct timeval tm = simpletimer_start();
266
267 std::cout << "processing ..." << std::endl;
268
269 for (unsigned int i=0; i<data->GetEntries() ; i++ ) {
270
271 if ( verbose ) std::cout << "event " << i;
272
273 if ( i%100==0 ) {
274
275 double frac = i*1.0/entries;
276
277 double t = simpletimer_stop(tm);
278
279 double est = 0;
280
281 if ( frac > 0 ) est = t/frac - t;
282
283 double eventsps = 1000*i/t;
284 // (1000*(i+1)/entries)) is implicitly unsigned division; make this clear with a cast
285 std::printf( "\r%c %6.2lf %% time: %6.2lf s remaining %6.2lf s (%u at %5.2lf ps) ",
286 cck[ii%4], (static_cast<unsigned>((1000*(i+1)/entries))*0.1), t*0.001, est*0.001, i, eventsps );
287
288 std::fflush(stdout);
289
290 ii++;
291 }
292
293
294
295 track_iev->clear();
296 track_ev->clear();
297
298 data->GetEntry(i);
299
300 ev_in++;
301
302 *track_ev = *track_iev;
303
304 // std::cout << *track_ev << std::endl;
305
306 // std::cout << "track_ev names " << track_ev->chainnames() << std::endl;
307 // std::cout << "track_iev names " << track_iev->chainnames() << std::endl;
308
309 if ( verbose ) std::cout << "----------------------------------------\n\tN chains " << track_ev->size() << " -> ";
310
311 std::vector<TIDA::Chain>& chains = track_ev->chains();
312
313
315
316 bool skip = true;
317
318 std::vector<TIDA::Chain>::iterator citr = chains.begin();
319 for ( ; citr!=chains.end() ; ++citr ) {
320
321 if ( citr->name().find("HLT")==std::string::npos ) continue;
322
323 if ( require ) {
324 for ( unsigned j=rchains.size() ; j-- ; ) {
325 if ( rchains[j].find("HLT")==std::string::npos ) continue;
326 if ( citr->name().find(rchains[j])!=std::string::npos ) {
327 skip = false;
328 if ( verbose ) std::cout << "keepin' " << citr->name() << " " << rchains[j] << std::endl;
329 }
330
331 }
332 }
333
334 }
335
336 if ( skip ) continue;
337
339
340 {
341
343
344 std::vector<std::string> chainnames = track_ev->chainnames();
345
346 for ( size_t ic=0 ; ic<chainnames.size() ; ic++ ) {
347
348
349 bool matched = false;
350 for ( std::set<std::string>::iterator it=require_chains.begin() ; it!=require_chains.end() ; ++it ) {
351
352 matched |= std::regex_match( chainnames[ic], std::regex(*it+".*") );
353
354 if ( verbose && matched ) std::cout << "chain: " << chainnames[ic] << "\t :: reg " << *it << "\tmatched: " << matched << std::endl;
355
356 }
357
358 if ( ( require && !matched ) ) track_ev->erase( chainnames[ic] );
359 }
360
361 if ( verbose ) std::cout << track_ev->size() << std::endl;
362
363
364 if ( roi_filter || ptmin>0 ) {
365
366 TIDA::Chain* offline = 0;
367
368 std::vector<std::string> chainnames = track_ev->chainnames();
369
371
372 for ( size_t ic=chainnames.size() ; ic-- ; ) {
373 if ( chainnames[ic] == "Offline" ) {
374 offline = &(track_ev->chains()[ic]);
375 break;
376 }
377 }
378
379 if ( offline ) {
380 // track_ev->addChain( "Offline" );
381
382 std::vector<TIDA::Chain>& chains = track_ev->chains();
383 std::vector<TIDA::Chain>::iterator citr = chains.begin();
384
385 std::vector<std::pair<double,double> > philims;
386
387 for ( ; citr!=chains.end() ; ++citr ) {
388 if ( citr->name().find("HLT_")!=std::string::npos ) {
389 for ( size_t ir=0 ; ir<citr->size() ; ir++ ) {
390 TIDARoiDescriptor& roi = citr->rois()[ir].roi();
391 if ( roi.composite() ) {
392 for ( size_t isub=0 ; isub<roi.size() ; isub++ ) {
393 philims.push_back( std::pair<double,double>( roi[isub]->phiMinus(), roi[isub]->phiPlus() ) );
394 }
395 }
396 else philims.push_back( std::pair<double,double>( roi.phiMinus(), roi.phiPlus() ) );
397 }
398 }
399 }
400
401 remove_duplicates( philims );
402
403 for ( size_t iroi=0 ; iroi<offline->size() ; iroi++ ) {
404
405 std::vector<TIDA::Track>& tracks = offline->rois()[iroi].tracks();
406
407 for ( std::vector<TIDA::Track>::iterator it=tracks.begin() ; it<tracks.end() ; ) {
408 bool inc = true;
409 if ( ptmin>0 ) {
410 if ( std::fabs(it->pT())<ptmin ) { inc=false; tracks.erase( it ); }
411 }
412 if ( inc && roi_filter ) {
413 bool remove_track = true;
414 for ( size_t isub=0 ; isub<philims.size() ; isub++ ) {
415
416 if ( philims[isub].first < philims[isub].second ) {
417 if ( it->phi()>=philims[isub].first && it->phi()<=philims[isub].second ) {
418 remove_track = false;
419 break;
420 }
421 }
422 else {
423 if ( it->phi()>=philims[isub].first || it->phi()<=philims[isub].second ) {
424 remove_track = false;
425 break;
426 }
427 }
428 }
429 if ( remove_track ) { inc=false; tracks.erase( it ); }
430 }
431 if ( inc ) ++it;
432 }
433
434 }
435
436 }
437
438
439 }
440
441
442 if ( verbose ) std::cout << "writing event:\n" << *track_ev << std::endl;
443
444 tree->Fill();
445 ev_out++;
446
447
448#if 0
449 for (unsigned int ic=0 ; ic<chains.size() ; ic++ ) {
450 if ( chains[ic].name()=="Offline" ) {
451 const std::vector<TIDA::Track>& tracks = chains[ic].rois()[0].tracks();
452
453 for ( unsigned it=0 ; it<tracks.size() ; it++ ) {
454 h->Fill( tracks[it].pT()*0.001 );
455 itracks++;
456
457 }
458 break;
459 }
460 }
461#endif
462
463 }
464
465 }
466
467
468 double t = simpletimer_stop(tm);
469
470 std::printf( "\r%c %6.2lf %% time: %6.2lf s\n",
471 cck[ii%4], 100., t*0.001 );
472
473
474 finput.Close();
475
476 }
477
478 std::cout << "skim::done " << time_str() << std::endl;
479
480 std::cout << "skim::events in: " << ev_in << std::endl;
481 std::cout << "skim::events out: " << ev_out << std::endl;
482
483 fout.Write();
484 fout.Close();
485
486 return 0;
487}
488
489
490
std::vector< size_t > vec
struct timeval simpletimer_start(void)
double simpletimer_stop(const struct timeval &start_time)
char data[hepevt_bytes_allocation_ATLAS]
Definition HepEvt.cxx:11
Basic event class to contain a vector of chains for trigger analysis.
these functions have a precision of about 0.001 ms
Header file for AthHistogramAlgorithm.
Describes the Region of Interest geometry It has basically 8 parameters.
double phiPlus() const
double phiMinus() const
bool composite() const
composite RoI methods
void erase(const std::string &name)
Definition TIDAEvent.cxx:36
const std::vector< TIDA::Chain > & chains() const
Definition TIDAEvent.h:76
void clear()
clear the event
Definition TIDAEvent.h:86
unsigned size() const
vertex multiplicity ?
Definition TIDAEvent.h:64
std::vector< std::string > chainnames() const
Definition TIDAEvent.cxx:28
int ir
counter of the current depth
Definition fastadd.cxx:49
StatusCode usage()
std::string find(const std::string &s)
return a remapped string
Definition hcg.cxx:140
bool verbose
Definition hcg.cxx:75
int main()
Definition hello.cxx:18
double entries
Definition listroot.cxx:49
static TFile * fout
Definition listroot.cxx:40
DataModel_detail::iterator< DVL > unique(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of unique for DataVector/List.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
void copyReleaseInfo(TFile *finput, TFile *foutdir)
copy the TTree of release info from one directory to another
Definition skim.cxx:82
std::ostream & operator<<(std::ostream &os, const std::set< T > &s)
Definition skim.cxx:62
void remove_duplicates(std::vector< T > &vec)
Definition skim.cxx:34
std::string time_str()
Definition skim.cxx:39
TChain * tree