]> Creatis software - clitk.git/blob - tools/clitkMergeRootFiles.cxx
Set the Root Tree maximum size to 1TB instead of 1GB
[clitk.git] / tools / clitkMergeRootFiles.cxx
1 /**
2    =================================================
3    * @file   clitkMergeRootFiles.cxx
4    * @author David Sarrut <david.sarrut@creatis.insa-lyon.fr>
5    * @author Brent Huisman <brent.huisman@insa-lyon.fr>
6    * @date   06 May 2014
7    *
8    * @brief
9    *
10    =================================================*/
11
12 #include "clitkMergeRootFiles_ggo.h"
13 #include "clitkCommon.h"
14 #include "GateMergeManager.hh"
15 #include <string>
16 #include <TROOT.h>
17 #include <TPluginManager.h>
18 #include <TFile.h>
19 #include <TKey.h>
20 #include <TFileMerger.h>
21 #include <TTree.h>
22 #include <TChain.h>
23 #include <TH1.h>
24 #include <TH2.h>
25 #include <iostream>
26 #include <TApplication.h>
27
28 using std::endl;
29 using std::cout;
30
31 struct PetInputFile {
32     string filename;
33     double mean_time;
34 };
35
36 bool sort_pet_input_file(const PetInputFile &a, const PetInputFile &b) {
37     return a.mean_time < b.mean_time;
38 };
39
40 typedef std::vector<PetInputFile> PetInputFiles;
41
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);
46
47     gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo", "*",
48                                           "TStreamerInfo", "RIO", "TStreamerInfo()");
49
50     // init command line
51     GGO(clitkMergeRootFiles, args_info);
52
53     // Check parameters
54     if (args_info.input_given < 2) {
55         FATAL("Error, please provide at least two inputs files");
56     }
57
58     // Set the tree maximum size to 1TB instead of 100GB
59     TTree::SetMaxTreeSize( 1000000000000LL );
60
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. */
66     {
67         // Detect Pet output
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");
75             assert(handle);
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;
80
81                 //TTree *histos = dynamic_cast<TH1F *>(handle->Get("histo;1"));
82                 //const bool is_hist_output = (histos != NULL);
83
84
85             if (is_pet_output) {
86                 double time;
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);
92                     time_accum += time;
93                 }
94
95                 input_file.mean_time = time_accum / total;
96                 pet_input_files.push_back(input_file);
97                 cout << " mean_time " << input_file.mean_time;
98             }
99
100             cout << endl;
101
102             handle->Close();
103             delete handle;
104             //bitwise on booleans?
105             all_pet_output &= is_pet_output;
106         }
107         cout << "all_pet_output " << all_pet_output << endl;
108
109         if (all_pet_output) {
110             GateMergeManager manager(args_info.fastmerge_given, args_info.verbose_arg, true, 0, "");
111
112             cout << "sorting input file using singles time" << endl;
113             std::sort(pet_input_files.begin(), pet_input_files.end(), sort_pet_input_file);
114
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);
118
119             manager.StartMergingFromFilenames(input_filenames, args_info.output_arg);
120             //if the file was PET, then we're done.
121             return 0;
122         }
123     }
124
125     //if the file was not PET, but a generic Rootfile, use TFileMerger.
126
127     // Merge
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();
132
133     cout << "whatbool: " << whatbool << " no more whatbool" << endl;
134     // this is the end my friend
135     return 0;
136     
137 }
138 //-----------------------------------------------------------------------------