Loading [MathJax]/extensions/tex2jax.js
Logo ROOT  
Reference Guide
 
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
Loading...
Searching...
No Matches
hadd.cxx
Go to the documentation of this file.
1/**
2 \file hadd.cxx
3 \brief This program will add histograms (see note) and Trees from a list of root files and write them to a target root file.
4 The target file is newly created and must not be
5 identical to one of the source files.
6
7 Syntax:
8 ```{.cpp}
9 hadd targetfile source1 source2 ...
10 ```
11 or
12 ```{.cpp}
13 hadd -f targetfile source1 source2 ...
14 ```
15 (targetfile is overwritten if it exists)
16
17 \param -a Append to the output
18 \param -f Force overwriting of output file.
19 \param -f[0-9] Set target compression level. 0 = uncompressed, 6 = highly compressed.
20 \param -fk Sets the target file to contain the baskets with the same compression
21 as the input files (unless -O is specified). Compresses the meta data
22 using the compression level specified in the first input or the
23 compression setting after fk (for example 206 when using -fk206)
24 \param -ff The compression level used is the one specified in the first input
25
26 \param -k Skip corrupt or non-existent files, do not exit
27 \param -O Re-optimize basket size when merging TTree
28 \param -v Explicitly set the verbosity level: 0 request no output, 99 is the default
29 \param -j Parallelise the execution in multiple processes
30 \param -dbg Parallelise the execution in multiple processes in debug mode (Does not delete partial files stored
31 inside working directory)
32 \param -d Carry out the partial multiprocess execution in the specified directory
33 \param -n Open at most `n` at once (use 0 to request to use the system maximum)
34 \param -experimental-io-features `<feature>` Enables the corresponding experimental feature for output trees
35 \return hadd returns a status code: 0 if OK, -1 otherwise
36
37 When the -f option is specified, one can also specify the compression
38 level of the target file. By default the compression level is 1 (kDefaultZLIB), but
39 if "-f0" is specified, the target file will not be compressed.
40 if "-f6" is specified, the compression level 6 will be used.
41
42 For example assume 3 files f1, f2, f3 containing histograms hn and Trees Tn
43 - f1 with h1 h2 h3 T1
44 - f2 with h1 h4 T1 T2
45 - f3 with h5
46 the result of
47 ```
48 hadd -f x.root f1.root f2.root f3.root
49 ```
50 will be a file x.root with h1 h2 h3 h4 h5 T1 T2
51 where
52 - h1 will be the sum of the 2 histograms in f1 and f2
53 - T1 will be the merge of the Trees in f1 and f2
54
55 The files may contain sub-directories.
56
57 If the source files contains histograms and Trees, one can skip
58 the Trees with
59 ```
60 hadd -T targetfile source1 source2 ...
61 ```
62
63 Wildcarding and indirect files are also supported
64 ```
65 hadd result.root myfil*.root
66 ```
67 will merge all files in myfil*.root
68 ```
69 hadd result.root file1.root @list.txt file2. root myfil*.root
70 ```
71 will merge file1.root, file2.root, all files in myfil*.root
72 and all files in the indirect text file list.txt ("@" as the first
73 character of the file indicates an indirect file. An indirect file
74 is a text file containing a list of other files, including other
75 indirect files, one line per file).
76
77 If the sources and and target compression levels are identical (default),
78 the program uses the TChain::Merge function with option "fast", ie
79 the merge will be done without unzipping or unstreaming the baskets
80 (i.e. direct copy of the raw byte on disk). The "fast" mode is typically
81 5 times faster than the mode unzipping and unstreaming the baskets.
82
83 If the option -cachesize is used, hadd will resize (or disable if 0) the
84 prefetching cache use to speed up I/O operations.
85
86 For options that take a size as argument, a decimal number of bytes is expected.
87 If the number ends with a `k`, `m`, `g`, etc., the number is multiplied
88 by 1000 (1K), 1000000 (1MB), 1000000000 (1G), etc.
89 If this prefix is followed by `i`, the number is multiplied by the traditional
90 1024 (1KiB), 1048576 (1MiB), 1073741824 (1GiB), etc.
91 The prefix can be optionally followed by B whose casing is ignored,
92 eg. 1k, 1K, 1Kb and 1KB are the same.
93
94 \note By default histograms are added. However hadd does not support the case where
95 histograms have their bit TH1::kIsAverage set.
96
97 \authors Rene Brun, Dirk Geppert, Sven A. Schmidt, Toby Burnett
98*/
99#include "Compression.h"
100#include <ROOT/RConfig.hxx>
101#include "ROOT/TIOFeatures.hxx"
102#include "TFile.h"
103#include "THashList.h"
104#include "TKey.h"
105#include "TClass.h"
106#include "TSystem.h"
107#include "TUUID.h"
108#include "ROOT/StringConv.hxx"
109#include "snprintf.h"
110
111#include <string>
112#include <iostream>
113#include <fstream>
114#include <cstdlib>
115#include <climits>
116#include <sstream>
117#include "haddCommandLineOptionsHelp.h"
118
119#include "TFileMerger.h"
120#ifndef R__WIN32
122#endif
123
124////////////////////////////////////////////////////////////////////////////////
125
126int main( int argc, char **argv )
127{
128 if ( argc < 3 || "-h" == std::string(argv[1]) || "--help" == std::string(argv[1]) ) {
129 fprintf(stderr, kCommandLineOptionsHelp);
130 return 1;
131 }
132
133 ROOT::TIOFeatures features;
134 Bool_t append = kFALSE;
135 Bool_t force = kFALSE;
136 Bool_t skip_errors = kFALSE;
137 Bool_t reoptimize = kFALSE;
138 Bool_t noTrees = kFALSE;
139 Bool_t keepCompressionAsIs = kFALSE;
140 Bool_t useFirstInputCompression = kFALSE;
141 Bool_t multiproc = kFALSE;
142 Bool_t debug = kFALSE;
143 Int_t maxopenedfiles = 0;
144 Int_t verbosity = 99;
145 TString cacheSize;
146 SysInfo_t s;
147 gSystem->GetSysInfo(&s);
148 auto nProcesses = s.fCpus;
149 auto workingDir = gSystem->TempDirectory();
150 int outputPlace = 0;
151 int ffirst = 2;
152 Int_t newcomp = -1;
153 for( int a = 1; a < argc; ++a ) {
154 if ( strcmp(argv[a],"-T") == 0 ) {
155 noTrees = kTRUE;
156 ++ffirst;
157 } else if ( strcmp(argv[a],"-a") == 0 ) {
158 append = kTRUE;
159 ++ffirst;
160 } else if ( strcmp(argv[a],"-f") == 0 ) {
161 force = kTRUE;
162 ++ffirst;
163 } else if ( strcmp(argv[a],"-k") == 0 ) {
164 skip_errors = kTRUE;
165 ++ffirst;
166 } else if ( strcmp(argv[a],"-O") == 0 ) {
167 reoptimize = kTRUE;
168 ++ffirst;
169 } else if (strcmp(argv[a], "-dbg") == 0) {
170 debug = kTRUE;
171 verbosity = kTRUE;
172 ++ffirst;
173 } else if (strcmp(argv[a], "-d") == 0) {
174 if (a + 1 != argc && argv[a + 1][0] != '-') {
175 if (gSystem->AccessPathName(argv[a + 1])) {
176 std::cerr << "Error: could not access the directory specified: " << argv[a + 1]
177 << ". We will use the system's temporal directory.\n";
178 } else {
179 workingDir = argv[a + 1];
180 }
181 ++a;
182 ++ffirst;
183 } else {
184 std::cout << "-d: no directory specified. We will use the system's temporal directory.\n";
185 }
186 ++ffirst;
187 } else if (strcmp(argv[a], "-j") == 0) {
188 // If the number of processes is not specified, use the default.
189 if (a + 1 != argc && argv[a + 1][0] != '-') {
190 // number of processes specified
191 Long_t request = 1;
192 for (char *c = argv[a + 1]; *c != '\0'; ++c) {
193 if (!isdigit(*c)) {
194 // Wrong number of Processes. Use the default:
195 std::cerr << "Error: could not parse the number of processes to run in parallel passed after -j: "
196 << argv[a + 1] << ". We will use the system maximum.\n";
197 request = 0;
198 break;
199 }
200 }
201 if (request == 1) {
202 request = strtol(argv[a + 1], 0, 10);
203 if (request < kMaxLong && request >= 0) {
204 nProcesses = (Int_t)request;
205 ++a;
206 ++ffirst;
207 std::cout << "Parallelizing with " << nProcesses << " processes.\n";
208 } else {
209 std::cerr << "Error: could not parse the number of processes to use passed after -j: " << argv[a + 1]
210 << ". We will use the default value (number of logical cores).\n";
211 }
212 }
213 }
214 multiproc = kTRUE;
215 ++ffirst;
216 } else if ( strcmp(argv[a],"-cachesize=") == 0 ) {
217 int size;
218 static const size_t arglen = strlen("-cachesize=");
219 auto parseResult = ROOT::FromHumanReadableSize(argv[a]+arglen,size);
220 if (parseResult == ROOT::EFromHumanReadableSize::kParseFail) {
221 std::cerr << "Error: could not parse the cache size passed after -cachesize: "
222 << argv[a + 1] << ". We will use the default value.\n";
223 } else if (parseResult == ROOT::EFromHumanReadableSize::kOverflow) {
224 double m;
225 const char *munit = nullptr;
226 ROOT::ToHumanReadableSize(INT_MAX,false,&m,&munit);
227 std::cerr << "Error: the cache size passed after -cachesize is too large: "
228 << argv[a + 1] << " is greater than " << m << munit
229 << ". We will use the default value.\n";
230 } else {
231 cacheSize = "cachesize=";
232 cacheSize.Append(argv[a]+1);
233 }
234 ++ffirst;
235 } else if ( strcmp(argv[a],"-cachesize") == 0 ) {
236 if (a+1 >= argc) {
237 std::cerr << "Error: no cache size number was provided after -cachesize.\n";
238 } else {
239 int size;
240 auto parseResult = ROOT::FromHumanReadableSize(argv[a+1],size);
241 if (parseResult == ROOT::EFromHumanReadableSize::kParseFail) {
242 std::cerr << "Error: could not parse the cache size passed after -cachesize: "
243 << argv[a + 1] << ". We will use the default value.\n";
244 } else if (parseResult == ROOT::EFromHumanReadableSize::kOverflow) {
245 double m;
246 const char *munit = nullptr;
247 ROOT::ToHumanReadableSize(INT_MAX,false,&m,&munit);
248 std::cerr << "Error: the cache size passed after -cachesize is too large: "
249 << argv[a + 1] << " is greater than " << m << munit
250 << ". We will use the default value.\n";
251 ++a;
252 ++ffirst;
253 } else {
254 cacheSize = "cachesize=";
255 cacheSize.Append(argv[a+1]);
256 ++a;
257 ++ffirst;
258 }
259 }
260 ++ffirst;
261 } else if (!strcmp(argv[a], "-experimental-io-features")) {
262 if (a+1 >= argc) {
263 std::cerr << "Error: no IO feature was specified after -experimental-io-features; ignoring\n";
264 } else {
265 std::stringstream ss;
266 ss.str(argv[++a]);
267 ++ffirst;
268 std::string item;
269 while (std::getline(ss, item, ',')) {
270 if (!features.Set(item)) {
271 std::cerr << "Ignoring unknown feature request: " << item << std::endl;
272 }
273 }
274 }
275 ++ffirst;
276 } else if ( strcmp(argv[a],"-n") == 0 ) {
277 if (a+1 >= argc) {
278 std::cerr << "Error: no maximum number of opened was provided after -n.\n";
279 } else {
280 Long_t request = strtol(argv[a+1], 0, 10);
281 if (request < kMaxLong && request >= 0) {
282 maxopenedfiles = (Int_t)request;
283 ++a;
284 ++ffirst;
285 } else {
286 std::cerr << "Error: could not parse the max number of opened file passed after -n: " << argv[a+1] << ". We will use the system maximum.\n";
287 }
288 }
289 ++ffirst;
290 } else if ( strcmp(argv[a],"-v") == 0 ) {
291 if (a+1 == argc || argv[a+1][0] == '-') {
292 // Verbosity level was not specified use the default:
293 verbosity = 99;
294// if (a+1 >= argc) {
295// std::cerr << "Error: no verbosity level was provided after -v.\n";
296 } else {
297 Bool_t hasFollowupNumber = kTRUE;
298 for (char *c = argv[a+1]; *c != '\0'; ++c) {
299 if (!isdigit(*c)) {
300 // Verbosity level was not specified use the default:
301 hasFollowupNumber = kFALSE;
302 break;
303 }
304 }
305 if (hasFollowupNumber) {
306 Long_t request = strtol(argv[a+1], 0, 10);
307 if (request < kMaxLong && request >= 0) {
308 verbosity = (Int_t)request;
309 ++a;
310 ++ffirst;
311 } else {
312 verbosity = 99;
313 std::cerr << "Error: could not parse the verbosity level passed after -v: " << argv[a+1] << ". We will use the default value (99).\n";
314 }
315 }
316 }
317 ++ffirst;
318 } else if ( argv[a][0] == '-' ) {
319 bool farg = false;
320 if (force && argv[a][1] == 'f') {
321 // Bad argument
322 std::cerr << "Error: Using option " << argv[a] << " more than once is not supported.\n";
323 ++ffirst;
324 farg = true;
325 }
326 const char *prefix = "";
327 if (argv[a][1] == 'f' && argv[a][2] == 'k') {
328 farg = true;
329 force = kTRUE;
330 keepCompressionAsIs = kTRUE;
331 prefix = "k";
332 }
333 if (argv[a][1] == 'f' && argv[a][2] == 'f') {
334 farg = true;
335 force = kTRUE;
336 useFirstInputCompression = kTRUE;
337 if (argv[a][3] != '\0') {
338 std::cerr << "Error: option -ff should not have any suffix: " << argv[a] << " (suffix has been ignored)\n";
339 }
340 }
341 char ft[7];
342 for (int alg = 0; !useFirstInputCompression && alg <= 5; ++alg) {
343 for( int j=0; j<=9; ++j ) {
344 const int comp = (alg*100)+j;
345 snprintf(ft,7,"-f%s%d",prefix,comp);
346 if (!strcmp(argv[a],ft)) {
347 farg = true;
348 force = kTRUE;
349 newcomp = comp;
350 break;
351 }
352 }
353 }
354 if (!farg) {
355 // Bad argument
356 std::cerr << "Error: option " << argv[a] << " is not a supported option.\n";
357 }
358 ++ffirst;
359 } else if (!outputPlace) {
360 outputPlace = a;
361 }
362 }
363
364 gSystem->Load("libTreePlayer");
365
366 const char *targetname = 0;
367 if (outputPlace) {
368 targetname = argv[outputPlace];
369 } else {
370 targetname = argv[ffirst-1];
371 }
372
373 if (verbosity > 1) {
374 std::cout << "hadd Target file: " << targetname << std::endl;
375 }
376
377 TFileMerger fileMerger(kFALSE, kFALSE);
378 fileMerger.SetMsgPrefix("hadd");
379 fileMerger.SetPrintLevel(verbosity - 1);
380 if (maxopenedfiles > 0) {
381 fileMerger.SetMaxOpenedFiles(maxopenedfiles);
382 }
383 if (newcomp == -1) {
384 if (useFirstInputCompression || keepCompressionAsIs) {
385 // grab from the first file.
386 TFile *firstInput = nullptr;
387 if (argv[ffirst] && argv[ffirst][0]=='@') {
388 std::ifstream indirect_file(argv[ffirst]+1);
389 if( ! indirect_file.is_open() ) {
390 std::cerr<< "hadd could not open indirect file " << (argv[ffirst]+1) << std::endl;
391 return 1;
392 }
393 std::string line;
394 while( indirect_file ){
395 if( std::getline(indirect_file, line) && line.length() ) {
396 firstInput = TFile::Open(line.c_str());
397 break;
398 }
399 }
400 } else {
401 firstInput = TFile::Open(argv[ffirst]);
402 }
403 if (firstInput && !firstInput->IsZombie())
404 newcomp = firstInput->GetCompressionSettings();
405 else
407 delete firstInput;
408 } else newcomp = ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault % 100; // default compression level.
409 }
410 if (verbosity > 1) {
411 if (keepCompressionAsIs && !reoptimize)
412 std::cout << "hadd compression setting for meta data: " << newcomp << '\n';
413 else
414 std::cout << "hadd compression setting for all output: " << newcomp << '\n';
415 }
416 if (append) {
417 if (!fileMerger.OutputFile(targetname, "UPDATE", newcomp)) {
418 std::cerr << "hadd error opening target file for update :" << argv[ffirst-1] << "." << std::endl;
419 exit(2);
420 }
421 } else if (!fileMerger.OutputFile(targetname, force, newcomp)) {
422 std::cerr << "hadd error opening target file (does " << argv[ffirst-1] << " exist?)." << std::endl;
423 if (!force) std::cerr << "Pass \"-f\" argument to force re-creation of output file." << std::endl;
424 exit(1);
425 }
426
427 auto filesToProcess = argc - ffirst;
428 auto step = (filesToProcess + nProcesses - 1) / nProcesses;
429 if (multiproc && step < 3) {
430 // At least 3 files per process
431 step = 3;
432 nProcesses = (filesToProcess + step - 1) / step;
433 std::cout << "Each process should handle at least 3 files for efficiency.";
434 std::cout << " Setting the number of processes to: " << nProcesses << std::endl;
435 }
436 if (nProcesses == 1)
437 multiproc = kFALSE;
438
439 std::vector<std::string> partialFiles;
440
441#ifndef R__WIN32
442 // this is commented out only to try to prevent false positive detection
443 // from several anti-virus engines on Windows, and multiproc is not
444 // supported on Windows anyway
445 if (multiproc) {
446 auto uuid = TUUID();
447 auto partialTail = uuid.AsString();
448 for (auto i = 0; (i * step) < filesToProcess; i++) {
449 std::stringstream buffer;
450 buffer << workingDir << "/partial" << i << "_" << partialTail << ".root";
451 partialFiles.emplace_back(buffer.str());
452 }
453 }
454#endif
455
456 auto mergeFiles = [&](TFileMerger &merger) {
457 if (reoptimize) {
458 merger.SetFastMethod(kFALSE);
459 } else {
460 if (!keepCompressionAsIs && merger.HasCompressionChange()) {
461 // Don't warn if the user any request re-optimization.
462 std::cout << "hadd Sources and Target have different compression levels" << std::endl;
463 std::cout << "hadd merging will be slower" << std::endl;
464 }
465 }
466 merger.SetNotrees(noTrees);
467 merger.SetMergeOptions(cacheSize);
468 merger.SetIOFeatures(features);
469 Bool_t status;
470 if (append)
471 status = merger.PartialMerge(TFileMerger::kIncremental | TFileMerger::kAll);
472 else
473 status = merger.Merge();
474 return status;
475 };
476
477 auto sequentialMerge = [&](TFileMerger &merger, int start, int nFiles) {
478
479 for (auto i = start; i < (start + nFiles) && i < argc; i++) {
480 if (argv[i] && argv[i][0] == '@') {
481 std::ifstream indirect_file(argv[i] + 1);
482 if (!indirect_file.is_open()) {
483 std::cerr << "hadd could not open indirect file " << (argv[i] + 1) << std::endl;
484 return kFALSE;
485 }
486 while (indirect_file) {
487 std::string line;
488 if (std::getline(indirect_file, line) && line.length() && !merger.AddFile(line.c_str())) {
489 return kFALSE;
490 }
491 }
492 } else if (!merger.AddFile(argv[i])) {
493 if (skip_errors) {
494 std::cerr << "hadd skipping file with error: " << argv[i] << std::endl;
495 } else {
496 std::cerr << "hadd exiting due to error in " << argv[i] << std::endl;
497 return kFALSE;
498 }
499 }
500 }
501 return mergeFiles(merger);
502 };
503
504 auto parallelMerge = [&](int start) {
505 TFileMerger mergerP(kFALSE, kFALSE);
506 mergerP.SetMsgPrefix("hadd");
507 mergerP.SetPrintLevel(verbosity - 1);
508 if (maxopenedfiles > 0) {
509 mergerP.SetMaxOpenedFiles(maxopenedfiles / nProcesses);
510 }
511 if (!mergerP.OutputFile(partialFiles[(start - ffirst) / step].c_str(), newcomp)) {
512 std::cerr << "hadd error opening target partial file" << std::endl;
513 exit(1);
514 }
515 return sequentialMerge(mergerP, start, step);
516 };
517
518 auto reductionFunc = [&]() {
519 for (const auto &pf : partialFiles) {
520 fileMerger.AddFile(pf.c_str());
521 }
522 return mergeFiles(fileMerger);
523 };
524
525 Bool_t status;
526
527#ifndef R__WIN32
528 if (multiproc) {
529 ROOT::TProcessExecutor p(nProcesses);
530 auto res = p.Map(parallelMerge, ROOT::TSeqI(ffirst, argc, step));
531 status = std::accumulate(res.begin(), res.end(), 0U) == partialFiles.size();
532 if (status) {
533 status = reductionFunc();
534 } else {
535 std::cout << "hadd failed at the parallel stage" << std::endl;
536 }
537 if (!debug) {
538 for (const auto &pf : partialFiles) {
539 gSystem->Unlink(pf.c_str());
540 }
541 }
542 } else {
543 status = sequentialMerge(fileMerger, ffirst, filesToProcess);
544 }
545#else
546 status = sequentialMerge(fileMerger, ffirst, filesToProcess);
547#endif
548
549 if (status) {
550 if (verbosity == 1) {
551 std::cout << "hadd merged " << fileMerger.GetMergeList()->GetEntries() << " input files in " << targetname
552 << ".\n";
553 }
554 return 0;
555 } else {
556 if (verbosity == 1) {
557 std::cout << "hadd failure during the merge of " << fileMerger.GetMergeList()->GetEntries()
558 << " input files in " << targetname << ".\n";
559 }
560 return 1;
561 }
562}
int main()
Definition Prototype.cxx:12
#define c(i)
Definition RSha256.hxx:101
#define a(i)
Definition RSha256.hxx:99
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
int Int_t
Definition RtypesCore.h:45
const Bool_t kFALSE
Definition RtypesCore.h:101
long Long_t
Definition RtypesCore.h:54
bool Bool_t
Definition RtypesCore.h:63
const Bool_t kTRUE
Definition RtypesCore.h:100
R__EXTERN TSystem * gSystem
Definition TSystem.h:559
#define snprintf
Definition civetweb.c:1540
auto Map(F func, unsigned nTimes) -> std::vector< typename std::result_of< F()>::type >
Execute a function without arguments several times.
TIOFeatures provides the end-user with the ability to change the IO behavior of data written via a TT...
bool Set(EIOFeatures bits)
Set a specific IO feature.
This class provides a simple interface to execute the same task multiple times in parallel,...
A pseudo container class which is a generator of indices.
Definition TSeq.hxx:66
virtual Int_t GetEntries() const
This class provides file copy and merging services.
Definition TFileMerger.h:30
virtual Bool_t OutputFile(const char *url, Bool_t force)
Open merger output file.
virtual Bool_t AddFile(TFile *source, Bool_t own, Bool_t cpProgress)
Add the TFile to this file merger and give ownership of the TFile to this object (unless kFALSE is re...
TList * GetMergeList()
Definition TFileMerger.h:91
void SetMsgPrefix(const char *prefix)
Set the prefix to be used when printing informational message.
void SetPrintLevel(Int_t level)
Definition TFileMerger.h:88
@ kAll
Merge all type of objects (default)
Definition TFileMerger.h:76
@ kIncremental
Merge the input file with the content of the output file (if already existing).
Definition TFileMerger.h:71
void SetMaxOpenedFiles(Int_t newmax)
Set a limit to the number of files that TFileMerger will open simultaneously.
A ROOT file is a suite of consecutive data records (TKey instances) with a well defined format.
Definition TFile.h:54
Int_t GetCompressionSettings() const
Definition TFile.h:401
static TFile * Open(const char *name, Option_t *option="", const char *ftitle="", Int_t compress=ROOT::RCompressionSetting::EDefaults::kUseCompiledDefault, Int_t netopt=0)
Create / open a file.
Definition TFile.cxx:4025
R__ALWAYS_INLINE Bool_t IsZombie() const
Definition TObject.h:153
Basic string class.
Definition TString.h:136
TString & Append(const char *cs)
Definition TString.h:564
virtual int GetSysInfo(SysInfo_t *info) const
Returns static system info, like OS type, CPU type, number of CPUs RAM size, etc into the SysInfo_t s...
Definition TSystem.cxx:2464
virtual int Load(const char *module, const char *entry="", Bool_t system=kFALSE)
Load a shared library.
Definition TSystem.cxx:1855
virtual Bool_t AccessPathName(const char *path, EAccessMode mode=kFileExists)
Returns FALSE if one can access a file using the specified access mode.
Definition TSystem.cxx:1296
virtual int Unlink(const char *name)
Unlink, i.e.
Definition TSystem.cxx:1381
virtual const char * TempDirectory() const
Return a user configured or systemwide directory to create temporary files in.
Definition TSystem.cxx:1482
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition TUUID.h:42
TLine * line
void ToHumanReadableSize(value_type bytes, Bool_t si, Double_t *coeff, const char **units)
Return the size expressed in 'human readable' format.
EFromHumanReadableSize FromHumanReadableSize(std::string_view str, T &value)
Convert strings like the following into byte counts 5MB, 5 MB, 5M, 3.7GB, 123b, 456kB,...
@ kUseCompiledDefault
Use the compile-time default setting.
Definition Compression.h:50
Int_t fCpus
Definition TSystem.h:154
auto * m
Definition textangle.C:8