2 =================================================
3 * @file clitkMergeRootFiles.cxx
4 * @author David Sarrut <david.sarrut@creatis.insa-lyon.fr>
5 * @author Brent Huisman <brent.huisman@insa-lyon.fr>
10 =================================================*/
12 #include "clitkMergeRootFiles_ggo.h"
13 #include "clitkCommon.h"
14 #include "GateMergeManager.hh"
17 #include <TPluginManager.h>
20 #include <TFileMerger.h>
26 #include <TApplication.h>
36 bool sort_pet_input_file(const PetInputFile &a, const PetInputFile &b) {
37 return a.mean_time < b.mean_time;
40 typedef std::vector<PetInputFile> PetInputFiles;
42 //-----------------------------------------------------------------------------
43 int main(int argc, char *argv[]) {
44 //this fixes a bug in TFileMerger. See http://root.cern.ch/phpBB3/viewtopic.php?t=18016.
45 TApplication app("app", 0, 0);
47 gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo", "*",
48 "TStreamerInfo", "RIO", "TStreamerInfo()");
51 GGO(clitkMergeRootFiles, args_info);
54 if (args_info.input_given < 2) {
55 FATAL("Error, please provide at least two inputs files");
58 // Set the tree maximum size to 1TB instead of 100GB
59 TTree::SetMaxTreeSize( 1000000000000LL );
61 /* The following block does some bookkeeping necesary for files originating from a pet simulation.
62 Seems fixing some timing info, for coincidences between files perhaps.
63 It seems the files are later on reopened and merged, if the conditions were met.
64 It's not required for merging other .root files.
65 GateMergeManager reportedly exists specifically for the purpose of merging pet simulations. */
68 bool all_pet_output = true;
69 PetInputFiles pet_input_files;
70 for (uint i = 0; i < args_info.input_given; i++) {
71 const char *filename = args_info.input_arg[i];
72 PetInputFile input_file;
73 input_file.filename = filename;
74 TFile *handle = TFile::Open(filename, "READ");
76 TTree *hits = dynamic_cast<TTree *>(handle->Get("Hits"));
77 TTree *singles = dynamic_cast<TTree *>(handle->Get("Singles"));
78 const bool is_pet_output = (hits != NULL) && (singles != NULL);
79 cout << "testing " << filename << " is_pet_output " << is_pet_output;
81 //TTree *histos = dynamic_cast<TH1F *>(handle->Get("histo;1"));
82 //const bool is_hist_output = (histos != NULL);
87 double time_accum = 0;
88 singles->SetBranchAddress("time", &time);
89 size_t total = singles->GetEntries();
90 for (size_t kk = 0; kk < total; kk++) {
91 singles->GetEntry(kk);
95 input_file.mean_time = time_accum / total;
96 pet_input_files.push_back(input_file);
97 cout << " mean_time " << input_file.mean_time;
104 //bitwise on booleans?
105 all_pet_output &= is_pet_output;
107 cout << "all_pet_output " << all_pet_output << endl;
109 if (all_pet_output) {
110 GateMergeManager manager(args_info.fastmerge_given, args_info.verbose_arg, true, 0, "");
112 cout << "sorting input file using singles time" << endl;
113 std::sort(pet_input_files.begin(), pet_input_files.end(), sort_pet_input_file);
115 Strings input_filenames;
116 for (PetInputFiles::const_iterator iter = pet_input_files.begin(); iter != pet_input_files.end(); iter++)
117 input_filenames.push_back(iter->filename);
119 manager.StartMergingFromFilenames(input_filenames, args_info.output_arg);
120 //if the file was PET, then we're done.
125 //if the file was not PET, but a generic Rootfile, use TFileMerger.
128 TFileMerger *merger = new TFileMerger;
129 for (uint i = 0; i < args_info.input_given; i++) merger->AddFile(args_info.input_arg[i]);
130 merger->OutputFile(args_info.output_arg);
131 bool whatbool = merger->Merge();
133 cout << "whatbool: " << whatbool << " no more whatbool" << endl;
134 // this is the end my friend
138 //-----------------------------------------------------------------------------