Skip to content

Commit cd734c2

Browse files
committed
[hadd] Improve verbosity settings
new verbosity works like this: v0: only output errors v1: only output errors and warnings v2: output errors, warnings and TFileMerger messages v3: output all messages This is largely backwards-compatible as the default verbosity was and still is 99.
1 parent 24f7f5f commit cd734c2

File tree

12 files changed

+90
-32
lines changed

12 files changed

+90
-32
lines changed

main/src/hadd.cxx

Lines changed: 66 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -63,16 +63,21 @@
6363
whitespaces or '/'. You can also pass TDirectory names, which apply to the entire directory
6464
content. Lines beginning with '#' are ignored. If this flag is passed, "-Ltype" MUST be
6565
passed as well.
66-
\param -Ltype <SkipListed|OnlyListed> Sets the type of operation performed on the objects listed in FILE given with the
66+
\param -Ltype <SkipListed|OnlyListed> Sets the type of operation performed on the objects listed in FILE given with
67+
the
6768
"-L" flag. "SkipListed" will skip all the listed objects; "OnlyListed" will only merge those
6869
objects. If this flag is passed, "-L" must be passed as well.
6970
\param -n <N_FILES> Open at most `N` files at once (use 0 to request to use the system maximum - which is also
7071
the default). This number includes both the input reading files as well as the output file.
71-
Thus, if set to 1, it will be automatically replaced to a minimum of 2. If set to a too large value,
72-
it will be clipped to the system maximum.
72+
Thus, if set to 1, it will be automatically replaced to a minimum of 2. If set to a too large
73+
value, it will be clipped to the system maximum.
7374
\param -O Re-optimize basket size when merging TTree
7475
\param -T Do not merge Trees
75-
\param -v [LEVEL] Explicitly set the verbosity level: 0 request no output, 99 is the default
76+
\param -v [LEVEL] Explicitly set the verbosity level:
77+
<= 0 = only output errors;
78+
1 = only output errors and warnings;
79+
2 = output minimal informative messages, errors and warnings;
80+
>= 3 = output all messages (default).
7681
\return hadd returns a status code: 0 if OK, 1 otherwise
7782
7883
For example assume 3 files f1, f2, f3 containing histograms hn and Trees Tn
@@ -155,29 +160,62 @@
155160
#include <optional>
156161
#include <sstream>
157162
#include <string>
163+
#include <streambuf>
158164

159165
#ifndef R__WIN32
160166
#include "ROOT/TProcessExecutor.hxx"
161167
#endif
162168

163169
////////////////////////////////////////////////////////////////////////////////
164170

165-
inline std::ostream &Err()
171+
// NOTE: TFileMerger will use PrintLevel = gVerbosity - 1. If PrintLevel is < 1, it will print nothing, otherwise
172+
// it will print everything. To give some granularity to hadd, we do the following:
173+
// gVerbosity = 0: only print hadd errors
174+
// gVerbosity = 1: only print hadd errors + warnings
175+
// gVerbosity = 2: print hadd errors + warnings and TFileMerger messages
176+
// gVerbosity > 2: print all hadd and TFileMerger messages.
177+
static int gVerbosity = 99;
178+
179+
namespace {
180+
181+
class NullBuf : public std::streambuf {
182+
public:
183+
int overflow(int c) final { return c; }
184+
};
185+
186+
class NullStream : public std::ostream {
187+
NullBuf fBuf;
188+
189+
public:
190+
NullStream() : std::ostream(&fBuf) {}
191+
};
192+
193+
} // namespace
194+
195+
static NullStream &GetNullStream()
196+
{
197+
static NullStream nullStream;
198+
return nullStream;
199+
}
200+
201+
static inline std::ostream &Err()
166202
{
167203
std::cerr << "Error in <hadd>: ";
168204
return std::cerr;
169205
}
170206

171-
inline std::ostream &Warn()
207+
static inline std::ostream &Warn()
172208
{
173-
std::cerr << "Warning in <hadd>: ";
174-
return std::cerr;
209+
std::ostream &s = gVerbosity < 1 ? GetNullStream() : std::cerr;
210+
s << "Warning in <hadd>: ";
211+
return s;
175212
}
176213

177-
inline std::ostream &Info()
214+
static inline std::ostream &Info()
178215
{
179-
std::cerr << "Info in <hadd>: ";
180-
return std::cerr;
216+
std::ostream &s = gVerbosity < 3 ? GetNullStream() : std::cerr;
217+
s << "Info in <hadd>: ";
218+
return s;
181219
}
182220

183221
using IntFlag_t = uint32_t;
@@ -626,7 +664,7 @@ int main(int argc, char **argv)
626664

627665
ROOT::TIOFeatures features = args.fFeatures.value_or(ROOT::TIOFeatures{});
628666
Int_t maxopenedfiles = args.fMaxOpenedFiles.value_or(0);
629-
Int_t verbosity = args.fVerbosity.value_or(99);
667+
gVerbosity = args.fVerbosity.value_or(99);
630668
Int_t newcomp = args.fCompressionSettings.value_or(-1);
631669
TString cacheSize = args.fCacheSize.value_or("");
632670

@@ -674,8 +712,7 @@ int main(int argc, char **argv)
674712
}
675713
targetname = argv[args.fOutputArgIdx];
676714

677-
if (verbosity > 1)
678-
Info() << "target file: " << targetname << "\n";
715+
Info() << "target file: " << targetname << "\n";
679716

680717
if (args.fCacheSize)
681718
Info() << "Using " << cacheSize << "\n";
@@ -686,7 +723,7 @@ int main(int argc, char **argv)
686723

687724
TFileMerger fileMerger(kFALSE, kFALSE);
688725
fileMerger.SetMsgPrefix("hadd");
689-
fileMerger.SetPrintLevel(verbosity - 1);
726+
fileMerger.SetPrintLevel(gVerbosity - 1);
690727
if (maxopenedfiles > 0) {
691728
fileMerger.SetMaxOpenedFiles(maxopenedfiles);
692729
}
@@ -758,21 +795,22 @@ int main(int argc, char **argv)
758795
fileMerger.SetMergeOptions(TString("DefaultCompression"));
759796
}
760797
}
761-
if (verbosity > 1) {
762-
if (args.fKeepCompressionAsIs && !args.fReoptimize)
763-
Info() << "compression setting for meta data: " << newcomp << '\n';
764-
else
765-
Info() << "compression setting for all output: " << newcomp << '\n';
766-
}
798+
if (args.fKeepCompressionAsIs && !args.fReoptimize)
799+
Info() << "compression setting for meta data: " << newcomp << '\n';
800+
else
801+
Info() << "compression setting for all output: " << newcomp << '\n';
802+
767803
if (args.fAppend) {
768804
if (!fileMerger.OutputFile(targetname, "UPDATE", newcomp)) {
769805
Err() << "error opening target file for update :" << targetname << ".\n";
770806
return 2;
771807
}
772808
} else if (!fileMerger.OutputFile(targetname, args.fForce, newcomp)) {
773-
Err() << "error opening target file (does " << targetname << " exist?).\n";
809+
std::stringstream ss;
810+
ss << "error opening target file (does " << targetname << " exist?).\n";
774811
if (!args.fForce)
775-
Info() << "pass \"-f\" argument to force re-creation of output file.\n";
812+
ss << "pass \"-f\" argument to force re-creation of output file.\n";
813+
Err() << ss.str();
776814
return 1;
777815
}
778816

@@ -850,7 +888,7 @@ int main(int argc, char **argv)
850888
auto parallelMerge = [&](int start) {
851889
TFileMerger mergerP(kFALSE, kFALSE);
852890
mergerP.SetMsgPrefix("hadd");
853-
mergerP.SetPrintLevel(verbosity - 1);
891+
mergerP.SetPrintLevel(gVerbosity - 1);
854892
if (maxopenedfiles > 0) {
855893
mergerP.SetMaxOpenedFiles(maxopenedfiles / nProcesses);
856894
}
@@ -893,16 +931,12 @@ int main(int argc, char **argv)
893931
#endif
894932

895933
if (status) {
896-
if (verbosity == 1) {
897-
Info() << "merged " << allSubfiles.size() << " (" << fileMerger.GetMergeList()->GetEntries()
898-
<< ") input (partial) files into " << targetname << ".\n";
899-
}
934+
Info() << "merged " << allSubfiles.size() << " (" << fileMerger.GetMergeList()->GetEntries()
935+
<< ") input (partial) files into " << targetname << "\n";
900936
return 0;
901937
} else {
902-
if (verbosity == 1) {
903-
Err() << "failure during the merge of " << allSubfiles.size() << " ("
904-
<< fileMerger.GetMergeList()->GetEntries() << ") input (partial) files into " << targetname << ".\n";
905-
}
938+
Err() << "failure during the merge of " << allSubfiles.size() << " (" << fileMerger.GetMergeList()->GetEntries()
939+
<< ") input (partial) files into " << targetname << "\n";
906940
return 1;
907941
}
908942
}

roottest/root/io/evolution/versions/attmarker.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ hadd Source file 2: hsimple20.root
55
Warning in <hadd>: Sources and Target have different compression settings
66
hadd merging will be slower
77
hadd Target path: result.root:/
8+
Info in <hadd>: merged 2 (2) input (partial) files into result.root

roottest/root/io/hadd/CMakeLists.txt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,3 +202,17 @@ ROOTTEST_ADD_TEST(test_hadd_args_missing_l
202202
COMMAND ${ROOT_hadd_CMD} hadd_args_missing_l.root hadd_args_in.root -Ltype SkipListed
203203
PASSREGEX "Error in <hadd>: -L must always be passed along with -Ltype"
204204
)
205+
206+
ROOTTEST_ADD_TEST(test_hadd_args_quiet
207+
FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture
208+
PRECMD ${CMAKE_COMMAND} -E rm -f hadd_args_quiet.root
209+
COMMAND ${ROOT_hadd_CMD} hadd_args_quiet.root hadd_args_in.root -v2
210+
OUTREF hadd_args_quiet.ref
211+
)
212+
213+
ROOTTEST_ADD_TEST(test_hadd_args_quieter
214+
FIXTURES_REQUIRED root-io-hadd-test_hadd_args_gen_input-fixture
215+
PRECMD ${CMAKE_COMMAND} -E rm -f hadd_args_quieter.root
216+
COMMAND ${ROOT_hadd_CMD} hadd_args_quieter.root hadd_args_in.root -v1
217+
OUTREF hadd_args_quieter.ref
218+
)

roottest/root/io/hadd/hadd_args_cachesize.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ Info in <hadd>: Using cachesize=100M
33
Info in <hadd>: compression setting for all output: 101
44
hadd Source file 1: hadd_args_in.root
55
hadd Target path: hadd_args_cachesize_out.root:/
6+
Info in <hadd>: merged 1 (1) input (partial) files into hadd_args_cachesize_out.root

roottest/root/io/hadd/hadd_args_ff_dbg_j_2.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ Info in <hadd>: each process should handle at least 3 files for efficiency. Sett
55
hadd Source file 1: hadd_args_in.root
66
hadd Source file 2: hadd_args_in.root
77
hadd Target path: hadd_args_ff_dbg_j_2_out.root:/
8+
Info in <hadd>: merged 2 (2) input (partial) files into hadd_args_ff_dbg_j_2_out.root

roottest/root/io/hadd/hadd_args_minusminus.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ hadd Source file 1: hadd_args_in.root
44
Warning in <hadd>: Sources and Target have different compression settings
55
hadd merging will be slower
66
hadd Target path: --hadd_args_out.root:/
7+
Info in <hadd>: merged 1 (1) input (partial) files into --hadd_args_out.root

roottest/root/io/hadd/hadd_args_n0.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ Info in <hadd>: target file: hadd_args_n0_out.root
22
Info in <hadd>: compression setting for all output: 101
33
hadd Source file 1: hadd_args_in.root
44
hadd Target path: hadd_args_n0_out.root:/
5+
Info in <hadd>: merged 1 (1) input (partial) files into hadd_args_n0_out.root

roottest/root/io/hadd/hadd_args_n_1.ref

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ Info in <hadd>: target file: hadd_args_n_1_out.root
22
Info in <hadd>: compression setting for all output: 101
33
hadd Source file 1: hadd_args_in.root
44
hadd Target path: hadd_args_n_1_out.root:/
5+
Info in <hadd>: merged 1 (1) input (partial) files into hadd_args_n_1_out.root
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
hadd Source file 1: hadd_args_in.root
2+
hadd Target path: hadd_args_quiet.root:/

roottest/root/io/hadd/hadd_args_quieter.ref

Whitespace-only changes.

0 commit comments

Comments
 (0)