21 #ifndef __USING_ROOT6__
24 #include <TFileMerger.h>
25 #include <TInterpreter.h>
54 std::vector<std::string>
GetTrees(TFile* file);
61 size_t slash = input.find_last_of(
"/");
62 if(slash != std::string::npos) {
63 dir = input.substr(0,slash+1);
64 file = input.substr(slash+1,std::string::npos);
67 getcwd(cwd,
sizeof(cwd));
77 if(input.empty())
return output;
79 output.push_back(prev);
80 for(
size_t i = 1; i < input.size(); i++) {
82 if(!(curr == prev && curr == d)) {
83 output.push_back(curr);
90 int main(
int argc,
char* argv[])
99 #ifdef __USING_ROOT6__
103 TCint* cint =
new TCint(
"pino",
"pino");
104 cint->EnableAutoLoading();
108 std::set<std::string> filenames;
109 for(
int f = args->
optind; f < argc; f++) {
110 std::string fileExtension =
"";
111 std::string inFile = argv[f];
112 size_t dotpos = inFile.find_last_of(
".");
113 if(dotpos != std::string::npos)
114 fileExtension = inFile.substr( dotpos+1 );
115 if(fileExtension ==
"list") {
118 std::cerr<<
"Error: problems reading file list "<<inFile<<std::endl;
121 std::list<std::string>::const_iterator iter = list.begin();
122 while(iter != list.end()) {
123 filenames.insert(*iter);
127 filenames.insert(inFile);
131 std::set<std::string>::const_iterator fiter = filenames.begin();
132 std::map<std::string, std::set<std::string> > dirfiles;
133 while(fiter != filenames.end()) {
134 TFile tfile(fiter->c_str());
135 if(tfile.IsZombie()) {
136 std::cerr<<
"Error: file "<<fiter->c_str()<<
" cannot be opened"<<std::endl;
139 std::string dir,file;
141 dirfiles[dir].insert(file);
147 std::map<std::string, std::set<std::string> >::const_iterator dfiter = dirfiles.begin();
148 while(dfiter != dirfiles.end()) {
149 filenames = dfiter->second;
150 fiter = filenames.begin();
151 std::cout<<
"== Processing directory: "<<dfiter->first<<std::endl;
152 while(fiter != filenames.end()) {
154 std::string filename = dfiter->first + *fiter;
155 std::cout<<*fiter<<
": ";
158 if(args->
v || args->
t) {
159 TFile file(filename.c_str());
160 std::vector<std::string> trees =
GetTrees(&file);
161 std::cout<<
" QTrees { ";
162 for(
size_t t = 0;
t < trees.size();
t++) {
164 std::cout<<trees[
t]<<
"[";
171 TFile file(filename.c_str());
172 std::vector<std::string> trees =
GetTrees(&file);
174 std::cout<<
" TBranches { ";
175 for(
size_t t = 0;
t < trees.size();
t++) {
177 TObjArray* leaflist = qtree->GetListOfBranches();
178 TIter next(leaflist);
179 while(TObject* leaf = next()) {
180 std::cout<<leaf->GetName()<<
" ";
185 std::cout<<
" QTrees { ";
186 for(
size_t t = 0;
t < trees.size();
t++) {
187 std::cout<<trees[
t]<<
" ";
192 Diana::QAliases aliases;
195 std::stringstream str;
197 std::cout<<str.str().c_str()<<std::endl;;
200 TFile file(filename.c_str(),
"UPDATE");
201 std::vector<std::string> trees =
GetTrees(&file);
202 for(
size_t t = 0;
t < trees.size();
t++) {
204 TObjArray* leaflist = qtree->GetListOfBranches();
205 TIter next(leaflist);
206 while(TObject* leaf = next()) {
207 std::string labelstr = leaf->GetName();
208 labelstr = labelstr.substr(0,labelstr.size()-1);
209 Diana::QEventLabel label(labelstr);
210 std::map<std::string, std::string> aliasMap = aliases.Find(label);
211 std::map<std::string, std::string>::const_iterator aiter = aliasMap.begin();
214 while(aiter != aliasMap.end()) {
216 if(aiter->second ==
"") {
219 path = labelstr+std::string(
".")+aiter->second;
222 const char* al = aiter->first.c_str();
223 const char*
ap = path.c_str();
225 qtree->SetAlias(al,
ap);
230 file.Write(
"",TObject::kOverwrite);
232 }
else if(args->
C || args->
S) {
233 Diana::QGlobalDataManager
dm;
234 Diana::GlobalHandle<QFrameWorkConfig> fwcHandle(
"Config");
235 dm.
Get(
"Diana",&fwcHandle,filename);
236 if(fwcHandle.IsValid()) {
239 std::string configfilename = args->
S;
240 configfilename +=
"/";
241 configfilename += *fiter;
242 configfilename +=
".cfg";
245 std::cout<<
"Created \""<<configfilename<<
"\"";
247 std::string directory = args->
C;
248 std::string prefix = *fiter;
252 std::cout<<
"Created config files in dir \""<<directory<<
"\"";
257 std::list<std::string> delObjects;
259 TFile file(filename.c_str(),
"UPDATE");
262 std::vector<std::string> trees =
GetTrees(&file);
263 std::vector<QTree*> qtreesToUpdate;
264 for(std::list<std::string>::const_iterator d = delObjects.begin(); d != delObjects.end(); d++) {
265 TString delObject = d->c_str();
266 bool foundThis =
false;
267 for(
size_t t = 0;
t < trees.size();
t++) {
269 if(qtree->FindBranch(delObject)) {
272 std::string bname = delObject.Data();
273 qtree->SetBranchStatus(bname.c_str(),0);
275 qtree->SetBranchStatus(bname.c_str(),0);
276 if(std::find(qtreesToUpdate.begin(),qtreesToUpdate.end(),qtree) == qtreesToUpdate.end()) {
277 qtreesToUpdate.push_back(qtree);
282 std::cout<<
"TBranch "<<delObject<<
" to be removed not found ";
288 std::string tmpOutput= filename+
".d-rfh";
289 TFile outputFile(tmpOutput.c_str(),
"RECREATE");
290 for(
size_t t = 0;
t < qtreesToUpdate.size();
t++) {
291 QTree* qtree = qtreesToUpdate[
t];
294 TString delObject = qtree->GetName();
295 file.Delete(delObject+
";*");
298 file.Write(
"",TObject::kOverwrite);
303 merg.AddFile(&outputFile);
304 std::string tmpOutput2= filename+
".d-rfh2";
305 merg.OutputFile(tmpOutput2.c_str(),1);
307 rename(tmpOutput2.c_str(),filename.c_str());
308 remove(tmpOutput.c_str());
310 std::cout<<
"Error merging "<<filename<<
": its content is unfortunately now split in: "<<filename<<
" and "<<tmpOutput<<std::endl;
311 remove(tmpOutput2.c_str());
317 for(std::list<std::string>::const_iterator d = delObjects.begin(); d != delObjects.end(); d++) {
318 TString delObject = d->c_str();
319 if(file.Get(delObject)) {
321 file.Delete(delObject+
";*");
324 TList* flist = itree->GetListOfFriends();
325 if(flist) fele = flist->FindObject(delObject.Data());
326 if(fele) itree->GetListOfFriends()->Remove(fele);
329 std::cout<<
"QTree "<<delObject<<
" to be removed not found ";
334 file.Write(
"",TObject::kOverwrite);
337 std::cout<<std::endl;
340 if(args->
c && !args->
b) {
342 TFile file(filename.c_str());
345 std::string tmpOutput= filename+
".d-rfh";
346 merg.OutputFile(tmpOutput.c_str(),1);
348 rename(tmpOutput.c_str(),filename.c_str());
350 std::cout<<
"Error merging "<<filename<<std::endl;
351 remove(tmpOutput.c_str());
355 std::cout<<std::endl;
369 printf(
"usage: %s [ -alcrSCh ] .root and/or .list filenames \n", executable);
371 printf(
"[ --list ] ");
373 printf(
" list QTrees (or their TBranches) in input files\n");
377 printf(
"[ --tag ] ");
379 printf(
" list version tag of QTrees in input files\n");
382 printf(
"[ --version ] ");
384 printf(
" list software revision of QTrees in input files\n");
387 printf(
"[ --branch ] ");
389 printf(
" let -l and -r options act on TBranches instead of QTrees\n");
392 printf(
"[ --compact ] ");
394 printf(
" optimize file size (takes time)\n");
397 printf(
"[ --remove ] object_name1,object_name2,... ");
399 printf(
" remove QTree (or TBranch) with specified name\n");
402 printf(
"[ --configfile ] outputdir ");
404 printf(
" extract config files containing all sequences used to produce each file\n");
407 printf(
"[ --single-configfile ] outputdir ");
409 printf(
" extract a single config file containing all sequences used to produce each file\n");
412 printf(
"[ --aliasfile ] aliasfile ");
414 printf(
" apply aliases from aliasfile\n");
417 printf(
"[ --help ] ");
419 printf(
" Display help information.\n");
421 printf(
"\nexample 1: (lists QTrees in root files and lists files in current dir)\n");
422 printf(
"\n-> diana-rootfilehandler -l *.root *.list\n\n");
424 printf(
"example 2: (get all executed sequences in a single config file per root file)\n");
425 printf(
"\n-> diana-rootfilehandler -S cfg *.root *.list\n\n");
440 if (my_args->
r != NULL) free(my_args->
r);
441 if (my_args->
C != NULL) free(my_args->
C);
442 if (my_args->
S != NULL) free(my_args->
S);
443 if (my_args->
a != NULL) free(my_args->
a);
459 int option_index = 0;
461 struct arg_t *my_args;
464 static struct option long_options[] =
467 {
"version", 0, 0,
'v'},
469 {
"branch", 0, 0,
'b'},
470 {
"compact", 0, 0,
'c'},
471 {
"remove", 1, 0,
'r'},
473 {
"configfile", 1, 0,
'C'},
474 {
"single-configfile", 1, 0,
'S'},
478 my_args = (
struct arg_t *) malloc (
sizeof(
struct arg_t));
491 while ((
c = getopt_long(argc, argv,
"a:lvtbcr:hC:S:", long_options, &option_index)) != EOF)
544 TList* keys = file->GetListOfKeys();
545 std::vector<std::string> trees;
548 while(TKey* key = (TKey*) next()) {
549 std::string className = key->GetClassName();
550 if(className !=
"QTree")
continue;
551 std::string objectName = key->GetName();
552 if(objectName.find(
"qtree") == 0) {
553 trees.push_back(key->GetName());
const std::string & GetVersionTag()
const std::string & GetSoftwareRevision()
error class with error type and description
void Read(const std::string &fileListPath)
QObject storing a set of QSecuenceConfigs.
bool SaveAllSequences(const std::string &outputfilename) const
save all sequences to a single file. Returns true/false in case of success/failure.
bool SaveAllFiles(const std::string &outputdir=".", const std::string &prefix="") const
calls SaveFile on all files present in the QSequenceConfigs and saves each file (preprnding an option...
QError Get(const std::string &owner, GlobalHandle< Q > *gh, const std::string &inSource, bool printError=true) const
Get an object using a global handle.
int main(int argc, char *argv[])
struct arg_t * Cmdline(int, char **)
void ParseDirAndFileName(const std::string &iinput, std::string &dir, std::string &file)
void free_args(struct arg_t *)
std::string RemoveDuplicates(const std::string &input, char d)
std::vector< std::string > GetTrees(TFile *file)
size_t Split(std::string source, std::list< std::string > &splitted, char separtator)
split source into a list of substrings separated by separator