Hello,
I’m trying to chain multiple root files together to use in a C file and print out specific histograms. I’m mostly reusing a C file and an h file that is able to connect to one root file at a time, but I want the h file to connect to multiple root files that are copies of one another. I can include some code that only works for one root file and another code that attempts to use multiple root files. I believe that this h file is using TChain (or includes TChain) to establish the branches, but not to chain multiple root files that are copies of one another. I can answer any questions if it doesn’t seem clear right now. Thanks in advance.
-Charlie Clark
ROOT Version: 6.26/06
Platform: Ubuntu 22
Compiler: from file root_v6.26.06.Linux-ubuntu22-x86_64-gcc11.2.tar.gz
Code:
//////////////////////////////////////////////////////////
// This class has been automatically generated on
// Wed Oct 5 12:01:55 2022 by ROOT version 6.26/06
// from TTree T/Geant4 Moller Polarimetry Simulation
// found on file: results_beamOn_C16.root
//////////////////////////////////////////////////////////
#ifndef results_beamOn_C16_h
#define results_beamOn_C16_h
#include <TROOT.h>
#include <TChain.h>
#include <TFile.h>
// Header file for the classes stored in the TTree if any.
class results_beamOn_C16 {
public :
TTree *fChain; //!pointer to the analyzed TTree or TChain
Int_t fCurrent; //!current Tree number in a TChain
// Fixed size dimensions of array or collections stored in the TTree if any.
// Declaration of leaf types
Int_t evNpart;
Int_t evPid[1]; //[ev.npart]
Double_t evVx[1]; //[ev.npart]
Double_t evVy[1]; //[ev.npart]
Double_t evVz[1]; //[ev.npart]
Double_t evP[1]; //[ev.npart]
Double_t evPx[1]; //[ev.npart]
Double_t evPy[1]; //[ev.npart]
Double_t evPz[1]; //[ev.npart]
Double_t evTh[1]; //[ev.npart]
Double_t evPh[1]; //[ev.npart]
Double_t evPhcom;
Double_t evThcom;
Double_t evXs;
Double_t evAsym;
Double_t evUnpolWght;
Double_t evPolPlusWghtX;
Double_t evPolPlusWghtY;
Double_t evPolPlusWghtZ;
Double_t evPolMinusWghtX;
Double_t evPolMinusWghtY;
Double_t evPolMinusWghtZ;
Double_t evTargMom;
Int_t hitN;
Int_t hitDet[1]; //[hit.n]
Int_t hitVid[1]; //[hit.n]
Int_t hitPid[1]; //[hit.n]
Int_t hitTrid[1]; //[hit.n]
Int_t hitMtrid[1]; //[hit.n]
Int_t hitGen[1]; //[hit.n]
Double_t hitX[1]; //[hit.n]
Double_t hitY[1]; //[hit.n]
Double_t hitZ[1]; //[hit.n]
Double_t hitLx[1]; //[hit.n]
Double_t hitLy[1]; //[hit.n]
Double_t hitLz[1]; //[hit.n]
Double_t hitPx[1]; //[hit.n]
Double_t hitPy[1]; //[hit.n]
Double_t hitPz[1]; //[hit.n]
Double_t hitVx[1]; //[hit.n]
Double_t hitVy[1]; //[hit.n]
Double_t hitVz[1]; //[hit.n]
Double_t hitVdx[1]; //[hit.n]
Double_t hitVdy[1]; //[hit.n]
Double_t hitVdz[1]; //[hit.n]
Double_t hitP[1]; //[hit.n]
Double_t hitE[1]; //[hit.n]
Double_t hitM[1]; //[hit.n]
// List of branches
TBranch *b_ev_npart; //!
TBranch *b_evPid; //!
TBranch *b_evVx; //!
TBranch *b_evVy; //!
TBranch *b_evVz; //!
TBranch *b_evP; //!
TBranch *b_evPx; //!
TBranch *b_evPy; //!
TBranch *b_evPz; //!
TBranch *b_evTh; //!
TBranch *b_evPh; //!
TBranch *b_ev_phcom; //!
TBranch *b_ev_thcom; //!
TBranch *b_ev_xs; //!
TBranch *b_ev_asym; //!
TBranch *b_ev_unpolWght; //!
TBranch *b_ev_polPlusWghtX; //!
TBranch *b_ev_polPlusWghtY; //!
TBranch *b_ev_polPlusWghtZ; //!
TBranch *b_ev_polMinusWghtX; //!
TBranch *b_ev_polMinusWghtY; //!
TBranch *b_ev_polMinusWghtZ; //!
TBranch *b_ev_targMom; //!
TBranch *b_hit_n; //!
TBranch *b_hitDet; //!
TBranch *b_hitVid; //!
TBranch *b_hitPid; //!
TBranch *b_hitTrid; //!
TBranch *b_hitMtrid; //!
TBranch *b_hitGen; //!
TBranch *b_hitX; //!
TBranch *b_hitY; //!
TBranch *b_hitZ; //!
TBranch *b_hitLx; //!
TBranch *b_hitLy; //!
TBranch *b_hitLz; //!
TBranch *b_hitPx; //!
TBranch *b_hitPy; //!
TBranch *b_hitPz; //!
TBranch *b_hitVx; //!
TBranch *b_hitVy; //!
TBranch *b_hitVz; //!
TBranch *b_hitVdx; //!
TBranch *b_hitVdy; //!
TBranch *b_hitVdz; //!
TBranch *b_hitP; //!
TBranch *b_hitE; //!
TBranch *b_hitM; //!
results_beamOn_C16(TTree *tree=0);
virtual ~results_beamOn_C16();
virtual Int_t Cut(Long64_t entry);
virtual Int_t GetEntry(Long64_t entry);
virtual Long64_t LoadTree(Long64_t entry);
virtual void Init(TTree *tree);
virtual void Loop();
virtual Bool_t Notify();
virtual void Show(Long64_t entry = -1);
};
#endif
#ifdef results_beamOn_C16_cxx
results_beamOn_C16::results_beamOn_C16(TTree *tree) : fChain(0)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
if (tree == 0) {
TFile *f = (TFile*)gROOT->GetListOfFiles()->FindObject("results_beamOn_C16.root");
if (!f || !f->IsOpen()) {
f = new TFile("results_beamOn_C16.root");
}
f->GetObject("T",tree);
}
Init(tree);
}
results_beamOn_C16::~results_beamOn_C16()
{
if (!fChain) return;
delete fChain->GetCurrentFile();
}
Int_t results_beamOn_C16::GetEntry(Long64_t entry)
{
// Read contents of entry.
if (!fChain) return 0;
return fChain->GetEntry(entry);
}
Long64_t results_beamOn_C16::LoadTree(Long64_t entry)
{
// Set the environment to read one entry
if (!fChain) return -5;
Long64_t centry = fChain->LoadTree(entry);
if (centry < 0) return centry;
if (fChain->GetTreeNumber() != fCurrent) {
fCurrent = fChain->GetTreeNumber();
Notify();
}
return centry;
}
void results_beamOn_C16::Init(TTree *tree)
{
// The Init() function is called when the selector needs to initialize
// a new tree or chain. Typically here the branch addresses and branch
// pointers of the tree will be set.
// It is normally not necessary to make changes to the generated
// code, but the routine can be extended by the user if needed.
// Init() will be called many times when running on PROOF
// (once per file to be processed).
// Set branch addresses and branch pointers
if (!tree) return;
fChain = tree;
fCurrent = -1;
fChain->SetMakeClass(1);
fChain->SetBranchAddress("evNpart", &evNpart, &b_ev_npart);
fChain->SetBranchAddress("evPid", evPid, &b_evPid);
fChain->SetBranchAddress("evVx", evVx, &b_evVx);
fChain->SetBranchAddress("evVy", evVy, &b_evVy);
fChain->SetBranchAddress("evVz", evVz, &b_evVz);
fChain->SetBranchAddress("evP", evP, &b_evP);
fChain->SetBranchAddress("evPx", evPx, &b_evPx);
fChain->SetBranchAddress("evPy", evPy, &b_evPy);
fChain->SetBranchAddress("evPz", evPz, &b_evPz);
fChain->SetBranchAddress("evTh", evTh, &b_evTh);
fChain->SetBranchAddress("evPh", evPh, &b_evPh);
fChain->SetBranchAddress("evPhcom", &evPhcom, &b_ev_phcom);
fChain->SetBranchAddress("evThcom", &evThcom, &b_ev_thcom);
fChain->SetBranchAddress("evXs", &evXs, &b_ev_xs);
fChain->SetBranchAddress("evAsym", &evAsym, &b_ev_asym);
fChain->SetBranchAddress("evUnpolWght", &evUnpolWght, &b_ev_unpolWght);
fChain->SetBranchAddress("evPolPlusWghtX", &evPolPlusWghtX, &b_ev_polPlusWghtX);
fChain->SetBranchAddress("evPolPlusWghtY", &evPolPlusWghtY, &b_ev_polPlusWghtY);
fChain->SetBranchAddress("evPolPlusWghtZ", &evPolPlusWghtZ, &b_ev_polPlusWghtZ);
fChain->SetBranchAddress("evPolMinusWghtX", &evPolMinusWghtX, &b_ev_polMinusWghtX);
fChain->SetBranchAddress("evPolMinusWghtY", &evPolMinusWghtY, &b_ev_polMinusWghtY);
fChain->SetBranchAddress("evPolMinusWghtZ", &evPolMinusWghtZ, &b_ev_polMinusWghtZ);
fChain->SetBranchAddress("evTargMom", &evTargMom, &b_ev_targMom);
fChain->SetBranchAddress("hitN", &hitN, &b_hit_n);
fChain->SetBranchAddress("hitDet", hitDet, &b_hitDet);
fChain->SetBranchAddress("hitVid", hitVid, &b_hitVid);
fChain->SetBranchAddress("hitPid", hitPid, &b_hitPid);
fChain->SetBranchAddress("hitTrid", hitTrid, &b_hitTrid);
fChain->SetBranchAddress("hitMtrid", hitMtrid, &b_hitMtrid);
fChain->SetBranchAddress("hitGen", hitGen, &b_hitGen);
fChain->SetBranchAddress("hitX", hitX, &b_hitX);
fChain->SetBranchAddress("hitY", hitY, &b_hitY);
fChain->SetBranchAddress("hitZ", hitZ, &b_hitZ);
fChain->SetBranchAddress("hitLx", hitLx, &b_hitLx);
fChain->SetBranchAddress("hitLy", hitLy, &b_hitLy);
fChain->SetBranchAddress("hitLz", hitLz, &b_hitLz);
fChain->SetBranchAddress("hitPx", hitPx, &b_hitPx);
fChain->SetBranchAddress("hitPy", hitPy, &b_hitPy);
fChain->SetBranchAddress("hitPz", hitPz, &b_hitPz);
fChain->SetBranchAddress("hitVx", hitVx, &b_hitVx);
fChain->SetBranchAddress("hitVy", hitVy, &b_hitVy);
fChain->SetBranchAddress("hitVz", hitVz, &b_hitVz);
fChain->SetBranchAddress("hitVdx", hitVdx, &b_hitVdx);
fChain->SetBranchAddress("hitVdy", hitVdy, &b_hitVdy);
fChain->SetBranchAddress("hitVdz", hitVdz, &b_hitVdz);
fChain->SetBranchAddress("hitP", hitP, &b_hitP);
fChain->SetBranchAddress("hitE", hitE, &b_hitE);
fChain->SetBranchAddress("hitM", hitM, &b_hitM);
Notify();
}
Bool_t results_beamOn_C16::Notify()
{
// The Notify() function is called when a new file is opened. This
// can be either for a new TTree in a TChain or when when a new TTree
// is started when using PROOF. It is normally not necessary to make changes
// to the generated code, but the routine can be extended by the
// user if needed. The return value is currently not used.
return kTRUE;
}
void results_beamOn_C16::Show(Long64_t entry)
{
// Print contents of entry.
// If entry is not specified, print current entry
if (!fChain) return;
fChain->Show(entry);
}
Int_t results_beamOn_C16::Cut(Long64_t entry)
{
// This function may be called from Loop.
// returns 1 if entry is accepted.
// returns -1 otherwise.
return 1;
}
#endif // #ifdef results_beamOn_C16_cxx
Code that attempts to anaylize multiple files:
#ifdef ScatteringAngle_cxx
ScatteringAngle::ScatteringAngle(TTree *tree) : fChain(0)
{
// if parameter tree is not specified (or zero), connect the file
// used to generate this class and read the Tree.
Int_t n = 2;
TFile * f[n];
for (Int_t i = 0; i < n; i++){
if (tree == 0) {
TString filename = Form("beam_run_%d.root",i+1);
f[i] = (TFile*)gROOT->GetListOfFiles()->FindObject(filename);
if (!f[i] || !f[i]->IsOpen()) {
f[i] = new TFile(filename);//("moller_run.root");
}
f[i]->GetObject("T",tree);
}
/*TFile *f2 = (TFile*)gROOT->GetListOfFiles()->FindObject("beam_run_2.root");
if (!f2 || !f2->IsOpen()) {
f2 = new TFile("beam_run_2.root");//("moller_run.root");
}
f2->GetObject("T",tree);*/
}
Init(tree);
}
This code above tries to chain multiple files together under the function name fChain. Is it possible that I need TChain somewhere for this to look at multiple root files?