Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
hadd.C
Go to the documentation of this file.
1/// \file
2/// \ingroup tutorial_io
3/// \notebook -nodraw
4/// Macro to add histogram files
5/// This macro is kept for didactical purposes only: use instead the executable $ROOTSYS/bin/hadd !
6///
7/// This macro will add histograms from a list of root files and write them
8/// to a target root file. The target file is newly created and must not be
9/// identical to one of the source files.
10/// This code is based on the hadd.C example by Rene Brun and Dirk Geppert,
11/// which had a problem with directories more than one level deep.
12/// The macro from Sven has been enhanced by Anne-Sylvie Nicollerat <Anne-Sylvie.Nicollerat@cern.ch>
13/// to automatically add Trees (via a chain of trees).
14///
15/// \macro_code
16///
17/// \author Sven A. Schmidt, sven.schmidt@cern.ch, 13.2.2001
18
19
20#include "TChain.h"
21#include "TFile.h"
22#include "TH1.h"
23#include "TTree.h"
24#include "TKey.h"
25
26#include <cstring>
27#include <iostream>
28
30TFile *Target;
31
33
34
35void hadd() {
36 // Prepare the files to me merged
37 if(gSystem->AccessPathName("hsimple1.root")) {
38 gSystem->CopyFile("hsimple.root", "hsimple1.root");
39 gSystem->CopyFile("hsimple.root", "hsimple2.root");
40 }
41
42 // in an interactive ROOT session, edit the file names
43 // Target and FileList, then
44 // root > .L hadd.C
45 // root > hadd()
46
47 Target = TFile::Open( "result.root", "RECREATE" );
48
49 FileList = new TList();
50 FileList->Add( TFile::Open("hsimple1.root") );
51 FileList->Add( TFile::Open("hsimple2.root") );
52
53 MergeRootfile( Target, FileList );
54
55}
56
58
59 // cout << "Target path: " << target->GetPath() << endl;
60 TString path( (char*)strstr( target->GetPath(), ":" ) );
61 path.Remove( 0, 2 );
62
63 TFile *first_source = (TFile*)sourcelist->First();
64 first_source->cd( path );
66 //gain time, do not add the objects in the list in memory
69
70 // loop over all keys in this directory
71 TChain *globChain = 0;
72 TIter nextkey( current_sourcedir->GetListOfKeys() );
73 TKey *key, *oldkey=0;
74 while ( (key = (TKey*)nextkey())) {
75
76 //keep only the highest cycle number for each key
77 if (oldkey && !strcmp(oldkey->GetName(),key->GetName())) continue;
78
79 // read object from first source file
80 first_source->cd( path );
81 TObject *obj = key->ReadObj();
82
83 if ( obj->IsA()->InheritsFrom( TH1::Class() ) ) {
84 // descendant of TH1 -> merge it
85
86 // cout << "Merging histogram " << obj->GetName() << endl;
87 TH1 *h1 = (TH1*)obj;
88
89 // loop over all source files and add the content of the
90 // correspondant histogram to the one pointed to by "h1"
92 while ( nextsource ) {
93
94 // make sure we are at the correct directory level by cd'ing to path
95 nextsource->cd( path );
96 TKey *key2 = (TKey*)gDirectory->GetListOfKeys()->FindObject(h1->GetName());
97 if (key2) {
98 TH1 *h2 = (TH1*)key2->ReadObj();
99 h1->Add( h2 );
100 delete h2;
101 }
102
104 }
105 }
106 else if ( obj->IsA()->InheritsFrom( TTree::Class() ) ) {
107
108 // loop over all source files create a chain of Trees "globChain"
109 const char* obj_name= obj->GetName();
110
112 globChain->Add(first_source->GetName());
114 // const char* file_name = nextsource->GetName();
115 // cout << "file name " << file_name << endl;
116 while ( nextsource ) {
117
118 globChain->Add(nextsource->GetName());
120 }
121
122 } else if ( obj->IsA()->InheritsFrom( TDirectory::Class() ) ) {
123 // it's a subdirectory
124
125 cout << "Found subdirectory " << obj->GetName() << endl;
126
127 // create a new subdir of same name and title in the target file
128 target->cd();
129 TDirectory *newdir = target->mkdir( obj->GetName(), obj->GetTitle() );
130
131 // newdir is now the starting point of another round of merging
132 // newdir still knows its depth within the target file via
133 // GetPath(), so we can still figure out where we are in the recursion
135
136 } else {
137
138 // object is of no type that we know or can handle
139 cout << "Unknown object type, name: "
140 << obj->GetName() << " title: " << obj->GetTitle() << endl;
141 }
142
143 // now write the merged histogram (which is "in" obj) to the target file
144 // note that this will just store obj in the current directory level,
145 // which is not persistent until the complete directory itself is stored
146 // by "target->Write()" below
147 if ( obj ) {
148 target->cd();
149
150 // if the object is a tree, it is stored in globChain...
151 if(obj->IsA()->InheritsFrom( TTree::Class() ))
152 globChain->Merge(target->GetFile(),0,"keep");
153 else
154 obj->Write( key->GetName() );
155 }
156
157 } // while ( ( TKey *key = (TKey*)nextkey() ) )
158
159 // save modifications to target file
160 target->SaveSelf(kTRUE);
161 TH1::AddDirectory(status);
162}
bool Bool_t
Boolean (0=false, 1=true) (bool)
Definition RtypesCore.h:78
constexpr Bool_t kFALSE
Definition RtypesCore.h:109
constexpr Bool_t kTRUE
Definition RtypesCore.h:108
ROOT::Detail::TRangeCast< T, true > TRangeDynCast
TRangeDynCast is an adapter class that allows the typed iteration through a TCollection.
#define gDirectory
Definition TDirectory.h:385
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t target
R__EXTERN TSystem * gSystem
Definition TSystem.h:582
A chain is a collection of files containing TTree objects.
Definition TChain.h:33
Describe directory structure in memory.
Definition TDirectory.h:45
static TClass * Class()
A file, usually with extension .root, that stores data and code in the form of serialized objects in ...
Definition TFile.h:130
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:3801
TH1 is the base class of all histogram classes in ROOT.
Definition TH1.h:109
static TClass * Class()
static void AddDirectory(Bool_t add=kTRUE)
Sets the flag controlling the automatic add of histograms in memory.
Definition TH1.cxx:1325
virtual Bool_t Add(TF1 *h1, Double_t c1=1, Option_t *option="")
Performs the operation: this = this + c1*f1 if errors are defined (see TH1::Sumw2),...
Definition TH1.cxx:852
static Bool_t AddDirectoryStatus()
Check whether TH1-derived classes should register themselves to the current gDirectory.
Definition TH1.cxx:772
Book space in a file, create I/O buffers, to fill them, (un)compress them.
Definition TKey.h:28
virtual TObject * ReadObj()
To read a TObject* from the file.
Definition TKey.cxx:804
A doubly linked list.
Definition TList.h:38
const char * GetName() const override
Returns name of object.
Definition TNamed.h:49
Mother of all ROOT objects.
Definition TObject.h:42
virtual const char * GetName() const
Returns name of object.
Definition TObject.cxx:461
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
Write this object to the current directory.
Definition TObject.cxx:987
virtual const char * GetTitle() const
Returns title of object.
Definition TObject.cxx:506
virtual TClass * IsA() const
Definition TObject.h:248
Basic string class.
Definition TString.h:137
virtual int CopyFile(const char *from, const char *to, Bool_t overwrite=kFALSE)
Copy a file.
Definition TSystem.cxx:1356
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:1311
static TClass * Class()
TH1F * h1
Definition legend1.C:5