Open files in a directory with a for loop

Sorry, I forgot to copy that part of code. Thanks for guidance. Ok. I have created trees with differnet names in the same .root file.

My code is as below:

TFile *f = new TFile("staff.root","RECREATE");
TTree *tree ;
FILE *fp;
char *token[20];

void list()
{
std::vector<std::string> lista;

TString path = gSystem->UnixPathName(gInterpreter->GetCurrentMacroName());
path.ReplaceAll("ToBeDeleted.C", "");
path.ReplaceAll("/./", "/");
TSystemDirectory dire(path+"2ndWeekNov-MPPCwLED/", path+"2ndWeekNov-MPPCwLED/");

TList *files = dire.GetListOfFiles();
TIter next(files);
TSystemFile *file;
TString fname;
while((file = (TSystemFile*)next())) {
fname = file->GetName();
if(file->IsDirectory()) continue;
lista.push_back(fname.Data());
}
for(vector<string>::iterator it = lista.begin(); it != lista.end(); it++)
cout << *it << endl;

for(int i = 0;i<lista.size();i++)
{
char *filename;
filename = lista.at(i).c_str()); //What to do here? Becoz for fopen it should not be a Array.
fp = fopen(filename, "r");
tokenOfFileName();
createTreeName();
assignTreeData();
}
void tokenOfFileName()
{         
         int count = 0;
	 token[0] = strtok(filename, "_.");
	   while (token[count] != NULL)
           {
		count++;
		token[count] = strtok (NULL, "_.");
	   }
		for (int i = 0; i <= count -1 ; i++)
		{
			printf ("%s \n", token[i]);
		}
}

void createTreeName()   
{
    treeName = strcat(token[0],token[3]);    
        cout << "TreeName : " << treeName << endl;
    tree = new TTree(treeName,"Tree");  
}

void assignTreeData()
{ .....
while (fgets(&line[0],127,fp)) {
..... sscanf();
tree->Fill();
}

tree->Write();
rootf->Write();
fclose(fp);   // Here I am trying to close the DataFile
}

Still have the same problem. Root is terminating automatically.

I think you are improperly using “strcat” in “createTreeName” (the “treeName” will be equal to the “token[0]”), unless you really know what you are doing there (see “man strcat” for details). One cannot check another places as it’s not clear what the “filename” in “tokenOfFileName” nor the “line[0]” in “createTreeName” are.
I believe you should stop using C strings (i.e. “chat *”, “char *[]”, …) and rewrite your code so that it solely uses C++ strings (i.e. std::string and/or TString).
Also, always try to pre-compile your source code using ACLiC (the compiler will find many possible source code bugs) … root [0] .L MySourceCode.cxx++

Hello,

Thanks for the guidance. I made changes to my program and its working. But I am facing another problem. I am creating one .root file and under .root file trying to create many trees. But its only creating 2 trees instead I wants to create many trees. One tree having 20480 records of data each.

Is more number of records in data file affecting to create many trees under one .root file ? Its not showing any error or warnings.

Thanks in advance.

Make sure that these trees have unique (unambiguous) “names” (their “titles” can be the same, though) and make sure that for every tree you call “MyTree->Write();”.

Thanks. Yes, I am assigning unique name to each tree and also doing MyTree->Write(). I am trying to read data from .data files to fill a tree. But it works for only two .data files.
Its not working for more than two data files. Means its creating only 2 trees for any .data file.

It’s difficult to say anything without the source code.
You can try one more thing. Add a line “MyRootFile->cd();” in two places:

  1. directly before you call “MyTree = new TTree(…);”
  2. directly before you call “MyTree->Write();”

I did some modifications to the original code but I am having a problem adding the histogram “hist”. I can see the correct histogram for each file but I was expecting to see the sum of all of them since I am using >>+. In fact the >> is not working at all because when the program finish, the histogram “hist” is empty.
How can I fix this? Thanks

void Plot(const Char_t *dirname= "out/", const Char_t *ext=".root") { TH1D *hist = new TH1D("hist","Reconstructed mass",500,0.45,0.55); Int_t count=0; TSystemDirectory dir(dirname, dirname); TList *files = dir.GetListOfFiles(); if (files) { TSystemFile *file; TString fname; TIter next(files); while ((file=(TSystemFile*)next())) { fname = file->GetName(); if (!file->IsDirectory() && fname.EndsWith(ext)) { //cout << fname.Data() << endl; Char_t eachfile[50]; sprintf(eachfile,"%s%s",dirname,fname.Data()); //cout << eachfile << endl; TFile f(eachfile); TTree *vertex = (TTree*)f.Get("vtx"); if (!vertex) {cout<< "No Vertex" << endl; continue;} vertex->Draw("Mass>>+hist",""); count++; if (count%10==0) cout << "Files: " << count << endl; gPad->Update(); } } } }

I’m afraid that the “logic” of the tree.Draw(“something>>[+]histo”) is a bit broken these days (well, I’ve been trying to “get it fixed”).

Try this “brutal fix”: // ... if (!vertex) {cout<< "No Vertex" << endl; continue;} hist->SetDirectory(gDirectory); // "attach" it to the current root file vertex->Draw("Mass>>+hist",""); hist->SetDirectory(gROOT); // "detach" it from the current root file count++; // ... or that one (note: instead of f.FindObject you can also try gPad->FindObject): // ... if (!vertex) {cout<< "No Vertex" << endl; continue;} vertex->Draw("Mass>>+hist",""); delete hist; // get rid of the old histogram hist = ((TH1D*)(f.FindObject("hist"))); // resume the new one hist->SetDirectory(gROOT); // "detach" it from the current root file count++; // ...

The second solution does not work, but the first one does the job. Thanks for the help

Hello, I have used this code from a long time without any problems, but recently I got something not working. All the files in the folder I read are label Hist_1.root, Hist_2.root, Hist_3.root … Before the files were being read in order (1,2,3,4,…), but now the are read in a random order. I tried in both linux and Mac, and Root 6 and 5 but it is not reading the files in order. Hope somebody knows what happen.