Read Data in a Ttree

Hi

I have a Ttree with a lot of branches (263) and I need to fill a new branch with all values not equal to 0 of 254 of these branches. To do that I have write a macro but I have some issues.

This is my macro :

void macro()
{
	TFile* file=new TFile("ResultsCP.root","update");
 	TTree* tree=(TTree*)file->Get("Ntuple/Ntuple");
	Double_t E_Si1;
	Double_t Eloss_Si1;
	TBranch* ElossSi1;
	TObjArray* ListBranch = tree->GetListOfBranches();
 	ElossSi1=tree->Branch("ElossSi1", &Eloss_Si1, "Eloss_Si1/D");
	for (Long64_t i =0; i < 254; i++)
	{
		TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9);
		tree->SetBranchAddress(StripSi1->GetName(),&E_Si1);
		for(Long64_t j=0; j < StripSi1->GetEntries(); j++)
		{
			tree->GetEntry(j);
			if (E_Si1){
				Eloss_Si1 = E_Si1;
				ElossSi1->Fill();
			}
		}
	}
	tree->Write();
	file->Close();	
}

I am a beginner on root and when I try to execute this macro I have a segmentation violation with errors that I don’t understand :

Processing macro.cpp...
Warning in <TBasket::ReadBasketBuffers>: basket:ESi1 has fNevBuf=3999 but fEntryOffset=0, pos=259, len=38036, fNbytes=0, fObjlen=0, trying to repair

 *** Break *** segmentation violation



===========================================================
There was a crash.
This is the entire stack trace of all threads:
===========================================================
#0  0x00000031658ac7be in waitpid () from /lib64/libc.so.6
#1  0x000000316583e5c9 in do_system () from /lib64/libc.so.6
#2  0x0000003f6ba6ab04 in TUnixSystem::StackTrace() () from /usr/lib64/root/libCore.so.5.34
#3  0x0000003f6ba69f23 in TUnixSystem::DispatchSignals(ESignals) () from /usr/lib64/root/libCore.so.5.34
#4  <signal handler called>
#5  0x00007f7c3fab5324 in TBufferFile::ReadDouble(double&) () from /usr/lib64/root/libRIO.so
#6  0x00007f7c3f2c0a31 in TBranch::GetEntry(long long, int) () from /usr/lib64/root/libTree.so
#7  0x00007f7c3f315c88 in TTree::GetEntry(long long, int) () from /usr/lib64/root/libTree.so
#8  0x00007f7c3f34f928 in ?? () from /usr/lib64/root/libTree.so
#9  0x0000003f6aa4dba9 in Cint::G__ExceptionWrapper(int (*)(G__value*, char const*, G__param*, int), G__value*, char*, G__param*, int) () from /usr/lib64/root/libCint.so.5.34
#10 0x0000003f6aa6f4aa in G__exec_asm () from /usr/lib64/root/libCint.so.5.34
#11 0x0000003f6ab29fc0 in ?? () from /usr/lib64/root/libCint.so.5.34
#12 0x0000003f6ab25651 in G__exec_statement () from /usr/lib64/root/libCint.so.5.34
#13 0x0000003f6ab2968b in ?? () from /usr/lib64/root/libCint.so.5.34
#14 0x0000003f6ab25651 in G__exec_statement () from /usr/lib64/root/libCint.so.5.34
#15 0x0000003f6aad6dd9 in G__interpret_func () from /usr/lib64/root/libCint.so.5.34
#16 0x0000003f6aac4918 in G__getfunction () from /usr/lib64/root/libCint.so.5.34
#17 0x0000003f6aaa312e in G__getitem () from /usr/lib64/root/libCint.so.5.34
#18 0x0000003f6aaa7cb8 in G__getexpr () from /usr/lib64/root/libCint.so.5.34
#19 0x0000003f6aab11c8 in G__calc_internal () from /usr/lib64/root/libCint.so.5.34
#20 0x0000003f6ab30275 in G__process_cmd () from /usr/lib64/root/libCint.so.5.34
#21 0x0000003f6ba2ac46 in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) () from /usr/lib64/root/libCore.so.5.34
#22 0x0000003f6ba283b3 in TCint::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) () from /usr/lib64/root/libCore.so.5.34
#23 0x0000003f6b98f126 in TApplication::ExecuteFile(char const*, int*, bool) () from /usr/lib64/root/libCore.so.5.34
#24 0x0000003f6b98e5d3 in TApplication::ProcessLine(char const*, bool, int*) () from /usr/lib64/root/libCore.so.5.34
#25 0x0000003f6c213811 in TRint::Run(bool) () from /usr/lib64/root/libRint.so.5.34
#26 0x000000000040103c in main ()
===========================================================


The lines below might hint at the cause of the crash.
If they do not help you then please submit a bug report at
http://root.cern.ch/bugs. Please post the ENTIRE stack trace
from above as an attachment in addition to anything else
that might help us fixing this issue.
===========================================================
#5  0x00007f7c3fab5324 in TBufferFile::ReadDouble(double&) () from /usr/lib64/root/libRIO.so
#6  0x00007f7c3f2c0a31 in TBranch::GetEntry(long long, int) () from /usr/lib64/root/libTree.so
#7  0x00007f7c3f315c88 in TTree::GetEntry(long long, int) () from /usr/lib64/root/libTree.so
#8  0x00007f7c3f34f928 in ?? () from /usr/lib64/root/libTree.so
===========================================================


Root > Function macro() busy flag cleared

Can you help me to solve this problem, or suggest me an other method ?

Thanks in advance!
Florian

[quote]I have a Ttree with a lot of branches (263) and I need to fill a new branch with all values not equal to 0 of 254 of these branches. [/quote]As expressed (and/or as implemented) this makes a semantically odd TTree.
If the code presented was working would would end up with most branch with N entries and the new branch having between 0 and 254*N entries. Consequently reading the resulting TTree correctly is likely to be hard (i.e. how would you read the value (in the new branch) belonging to the same original entry?

The plausible cause of the crash is:

TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9); tree->SetBranchAddress(StripSi1->GetName(),&E_Si1); where you might be off in your index calculation and you should consider using:

      TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9);
      if (StripSi1 == nullptr) {
           fprintf(stderr,"Missing branch number %d\n",i+9);
           continue;
      }
      tree->SetBranchAddress(StripSi1->GetName(),&E_Si1);

Also you read the entire TTree 254 times!

Guessing at what you meant to do, this might work and would be more efficient.

[code]
void macro()
{
TFile* file=new TFile(“ResultsCP.root”,“update”);
TTree* tree=(TTree*)file->Get(“Ntuple/Ntuple”);
Double_t E_Si1;
std::vector<Double_t> Eloss_Si1;
TBranch* ElossSi1;
TObjArray* ListBranch = tree->GetListOfBranches();
ElossSi1=tree->Branch(“ElossSi1”, &Eloss_Si1, “Eloss_Si1/D”);
for (Long64_t i =0; i < 254; i++) {
TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9);
if (StripSi1 == nullptr) {
fprintf(stderr,“Missing branch number %d\n”,i+9);
continue;
}
tree->SetBranchAddress(StripSi1->GetName(),&E_Si1);
}
for(Long64_t j=0; j < tree->GetEntries(); ++j)
for (Long64_t i =0; i < 254; i++) {
TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9);
if (!StripSi1) continue;

     StripSi1->GetEntry(j);
     if (E_Si1){
        Eloss_Si1.push_back(E_Si1);
     }
  }
  ElossSi1->Fill();
  Eloss_Si1.clear();

}
tree->Write();
file->Close();
}[/code]

Cheers,
Philippe.

Hi

I can’t use a vector to fill my branch because, I don’t know why, the branch have a lot of 0 if I do that.

But I modified my code with your advices and now it’s seem to works. This is the code if you want to see it :

void macro()
{
	TFile* file=new TFile("ResultsCP.root","update");
 	TTree* tree=(TTree*)file->Get("Ntuple/Ntuple");
	Double_t E_Si1;
	Double_t Eloss_Si1;
	TBranch* ElossSi1;
	TObjArray* ListBranch = tree->GetListOfBranches();
 	ElossSi1=tree->Branch("ElossSi1", &Eloss_Si1, "Eloss_Si1/D");
	for (Long64_t i =0; i < 254; i++)
	{
		TBranch* StripSi1 = (TBranch*) ListBranch->At(i+9);
		tree->SetBranchAddress(StripSi1->GetName(),&E_Si1);
       		if (StripSi1 == NULL) {
           		fprintf(stderr,"Missing branch number %d\n",i+9);
          		continue;
      		}
		for(Long64_t j=0; j < StripSi1->GetEntries(); j++)
		{		
			StripSi1->GetEntry(j);
			if (E_Si1){			
				Eloss_Si1 = E_Si1;
				ElossSi1->Fill();
			}
		}
	}
	tree->Write();
	file->Close();	
}

Thanks a lot !

Cheers
Florian