Hello!
I have a lot of events (> 100 000).
I want to calculate some values (integral, for example), draw graphs and save all this information in a tree.
Individual tree for each event.
If I write one tree in one file I waste a lot of time for open and close operations.
So, the better solution to save several trees in one file.
Previously, I used tree.Write()
.
Now, as I understand (TTree.Write() vs. TFile.Write() ), I have to use tfile.Write()
.
But I get this message: Warning in <TFile::Write>: file not opened in write mode
.
And my file is empty.
My code:
#include <iostream>
#include <string>
#include <iomanip>
#include "TGraph.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TROOT.h"
#include "TRandom.h"
using namespace std;
int main(int argc, char *argv[])
{
TFile f_tree;
string s_output_file = "/home/darkside/Vlad_Programs/test.root";
const int events_per_file = 2;
const int n_events = 2;
const int samp_per_event = 100;
vector<double> xv;
for (int i = 0; i < samp_per_event; ++i)
{
xv.push_back(i);
}
TRandom rnd;
for(int file_i = 0; file_i < n_events; file_i++)
{
vector<double> yv;
for (int i = 0; i < samp_per_event; ++i)
{
yv.push_back( rnd.Rndm() );
}
//I want to save "events_per_file" events per one file
if(file_i % events_per_file == 0) f_tree.Open(s_output_file.c_str(), "RECREATE");
TTree tree("t1", "Tree with result");
double just_some_value = file_i;
tree.Branch("just_some_value", &just_some_value, "just_some_value/D");
TCanvas canv("c", "c", 0, 0, 1900, 1000);
tree.Branch("canvas_tr", "TCanvas", &canv);
TGraph graph_ch1(samp_per_event, &xv[0], &yv[0]);
graph_ch1.Draw();
tree.Fill();
if(file_i % events_per_file == 0) f_tree.Write();
if(file_i % events_per_file == 0) f_tree.Close();
}
cout << "all is ok" << endl;
return 0;
}
Could you help me?
Thank you in advance.
Best regards, Vladislav.
ferhue
October 28, 2016, 12:38pm
2
Why do you want to have one tree for each event? Put everything in the same tree. Call Fill once per event.
couet
October 28, 2016, 1:03pm
3
The following version of your program does not produce the warning.
#include <iostream>
#include <string>
#include <iomanip>
#include "TGraph.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TROOT.h"
#include "TRandom.h"
using namespace std;
void vla()
{
TFile *f_tree;
string s_output_file = "/home/darkside/Vlad_Programs/test.root";
const int events_per_file = 2;
const int n_events = 2;
const int samp_per_event = 100;
vector<double> xv;
for (int i = 0; i < samp_per_event; ++i)
{
xv.push_back(i);
}
TRandom rnd;
for(int file_i = 0; file_i < n_events; file_i++)
{
vector<double> yv;
for (int i = 0; i < samp_per_event; ++i)
{
yv.push_back( rnd.Rndm() );
}
//I want to save "events_per_file" events per one file
if(file_i % events_per_file == 0) {
f_tree = new TFile(s_output_file.c_str(), "RECREATE");
}
TTree tree("t1", "Tree with result");
double just_some_value = file_i;
tree.Branch("just_some_value", &just_some_value, "just_some_value/D");
TCanvas canv("c", "c", 0, 0, 1900, 1000);
tree.Branch("canvas_tr", "TCanvas", &canv);
TGraph graph_ch1(samp_per_event, &xv[0], &yv[0]);
graph_ch1.Draw();
tree.Fill();
if(file_i % events_per_file == 0) f_tree->Write();
if(file_i % events_per_file == 0) f_tree->Close();
}
}
ferhue
October 28, 2016, 1:04pm
4
Anyway, here a modified version of your code:
#include <iostream>
#include <string>
#include <iomanip>
#include "TGraph.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TROOT.h"
#include "TRandom.h"
using namespace std;
int test()
{
string s_output_file = "test.root";
const int events_per_file = 2;
const int n_events = 2;
const int samp_per_event = 100;
vector<double> xv;
for (int i = 0; i < samp_per_event; ++i)
{
xv.push_back(i);
}
TRandom rnd;
TFile* f_tree = NULL;
TTree* tree = NULL;
for(int file_i = 0; file_i < n_events; file_i++)
{
double just_some_value = file_i;
vector<double> yv;
for (int i = 0; i < samp_per_event; ++i)
{
yv.push_back( rnd.Rndm() );
}
TCanvas canv("c", "c", 0, 0, 1900, 1000);
TGraph graph_ch1(samp_per_event, &xv[0], &yv[0]);
graph_ch1.Draw();
if(file_i % events_per_file == 0)
{
f_tree = TFile::Open(s_output_file.c_str(), "RECREATE");
tree = new TTree("t1", "Tree with result");
tree->Branch("just_some_value", &just_some_value, "just_some_value/D");
tree->Branch("canvas_tr", "TCanvas", &canv);
}
//I want to save "events_per_file" events per one file
tree->Fill();
if(file_i % events_per_file == events_per_file-1)
{
f_tree->Write();
f_tree->Close();
delete f_tree;
f_tree = NULL;
tree = NULL;
}
}
if(f_tree)
{
f_tree->Write();
f_tree->Close();
delete f_tree;
f_tree = NULL;
tree = NULL;
}
cout << "all is ok" << endl;
return 0;
}
I am not specialist in root trees. May be your variant is better.
In any case, how to save root tree?
As I understand your variant is to put TTree tree("t1", "Tree with result");
outside the loop.
This code (one tree with per file) has the same error:
#include <iostream>
#include <string>
#include <iomanip>
#include "TGraph.h"
#include "TFile.h"
#include "TRandom.h"
#include "TTree.h"
#include "TCanvas.h"
#include "TROOT.h"
#include "TRandom.h"
using namespace std;
int main(int argc, char *argv[])
{
TFile f_tree;
TTree tree("t1", "Tree with result");
string s_output_file = "/home/darkside/Vlad_Programs/test.root";
const int events_per_file = 2;
const int n_events = 2;
const int samp_per_event = 100;
vector<double> xv;
for (int i = 0; i < samp_per_event; ++i)
{
xv.push_back(i);
}
TRandom rnd;
for(int file_i = 0; file_i < n_events; file_i++)
{
vector<double> yv;
for (int i = 0; i < samp_per_event; ++i)
{
yv.push_back( rnd.Rndm() );
}
//I want to save "events_per_file" events per one file
if(file_i % events_per_file == 0) f_tree.Open(s_output_file.c_str(), "RECREATE");
double just_some_value = file_i;
tree.Branch("just_some_value", &just_some_value, "just_some_value/D");
TCanvas canv("c", "c", 0, 0, 1900, 1000);
tree.Branch("canvas_tr", "TCanvas", &canv);
TGraph graph_ch1(samp_per_event, &xv[0], &yv[0]);
graph_ch1.Draw();
tree.Fill();
if(file_i % events_per_file == 0) f_tree.Write();
if(file_i % events_per_file == 0) f_tree.Close();
}
cout << "all is ok" << endl;
return 0;
}
couet
October 28, 2016, 1:08pm
6
The version I posted does not have the error
Many thanks!
When I was writing my post you sent the answer.
Dear ferhue, many thanks for your help!
I had also several errors in my code, but you fixed them.
1 Like