BmnRoot 26.10.0-18-g4e3414f9
Software framework of the BM@N experiment
Loading...
Searching...
No Matches
calculate_size.C
Go to the documentation of this file.
1// Calculate the disk space taken by the event tree of a BmnRoot ROOT file and by each of its branches.
2//
3// The macro opens the "bmndata" tree of a simulation, digi or DST file and prints the size on disk of
4// the whole tree and of every top-level branch (including all its sub-branches), e.g. to estimate how
5// much a new branch or a change of a data format costs in the output files.
6//
7// The size of a branch is the compressed size of its baskets (the event data) plus the compressed size
8// of its metadata (the TBranch object with its sub-branches and leaves, which is streamed into a memory
9// file with the compression settings of the input file). For an uncompressed branch the uncompressed
10// size of its baskets is taken. The size of the tree is the size of its header stored in the file
11// (it contains the metadata of all branches) plus the baskets of all branches, so the sizes of the
12// branches add up approximately to the size of the tree.
13// The event data themselves are not read, only the tree header, so even large files are processed fast.
14// NB: only the "bmndata" tree is taken into account. Other objects of the file (geometry, parameter
15// containers, run headers...) are not, therefore the file itself is larger than the tree.
16// NB: the sizes are printed in binary units (1 KB = 1024 B)
17//
18// Usage: root -l -b -q 'calculate_size.C("bmndst.root")'
19// root -l -b -q '$VMCWORKDIR/macro/profiling/size/calculate_size.C("$VMCWORKDIR/macro/run/bmndst.root")'
20
21R__ADD_INCLUDE_PATH($VMCWORKDIR)
22#include "services/function_set.h"
23
24Long64_t GetTotalSize(TBranch* b, bool ondisk, bool inclusive);
25Long64_t GetBasketSize(TBranch* b, bool ondisk, bool inclusive);
26
27Long64_t GetBasketSize(TObjArray* branches, bool ondisk, bool inclusive)
28{
29 Long64_t result = 0;
30 size_t n = branches->GetEntries();
31 for (size_t i = 0; i < n; i++)
32 result += GetBasketSize(dynamic_cast<TBranch*>(branches->At(i)), ondisk, inclusive);
33
34 return result;
35}
36
37Long64_t GetBasketSize(TBranch* b, bool ondisk, bool inclusive)
38{
39 Long64_t result = 0;
40 if (b) {
41 if (ondisk && b->GetZipBytes() > 0)
42 result = b->GetZipBytes();
43 else
44 result = b->GetTotBytes();
45
46 if (inclusive) {
47 result += GetBasketSize(b->GetListOfBranches(), ondisk, true);
48 }
49 return result;
50 }
51 return result;
52}
53
54Long64_t GetTotalSize(TBranch* br, bool ondisk, bool inclusive)
55{
56 TMemFile f("buffer", "CREATE");
57 if (br->GetTree()->GetCurrentFile())
58 f.SetCompressionSettings(br->GetTree()->GetCurrentFile()->GetCompressionSettings());
59
60 f.WriteObject(br, "thisbranch");
61 TKey* key = f.GetKey("thisbranch");
62 Long64_t size;
63 if (ondisk)
64 size = key->GetNbytes();
65 else
66 size = key->GetObjlen();
67 return GetBasketSize(br, ondisk, inclusive) + size;
68}
69
70Long64_t GetTotalSize(TObjArray* branches, bool ondisk)
71{
72 Long64_t result = 0;
73 size_t n = branches->GetEntries();
74 for (size_t i = 0; i < n; i++) {
75 result += GetTotalSize(dynamic_cast<TBranch*>(branches->At(i)), ondisk, true);
76 cerr << "After " << branches->At(i)->GetName() << " " << result << endl;
77 }
78 return result;
79}
80
81Long64_t GetTotalSize(TTree* t, bool ondisk)
82{
83 TKey* key = 0;
84 if (t->GetDirectory())
85 key = t->GetDirectory()->GetKey(t->GetName());
86
87 Long64_t ondiskSize = 0;
88 Long64_t totalSize = 0;
89 if (key) {
90 ondiskSize = key->GetNbytes();
91 totalSize = key->GetObjlen();
92 } else {
93 TMemFile f("buffer", "CREATE");
94 if (t->GetCurrentFile())
95 f.SetCompressionSettings(t->GetCurrentFile()->GetCompressionSettings());
96
97 f.WriteTObject(t);
98 key = f.GetKey(t->GetName());
99 ondiskSize = key->GetNbytes();
100 totalSize = key->GetObjlen();
101 }
102 if (t->GetBranchRef()) {
103 if (ondisk)
104 ondiskSize += GetBasketSize(t->GetBranchRef(), true, true);
105 else
106 totalSize += GetBasketSize(t->GetBranchRef(), false, true);
107 }
108 if (ondisk)
109 return ondiskSize + GetBasketSize(t->GetListOfBranches(), /* ondisk */ true, /* inclusive */ true);
110 else
111 return totalSize + GetBasketSize(t->GetListOfBranches(), /* ondisk */ false, /* inclusive */ true);
112}
113
115{
116 // Return the size on disk on this TTree
117 return GetTotalSize(t, true);
118}
119
120Long64_t sizeOnDisk(TBranch* branch, bool inclusive)
121{
122 // Return the size on disk on this branch.
123 // If 'inclusive' is true, include also the size of all its sub-branches
124 return GetTotalSize(branch, true, inclusive);
125}
126
128{
129 cout << "The branch \"" << br->GetName() << "\" takes " << byte_size_to_human(sizeOnDisk(br, true)) << " on disk"
130 << endl;
131 size_t n = br->GetListOfBranches()->GetEntries();
132 for (size_t i = 0; i < n; i++) {
133 TBranch* subbr = dynamic_cast<TBranch*>(br->GetListOfBranches()->At(i));
134 cout << " Its sub-branch \"" << subbr->GetName() << "\" takes " << byte_size_to_human(sizeOnDisk(subbr, true))
135 << " on disk" << endl;
136 }
137}
138
140{
141 cout << "The TTree \"" << t->GetName() << "\" takes " << byte_size_to_human(sizeOnDisk(t)) << " on disk" << endl;
142 size_t n = t->GetListOfBranches()->GetEntries();
143 for (size_t i = 0; i < n; i++) {
144 TBranch* br = dynamic_cast<TBranch*>(t->GetListOfBranches()->At(i));
145 cout << " Its branch \"" << br->GetName() << "\" takes " << byte_size_to_human(sizeOnDisk(br, true))
146 << " on disk" << endl;
147 }
148}
149
150// reserved approach
152{
153 TStopwatch timer;
154 timer.Start();
155
156 size_t n = t->GetListOfBranches()->GetEntries();
157 for (size_t i = 0; i < n; i++) {
158 TBranch* br = dynamic_cast<TBranch*>(t->GetListOfBranches()->At(i));
159 t->SetBranchStatus("*", 0);
160 t->SetBranchStatus(br->GetName(), 1);
161
162 TFile* branch_file = new TFile("cloned_branch_size.root", "recreate");
163 TTree* branch_tree = t->CloneTree();
164 branch_tree->Write();
165 branch_file->Close();
166 delete branch_file;
167
168 // print file size and remove it
169 // ... //
170 }
171
172 timer.Stop();
173 Double_t rtime = timer.RealTime(), ctime = timer.CpuTime();
174 printf("RealTime=%f seconds, CpuTime=%f seconds\n", rtime, ctime);
175}
176
177void calculate_size(TString root_file_path)
178{
179 gSystem->ExpandPathName(root_file_path);
180
181 // check that the file exists and can be opened
182 if (gSystem->AccessPathName(root_file_path.Data())) {
183 cerr << "Error: file does not exist or is not accessible: " << root_file_path << endl;
184 return;
185 }
186
187 TChain* bmnChain = new TChain("bmndata");
188 bmnChain->Add(root_file_path);
189
190 // force opening the file and reading the tree header;
191 // if the "bmndata" tree is missing, the chain stays empty
192 if (bmnChain->GetEntries() <= 0) {
193 cerr << "Error: TTree \"bmndata\" not found or empty in file: " << root_file_path << endl;
194 delete bmnChain;
195 return;
196 }
197
198 // measure the tree stored in the file, not the chain: the chain is not written to the file,
199 // so the tree header with the metadata of all branches would be missed
200 bmnChain->LoadTree(0);
201 printTreeSummary(bmnChain->GetTree());
202
203 delete bmnChain;
204}
int i
Definition P4_F32vec4.h:22
double Double_t
long long Long64_t
#define R__ADD_INCLUDE_PATH(PATH)
R__EXTERN TSystem * gSystem
TTree * GetTree() const
TObjArray * GetListOfBranches()
TTree * GetTree() const override
virtual Int_t Add(const char *name, Long64_t nentries=TTree::kMaxEntries)
Long64_t LoadTree(Long64_t entry) override
Long64_t GetEntries() const override
virtual TKey * GetKey(const char *, Short_t=9999) const
Int_t GetCompressionSettings() const
void Close(Option_t *option="") override
const char * GetName() const override
Int_t GetEntries() const override
TObject * At(Int_t idx) const override
virtual const char * GetName() const
Double_t RealTime()
void Start(Bool_t reset=kTRUE)
Double_t CpuTime()
void Stop()
const char * Data() const
virtual void SetBranchStatus(const char *bname, bool status=true, UInt_t *found=nullptr)
TFile * GetCurrentFile() const
TDirectory * GetDirectory() const
virtual TBranchRef * GetBranchRef() const
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) const override
virtual TTree * CloneTree(Long64_t nentries=-1, Option_t *option="")
virtual TObjArray * GetListOfBranches()
string byte_size_to_human(uint64_t byte_size, unsigned precision=2)
*brief user defined string literal for JSON values *sa std::size_t n
Definition json.hpp:20362
Long64_t sizeOnDisk(TTree *t)
void printTreeSummary(TTree *t)
void calculate_size(TString root_file_path)
void printBranchSummary(TBranch *br)
void cloned_branch_sizez(TTree *t)
Long64_t GetTotalSize(TBranch *b, bool ondisk, bool inclusive)
Long64_t GetBasketSize(TBranch *b, bool ondisk, bool inclusive)