How to save TGraph in TTree

hi,

I would save for each entry in my TTree some numbers and a graph with x-axys from 0 to MAXNUMBER and y-axys with the numbers stored in an array of usigned int from the 12° numbers to MAXNUMBER+12

how should I do?

thanks
Antonio

Hi Antonio,

why not saving directly 2 vectors or arrays? This could be more efficient and it is straightforward to re-build a tgraph once the coordinates are available:
root.cern.ch/root/html/TGraph.ht … h:TGraph@3

Cheers,
Danilo

hi Danilo,

generally because a Graph can be seen directly also browsing the TTree and because I though it would be very easy (but I do not know ROOT so much)

if I would save those arrays how I should declare them and save them?

thanks a lot
Antonio

Hi Antonio,

you can dive into examples using ttrees here:
root.cern.ch/root/html/tutorials/tree/index.html

and have a look to the primer and users guide here:
root.cern.ch/drupal/content/users-guide#UG

to start: root.cern.ch/root/htmldoc/guides … l-analysis

Cheers,
Danilo

thanks for the links … I will browse into them …

hi,

I still have problems with this issue on TGraph

I declare a TGraph with

TGraph *graph = new TGraph();

then a declare the branches in TTree with

	tree->Branch("graph","TGraph",&graph,32000,0);

and then when I manage the data I create two array x and y and I tried to use some instructions to pass them to the TGraph without any good results (when I lunch the code it gives me Illegal instruction: 4

please help me

Hi,

is the tgraph pointer in the correct scope? Are you filling the branch in a function?

hi,

I declare the TGraph and the TTree and the branch with the instruction I wrote above then I open a do{}while() loop

and in the loop I create fill two arrays x and y ( I print them and they are correct)

then I wrote:

graph->DrawGraph((int)sample_length,x,y);
tree->Fill();

but i did not work

I also tried with graph = new TGraph(sample_length,x,y)

but also that did not work

I do not know how to proceed … do you have same examples to find the correct way.

unfortunately I am not an expert but the DAQ I bought uses ROOT so I have to fight with it

Hi,

maybe you can post the minimal reproducer of your issue in order to spot the problem.

Cheers,
Danilo

i do not understand what you mean

I can post the code

[code]cout << “aperto TFILE e creato TTree” << endl;
TFile f(“data60Co2Riv.root”,“RECREATE”);
TTree *tree = new TTree(“tree”, “sorted_signals”);
cout << “aperto TFILE e creato TTree” << endl;

	char filename[128]  ;
	unsigned int i_file;
	unsigned int i_ch_no;

	int channel;
	double time;
	double energy;

	TGraph *graph = new TGraph();
	//TNtuple *ntuple = new TNtuple("ntuple","dati evento","channel:time:energy");
	int x[MAX_NUMBER_LWORDS_64MBYTE];
	int y[MAX_NUMBER_LWORDS_64MBYTE];
	for(int i = 0 ; i < MAX_NUMBER_LWORDS_64MBYTE ; i++){
		x[i] = i;
		y[i] = 0;
	}

	//strutturo il TTre
	tree->Branch("channel",&channel,"channel/I");
	tree->Branch("time",&time,"time/D");
	tree->Branch("energy",&energy,"energy/D");
	//tree->Branch("ntuple","TNtuple",&ntuple,32000,0);
	tree->Branch("graph","TGraph",&graph,32000,0);


	bank_buffer_counter = 8 ;
	for (i_file=0; i_file<1; i_file++) {
		sprintf(filename,"/Users/antonio/Documents/Work/Experiments/DAQ_struck/dati/60Co_2Riv/sis3316_test_data_%d_testTime_Anto.dat",i_file ) ;
		printf("%s\n",filename) ;
		gl_FILE_DataEvenFilePointer = fopen(filename,"rb") ;
		//if (gl_FILE_DataEvenFilePointer == NULL) {
			//		printf("gl_FILE_DataEvenFilePointer == NULL \n");
				//	return -1;
				//}

		do {


			bla bla bla something working

		} while(valid_BankBufferHeader_valid_flag == 1 ) ;

		fclose(gl_FILE_DataEvenFilePointer);
		printf("file closed and finished   \n");
		bank_buffer_counter++;
		i_event1 = 0;
		i_event2 = 0;

		while(1){

			if((i_event1 < event_1) && (i_event2 < event_2)){

			// calcolo tempo ch 1
			bla bla boa something working

			if(ch1_double_timestamp_ns < ch2_double_timestamp_ns){
				//scrivo il primo canale sul TTre
				channel = (int)((gl_ch_data_1[0] & 0xfff0) >> 4);
				time = ch1_double_timestamp_ns_tot + ch1_double_timestamp_ns/1.e9 ; // time in seconds
				energy = ((double)gl_ch_data_1[i_event1*(event_length) + (header_length - 2)] - (double)gl_ch_data_1[i_event1*(event_length) + (header_length - 3)]) / 10.;
				unsigned short* ushort_adc_buffer_ptr;
				ushort_adc_buffer_ptr = (unsigned short*) &gl_ch_data_1[i_event1*(event_length) + header_length];
				cout << "scrivo i due array" << endl;
				for(int i = 0 ; i < sample_length ; i++){
					x[i] = i;
					y[i] = (int) (ushort_adc_buffer_ptr[i]);
				//	cout << i << "\t" << x[i] << "\t" << y[i] << endl;
				}
				if(sample_length < MAX_NUMBER_LWORDS_64MBYTE)
					graph->DrawGraph((int)sample_length,x,y);
				tree->Fill();
				
				i_event1++;
			}
			bla bla bla something working
			}
				
		}
	}

	tree->Print();
	f.Write();[/code]

and if I comment “graph->DrawGraph((int)sample_length,x,y);” the code works otherwise it compiles but when I lunch it says Illegal instruction: 4

Try to replace: if(sample_length < MAX_NUMBER_LWORDS_64MBYTE) graph->DrawGraph((int)sample_length,x,y); with: delete graph; // delete the old graph if (sample_length < MAX_NUMBER_LWORDS_64MBYTE) graph = new TGraph(sample_length, x, y); else graph = new TGraph();

[quote=“Wile E. Coyote”]Try to replace:
graph->DrawGraph((int)sample_length,x,y);
with:
{ delete graph; graph = new TGraph(sample_length, x, y); }[/quote]

the same Illegal instruction: 4

Also, replace: f.Write(); with: tree->Write(); f.Close(); // note: it will automatically delete the "tree", too

that part works
if I comment the line of the Tgraph the program work and writes the TTre in the .root file

it crashes when I try to create the TGraph with x and y (I print them and they are right)

Hi,

with my post I meant the smallest possible macro/program (including input data if any) which is runnable by anybody and that shows the issue.

Cheers,
Danilo

#include "project_system_define.h"		//define LINUX or WINDOWS


#include <iostream>
using namespace std;




#define CERN_ROOT_PLOT

#ifdef CERN_ROOT_PLOT
	#include "rootIncludes.h"
#endif




#define MAX_NUMBER_LWORDS_64MBYTE			0x1000000       /* 64MByte */


/* ***************************************************************************************************************** */
int main(int argc, char* argv[]) {

	/******************************************************************************************************************************/
	/* CERN ROOT                                                                                                                  */
	/******************************************************************************************************************************/

	#ifdef CERN_ROOT_PLOT

		




		TApplication theApp("SIS3316 Application: Test", &argc, (char**)argv);
		

	#endif

		
		

		cout << "aperto TFILE e creato TTree" << endl;
		TFile f("data60Co2Riv.root","RECREATE");
		TTree *tree = new TTree("tree", "sorted_signals");
		cout << "aperto TFILE e creato TTree" << endl;

		char filename[128]  ;
		unsigned int i_file;
		unsigned int i_ch_no;

		int channel;
		double time;
		double energy;

		TGraph *graph = new TGraph();
		//TNtuple *ntuple = new TNtuple("ntuple","dati evento","channel:time:energy");
		int x[MAX_NUMBER_LWORDS_64MBYTE];
		int y[MAX_NUMBER_LWORDS_64MBYTE];
		for(int i = 0 ; i < MAX_NUMBER_LWORDS_64MBYTE ; i++){
			x[i] = i;
			y[i] = 0;
		}

		//strutturo il TTre
		tree->Branch("channel",&channel,"channel/I");
		tree->Branch("time",&time,"time/D");
		tree->Branch("energy",&energy,"energy/D");
		//tree->Branch("ntuple","TNtuple",&ntuple,32000,0);
		tree->Branch("graph","TGraph",&graph,32000,0);


		

			
			int i_event1 = 0;
			int i_event2 = 0;
			int k = 0;
			int sample_length = 1000;
			
			while( k < 1000){




				
				
					channel = 1;
					time = 10;
					energy = 1500.;
					
					for(int i = 0 ; i < sample_length ; i++){
						x[i] = i;
						y[i] = 4;
					}
					delete graph;
					TGraph *graph = new TGraph(sample_length, x, y);
					tree->Fill();
					k++;
					
				}
				

		tree->Print();
		f.Write();

		


	return 0;
}




here there is a code clean by all other stuff
it gives me the same illegal instruction 4 output, but it compiles correctly

all includes are in a separate file with almost all root inludes

Try: [code]#include “TApplication.h”
#include “TFile.h”
#include “TTree.h”
#include “TGraph.h”

#include

#define MAX_NUMBER_LWORDS_64MBYTE 0x1000000 /* 64MByte */

int main(int argc, char **argv) {
TApplication theApp(“SIS3316 Application: Test”, &argc, argv);

int channel;
double time;
double energy;
TGraph *graph = ((TGraph *)0);

std::cout << “aperto TFILE e creato TTree” << std::endl;

TFile f(“data60Co2Riv.root”, “RECREATE”);
TTree *tree = new TTree(“tree”, “sorted_signals”);

#if 1 /* 0 or 1 /
tree->Branch(“channel”, &channel);
tree->Branch(“time”, &time);
tree->Branch(“energy”, &energy);
tree->Branch(“graph”, &graph, 32000, 0);
// tree->Branch(“graph.”, &graph);
#else /
0 or 1 /
tree->Branch(“channel”, &channel, “channel/I”);
tree->Branch(“time”, &time, “time/D”);
tree->Branch(“energy”, &energy, “energy/D”);
tree->Branch(“graph”, “TGraph”, &graph, 32000, 0);
#endif /
0 or 1 */

std::cout << “aperto TFILE e creato TTree” << std::endl;

int *x = new int[(MAX_NUMBER_LWORDS_64MBYTE)];
int *y = new int[(MAX_NUMBER_LWORDS_64MBYTE)];

int k = 0;
int sample_length = 1000;

while (k < 1000) {
channel = 1;
time = 10;
energy = 1500.;

for (int i = 0; i < sample_length; i++) {
  x[i] = i;
  y[i] = 4;
}
delete graph;
graph = new TGraph(sample_length, x, y);

tree->Fill();
k++;

}

tree->Print();

f.Write();
f.Close(); // automatically deletes the “tree”, too

delete graph;
delete[] x;
delete[] y;

return 0;
}[/code]

You can read this “tree” using, for example, something like: [code]#include “TFile.h”
#include “TTree.h”
#include “TGraph.h”
#include “TCanvas.h”

#include

int ReadTree(const char *filename = “data60Co2Riv.root”)
{
if ((!filename) || (!(*filename))) return -1; // just a precaution

TFile *file = TFile::Open(filename);
if (!file) return -2; // just a precaution

TTree *tree; file->GetObject(“tree”, tree);
if (!tree) return -3; // just a precaution

int channel = -1;
double time = -1;
double energy = -1;
TGraph *graph = ((TGraph *)0);

tree->SetBranchAddress(“channel”, &channel);
tree->SetBranchAddress(“time”, &time);
tree->SetBranchAddress(“energy”, &energy);
tree->SetBranchAddress(“graph”, &graph);

TCanvas *c = new TCanvas(“c”, “c”, 600, 600);
c->Divide(3,3);

Long64_t nentries = tree->GetEntries();
if (nentries > 9) nentries = 9; // read only at most the first 9 entries

for (Long64_t i = 0; i < nentries; i++) {
tree->GetEntry(i);

std::cout << "i = " << i << "   "
          << "channel = " << channel << "   "
          << "time = " << time << "   "
          << "energy = " << energy << std::endl;

c->cd(i + 1);

#if 1 /* 0 or 1 */
if (graph) graph->Draw(“AL”);
graph = ((TGraph )0); // prevent next “GetEntry” from deleting “graph”
#else /
0 or 1 /
if (graph) graph->DrawClone(“AL”);
#endif /
0 or 1 */
}

c->cd(0);

tree->ResetBranchAddresses(); // detach “tree” from local variables
delete file; // automatically deletes “tree”, too

delete graph;

return 0;
}[/code]

ok, thanks

they all works

now I have to find why mine does not :frowning:

but starting from something working is better than walking in the dark :smiley: