TFile and TTree issue

Hello,

I am having one problem that I cannot solve. I have one TTree called extraVariables and I have one function that would create a TFile and write it with this TTree, and I also have a function that use this TTree to draw a TH1F.

This is the function that writes the TTree:

391 HypoBase::CODE T2CaCommon::WriteTree(const std::string &fileName){ 392 393 394 TFile file(fileName.c_str(), "recreate"); 395 file.Add(extraVariables); 396 file.Write(); 397 extraVariables = static_cast<TTree*>(file.Remove(extraVariables)); 398 file.Close(); 399 400 401 return HypoBase::OK; 402 403 }

This is the function that draw the TH1:

301 HypoBase::CODE T2CaCommon::DrawCutCounter(const std::string &opt){ 302 303 TH1I *hCuts = new TH1I("CutCounter", "L2Calo Hypo Passed Cuts; Cut", 11, -1.5, 9.5); 304 305 int nEntries = static_cast<int>(extraVariables->GetEntries()); 306 307 for(int i=0; i<nEntries;++i){ 308 extraVariables->GetEntry(i); 309 for(size_t j=0; j<t2CaAns->size();++j){ 310 switch (t2CaAns->at(j)){ 311 case T2CaCommon::AP: 312 hCuts->Fill(T2CaCommon::c_F1); 313 case T2CaCommon::c_F1: 314 hCuts->Fill(T2CaCommon::et_HAD); 315 case T2CaCommon::et_HAD: 316 hCuts->Fill(T2CaCommon::et_EM); 317 case T2CaCommon::et_EM: 318 hCuts->Fill(T2CaCommon::eRATIO); 319 case T2CaCommon::eRATIO: 320 hCuts->Fill(T2CaCommon::rCORE); 321 case T2CaCommon::rCORE: 322 hCuts->Fill(T2CaCommon::dPHI); 323 case T2CaCommon::dPHI: 324 hCuts->Fill(T2CaCommon::dETA); 325 case T2CaCommon::dETA: 326 hCuts->Fill(T2CaCommon::TRIG); 327 hCuts->Fill(T2CaCommon::LVL2E); 328 break; 329 default: 330 return HypoBase::ERROR; 331 } 332 } 333 } 334 335 hCuts->GetXaxis()->SetBinLabel(1,"Input"); 336 hCuts->GetXaxis()->SetBinLabel(2,"has one TrigEMCluster"); 337 hCuts->GetXaxis()->SetBinLabel(3,"#Delta #eta L2-L1"); 338 hCuts->GetXaxis()->SetBinLabel(4,"#Delta #phi L2-L1"); 339 hCuts->GetXaxis()->SetBinLabel(5,"rCore"); 340 hCuts->GetXaxis()->SetBinLabel(6,"eRatio"); 341 hCuts->GetXaxis()->SetBinLabel(7,"E_{T}^{EM}"); 342 hCuts->GetXaxis()->SetBinLabel(8,"E_{T}^{Had}"); 343 hCuts->GetXaxis()->SetBinLabel(9,"f_{1}"); 344 hCuts->SetEntries(hCuts->GetBinContent(1)); 345 hCuts->SetLineColor(color); 346 hCuts->Draw(opt.c_str()); 347 return HypoBase::OK; 348 349 }

Well, if I use the DrawCutCounter first it will be all right, it will do what it is supposed to do, but if I run WriteTree and then run DrawCutCounter I will get a segmentation fault x(. I tried many different things but none were successful. What am I missing?

Thank you,

Werner.

In your function

HypoBase::CODE T2CaCommon::WriteTree(const std::string &fileName){ The TFile object goes out of scope, the simplest solution is to replace

TFile file(fileName.c_str(), "recreate"); by

TFile *file = new TFile(fileName.c_str(), "recreate");
Rene

Hello Rene,

I tried what you told me but it didnt work, still it has put me on the way for the answer. I discovered that the problem is closing the file. In the end I created a variable called TFile *file in my class, and my WriteTree function is now like this:

391 HypoBase::CODE T2CaCommon::WriteTree(const std::string &fileName){ 392 393 if (file){ 394 file->Close(); 395 delete file; 396 file = 0; 397 } 398 file = new TFile(fileName.c_str(), "recreate"); 399 file->Add(extraVariables); 400 file->Write(); 401 extraVariables = static_cast<TTree*>(file->Remove(extraVariables)); 402 403 return HypoBase::OK; 404 405 }

And on destructor I would do:

[quote]160 if (file != 0){
161 file->Close();
162 delete file;
163 }[/quote]

Is this the only way? This is not really necessary, but I would like only to allocate memory for the TFile WriteTree and then delete it as soon as I wrote it. Is it possible?

Thank you,

Werner.

Hi,

TTree are designed to be attached to a ‘live’ TFile object so that you do not need to load all the data in memory but can read it from the file when needed (This is absolutely necessary for very large data set).

If you data set is small and can fit comfortably in memory you can load all the baskets (tree->LoadBaskets()) and detach the TTree (tree->SetDirectory(0)) from the TFile.

However, it strikes me that if you want to delete the TFile early, the intend must be that you want to save memory … however by needing to load all the TTree data at once, you accomplish the opposite (i.e. increase the memory requirement).

Cheers,
Philippe.

Hello,

that was what I was missing.

So if I create a TFile on the more basic class everything that I create will be inside this TFile. If I close the TFile early root will search for data inside it and wont be able to find it because he is still on that directory and I need to change it, I see. All right, if I want only to write the TTree I would do TTree::Write() and I can still be on the folder.

I was thinking like a C file, that I would create it, write it and than close it since I wouldnt need it anymore.

Sorry for the misunderstood,

Werner.