How to write / read TMultiGraph in the tree?

Hello!

Could you help me?
I want to read tree and add TMultiGraph in the TObjArray.
But TMultiGraph don’t have copy constructor.
How to overcome this promlem?

void ReadTree()
{
	TObjArray Hlist(0);
	Hlist.SetOwner(kTRUE);

	TFile f("D:\\Data_work\\tree.root");
	TTree* t;
	f.GetObject("t1", t);

	TMultiGraph* graph = new TMultiGraph();

	t->SetBranchAddress("gr", &graph);

	for (int i = 0; i < t->GetEntries(); ++i)
	{
		t->GetEntry(i);
		Hlist.Add(new TMultiGraph(*graph)); // error
	}

	TFile ofile_Hlist("D:\\Data_work\\graphs.root", "RECREATE");
	Hlist.Write();
	ofile_Hlist.Close();
}

And also: is this code to write TMultiGraph in the tree correct?

[code]void CreateTree()
{
TTree tree(“t1”, “Parser tree”);

TMultiGraph *gr = new TMultiGraph();
TGraphErrors *gr_1 = new TGraphErrors();
TGraphErrors *gr_2 = new TGraphErrors();

tree.Branch("gr", "TMultiGraph", &gr, 128000, 0);

//loop to create 5 TMultiGraph
for (int j = 0; j < 5; j++)
{
	//fill graphs
	for (int i = 0; i < 10; ++i)
	{
		gr_1->SetPoint(i, i + gRandom->Uniform(-.5, .5), gRandom->Uniform(-.5, .5));
		gr_2->SetPoint(i, i + gRandom->Uniform(-.1, .1), gRandom->Uniform(-.1, .1));
	}

	gr->Add(gr_1);
	gr->Add(gr_2);

	tree.Fill();

	gr->Clear();
	gr_1->Clear();
	gr_2->Clear();
}

TFile f("D:\\Data_work\\tree.root", "recreate");
tree.Write();

}[/code]

I have read here root.cern.ch/root/htmldoc/guide … ding-trees , but have not found the similiar examples.

Thank you in advance.

The copy constructor and the assignment operator are ‘protected’ for TMultiGraph. I would guess for very good reasons, which I do not know at this moment. This makes impossible to put them into a TTree or a std::vector for instance. Can you perhaps workaround and put in the TTree a vector instead of a TMultiGraph?

Hello!

We have found this solution:

	for (int i = 0; i < t->GetEntries(); ++i)
	{
		t->GetEntry(i);		
		Hlist.Add(graph->Clone());
	}

root.cern.ch/root/roottalk/roottalk04/0422.html

But I don’t understand how to realize more complex case of writing.

For example, this is work example of simple writing:

void CreateTree_work()
{
	TTree tree("t1", "Parser tree");

	TMultiGraph *gr = new TMultiGraph();
	TGraphErrors *gr_1 = new TGraphErrors();
	TGraphErrors *gr_2 = new TGraphErrors();

	gr->Add(gr_1);
	gr->Add(gr_2);

	tree.Branch("gr", "TMultiGraph", &gr, 128000, 0);

	TFile f("D:\\Data_work\\tree.root", "recreate");

	//loop to create 5 TMultiGraph
	for (int j = 0; j < 5; j++)
	{

		
		//fill graphs
		for (int i = 0; i < 10; ++i)
		{
			gr_1->SetPoint(i, i + gRandom->Uniform(-.5, .5), gRandom->Uniform(-.5, .5));
			gr_2->SetPoint(i, i + gRandom->Uniform(-.1, .1), gRandom->Uniform(-.1, .1));
		}



		tree.Fill();
		//gr->Write();

	}
	
	tree.Write();
}

But how to realize case when I have to create new graphs in the loop?
How to transfer the pointers of new graphs properly?

void CreateTree_test()
{
	TTree tree("t1", "Parser tree");

	TMultiGraph *gr = new TMultiGraph();
	TGraphErrors *gr_1 = new TGraphErrors();
	TGraphErrors *gr_2 = new TGraphErrors();

	gr->Add(gr_1);
	gr->Add(gr_2);

	tree.Branch("gr", "TMultiGraph", &gr, 128000, 0);

	TFile f("D:\\Data_work\\tree.root", "recreate");

	//loop to create 5 TMultiGraph
	for (int j = 0; j < 5; j++)
	{
		TGraphErrors *gr_a = new TGraphErrors();
		TGraphErrors *gr_b = new TGraphErrors();

		//fill graphs
		for (int i = 0; i < 10; ++i)
		{
			gr_a->SetPoint(i, i + gRandom->Uniform(-.5, .5), gRandom->Uniform(-.5, .5));
			gr_b->SetPoint(i, i + gRandom->Uniform(-.1, .1), gRandom->Uniform(-.1, .1));
		}

		//gr_1 = new TGraphErrors(*gr_a); //don't work
		//gr_2 = new TGraphErrors(*gr_b);

		//gr_1 = (TGraphErrors *)gr_a->Clone(); //don't work
		//gr_2 = (TGraphErrors *)gr_b->Clone();

		//gr_1->Copy(gr_a); // meybe I have to use Copy()

		tree.Fill();
		//gr->Write();

	}

	tree.Write();
}

Could you help me?
Thank you in advance.

I have found solution :slight_smile:

void CreateTree_test()
{
	TTree tree("t1", "Parser tree");

	TMultiGraph *gr = new TMultiGraph();
	TGraphErrors *gr_1 = new TGraphErrors();
	TGraphErrors *gr_2 = new TGraphErrors();

	gr->Add(gr_1);
	gr->Add(gr_2);

	tree.Branch("gr", "TMultiGraph", &gr, 128000, 0);

	

	//loop to create 5 TMultiGraph
	for (int j = 0; j < 5; j++)
	{
		TGraphErrors *gr_a = new TGraphErrors();
		TGraphErrors *gr_b = new TGraphErrors();

		//fill graphs
		for (int i = 0; i < 10; ++i)
		{
			gr_a->SetPoint(i, i + gRandom->Uniform(-.5, .5), gRandom->Uniform(-.5, .5));
			gr_b->SetPoint(i, i + gRandom->Uniform(-.1, .1), gRandom->Uniform(-.1, .1));
		}

		*gr_1 = *gr_a; //work
		*gr_2 = *gr_b;

		tree.Fill();

		delete gr_a;
		delete gr_b;

	}

	TFile f("D:\\Data_work\\tree.root", "recreate");
	tree.Write();
}