Problems with use of CloneTree for sorting one tree variable

Hi, I want to sort (decreasing order) a tree according to one of the variables it has. What I do is to define a CloneTree which I fill with the sorted entries. My script works fine if I use a tree with only few entries (up to 60), but when I use bigger trees, the code compiles but I get the following error when running:

NO.Events 1347
tree entries 1347

Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 6158 instead of 9230
Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 56680 instead of 276632
Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 2514 instead of 5016
Error in TBufferFile::ReadVersion: Could not find the StreamerInfo with a checksum of 0xd00f1f40 for the class “vector” (buffer with no parent)

*** Break *** segmentation violation
Segmentation fault
My code is:

#include <RecEvent.h> 
#include <RecEventFile.h>
#include <DetectorGeometry.h>
#include <FileInfo.h>
#include <FdRecLevel.h>
#include <SdRecLevel.h>
#include <RecShower.h>
#include <GenShower.h>
#include <Detector.h>
#include <TH1D.h>
#include <TStyle.h>
#include <TH1F.h>
#include <TProfile.h>
#include <TPaveStats.h>
#include <TFile.h>
#include <TLegend.h>
#include <TMath.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <vector>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <TTree.h>
#include <TChain.h>
#include <TClonesArray.h>
#include <TBranch.h>
#include <TBranchClones.h>
#include "SelectHor.h"
using namespace std;
//using namespace sevt;
//using namespace utl;

ClassImp(SelectHor);

SelectHor::SelectHor()
 {//1
                                      
    dataFile=new RecEventFile("GoldenGoldenRec_v7r4_2012_01_generated_2012-2-29.root");
    fChain =new TChain("recData");
    fChain ->Add("GoldenRec_v7r4_2012_01_generated_2012-2-29.root");  
    GoodFile = new RecEventFile("Golden_FdEnAscending_01.root",RecEventFile:eWrite);
 
 
 dataFile->SetBuffers(&(theEvent));
 fChain->SetBranchAddress("event.",&theEvent);
 GoodFile->SetBuffers(&(theEvent));

 const Int_t ntot=(Int_t)fChain->GetEntries();
  theEvent = new RecEvent();           
 }//1

SelectHor::~SelectHor()
  
{ // <-2 
  //=================================================	
 
  delete fChain;
  delete theEvent;

  //=================================================
} // -> 2

 void SelectHor::MakeSelectHor()
   
 { // 
   const Int_t ntot=(Int_t)fChain->GetEntries(); 
   fChain->Draw("event.fSDEvent.fSdRecShower.fEnergy","","goff");
   
   Int_t *index =new Int_t[ntot];   
   TMath::Sort(ntot,fChain->GetV1(),index);
   fChain->GetEntry(0);
   
   TTree *tree=(TTree*)fChain->CloneTree(0);
   for(Int_t i=0; i<ntot;i++){
     fChain->GetEntry(index[i]);
     tree->Fill();
   }
   
   cout<<"tree entries "<<tree->GetEntries()<<endl;
  
  
   TChain *ChainSorted=(TChain*)tree->CloneTree();
  
   delete [] index;
   
   int j=0;
   
   Int_t  GoodEvId;
      
   DetectorGeometry* theGeometry = new DetectorGeometry();
   dataFile->ReadDetectorGeometry(*theGeometry);
   
   FileInfo theInfo;
   dataFile->ReadFileInfo(theInfo);
   
   
   
   const int lastevent=ChainSorted->GetEntries();

   

   //for (int i=0; i<lastevent;i++)
   for (int i=0; i<100;i++)
   
     { // <- while               
       
       ChainSorted->GetEntry(i);            
       Double_t Theta=theEvent->GetSDEvent().GetSdRecShower().GetZenith()*180/TMath::Pi();
	Int_t EventId=theEvent->GetSDEvent().GetEventId();	
	
	if(59<=Theta && Theta <= 82){
	  
	  	  
	  GoodEvId=theEvent->GetSDEvent().GetEventId();
	  
	  } // ->Zenith angle condition


     	if (theEvent->GetSDEvent().GetEventId()==GoodEvId)
 	{
	    
 	    GoodFile->WriteEvent();
 	    GoodFile->WriteDetectorGeometry (*theGeometry);
 	    GoodFile->WriteFileInfo(theInfo);
	    
 	    ++j; 
	  
 	}


      
	
      }//While event next event, ...
    
   cout<<"No. Good Events "<<j<<endl;
   GoodFile->Close();


 } // -> funcion

If I use the tree “tree” stead of the ChainSorted I get the same kind of error. Could someone help me with this?, what am I doing wrong?

I thank you in advance!
Best regards
Karen

Hi Karen,

[code] const Int_t ntot=(Int_t)fChain->GetEntries();
fChain->Draw(“event.fSDEvent.fSdRecShower.fEnergy”,"",“goff”);

Int_t *index =new Int_t[ntot];
TMath::Sort(ntot,fChain->GetV1(),index);[/code]If ntot is greater than 1,000,000, this will result in unitialize memory read. The ‘size’ of fChain->GetV1() is the value of fChain->GetEstimate(). Use [code] const Int_t ntot=(Int_t)fChain->GetEntries();
fChain->SetEstimate(ntot+1);
fChain->Draw(“event.fSDEvent.fSdRecShower.fEnergy”,"",“goff”);

Int_t *index =new Int_t[ntot];
TMath::Sort(ntot,fChain->GetV1(),index);[/code]

Also make sure that the cloned tree is attached to the output file: TTree *tree=(TTree*)fChain->CloneTree(0); tree->SetDirectory(GoodFile->GetUnderlyingRootFile());

Cheers,
Philippe.

Dear Philippe,

I thank you very much for your help!!. I changed my script according to your advice. I did not manage to attach the tree to the output file, the outputfile I am using does not support GetUnderlyingRootFile() since is a file of the kind “RecEventFile”. But I changed the estimate of the original chain. Now the script runs and finishes but the number of entries of the new chain I define based on the tree is less than the entries of the tree. I also get the same kind of error as before:
Output on screen:

NO.Events 1347
tree entries 1347
Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 6158 instead of 9230
Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 56680 instead of 276632
Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 2514 instead of 5016
Error in TBufferFile::ReadVersion: Could not find the StreamerInfo with a checksum of 0x405300 for the class “vector” (buffer with no parent)
Error in TBufferFile::CheckByteCount: object of class vector<Double_t> read too few bytes: 10 instead of 356515840
Error in TBufferFile::CheckByteCount: Byte count probably corrupted around buffer position 216286:
356515840 for a possible maximum of -11500
ChainSorted entries 18
No. Good Events 5

My new code looks like that:

ClassImp(SelectHor);

SelectHor::SelectHor()
 {//1

  
dataFile=new RecEventFile("GoldenRec_v7r4_2012_01_generated_2012-2-29.root");

    fChain =new TChain("recData"); 
    fChain ->Add("GoldenRec_v7r4_2012_01_generated_2012-2-29.root");  //
   

    GoodFile = new RecEventFile("Golden_FdEnAscending_v7r4_2012_01.root",RecEventFile::eWrite);
 
 
 dataFile->SetBuffers(&(theEvent));
 fChain->SetBranchAddress("event.",&theEvent);
 GoodFile->SetBuffers(&(theEvent));



 
 const Int_t ntot=(Int_t)fChain->GetEntries();
  theEvent = new RecEvent(); 
 


cout<<" NO.Events "<<ntot<<endl;            
 }//1

SelectHor::~SelectHor()
  
{ // <-2 
  //=================================================	
 
  delete fChain;
  delete theEvent;

  //=================================================
} // -> 2

 void SelectHor::MakeSelectHor()
   
 { // <- la función

   const Int_t ntot=(Int_t)fChain->GetEntries(); 
   fChain->SetEstimate(ntot+1);
 
   fChain->Draw("event.fSDEvent.fSdRecShower.fEnergy","","goff");
   
   Int_t *index =new Int_t[ntot];   
   TMath::Sort(ntot,fChain->GetV1(),index);
   fChain->GetEntry(0);
   
   TTree *tree=(TTree*)fChain->CloneTree(0);
   //tree->SetDirectory(GoodFile->GetUnderlyingRootFile());
   
   
   for(Int_t i=0; i<ntot;i++){
     fChain->GetEntry(index[i]);
     tree->Fill();
   }
   
   cout<<"tree entries "<<tree->GetEntries()<<endl;

 
   TChain *ChainSorted=(TChain*)tree->CloneTree();
   cout<<"ChainSorted entries "<<ChainSorted->GetEntries()<<endl;
   
  
  

   delete [] index;
   

   
   cout <<"termina lo de sorting"<<endl;
   
   //============================ 
   int j=0;         
   DetectorGeometry* theGeometry = new DetectorGeometry();
   dataFile->ReadDetectorGeometry(*theGeometry);
   
   FileInfo theInfo;
   dataFile->ReadFileInfo(theInfo);
   
   const int lastevent=ChainSorted->GetEntries();//
   for (int i=0; i<lastevent;i++)
  
     { // <- while               
       
   
       ChainSorted->GetEntry(i);     
  
       Double_t Theta=theEvent->GetSDEvent().GetSdRecShower().GetZenith()*180/TMath::Pi();

	if(!(59<=Theta && Theta <= 82))continue;
	    
 	    GoodFile->WriteEvent();
 	    GoodFile->WriteDetectorGeometry (*theGeometry);
 	    GoodFile->WriteFileInfo(theInfo);
	    
 	    ++j; 
	  
	
      }//While event next event, ...
    
   cout<<"No. Good Events "<<j<<endl;
   GoodFile->Close();


 } // -> funcion

Do you have any other idea about how to set correctly the entries of the chain?. I thank you very much in advance.

Cheers

Karen

Hi Karen,

[quote]the outputfile I am using does not support GetUnderlyingRootFile() since is a file of the kind “RecEventFile”. [/quote]Humm … the name of the function was not intended as an accurate spelling but as a semantic marker. I do not know anything about the class RecEventFile (this is one of yours and/or your framework) but you still need to find a way to properly associate the TTree with the output TFile.

[quote]Error in TBufferFile::CheckByteCount: object of class vector read too few bytes: 6158 instead of 9230
[/quote]I do not know the source of this problem in your case. I would recommend that you either run valgrind on your example (on the guess that this is due to a memory over-write problem) or provide us with a complete running example showing the failure.

Cheers,
Philippe.

Hi Philippe,

I thank you again for your reply. The way I associate the TTree with the output TFile is by writing cd():

    const Int_t ntot=(Int_t)fChain->GetEntries(); 
   fChain->SetEstimate(ntot+1);  
   fChain->Draw("event.fSDEvent.fSdRecShower.fEnergy","","goff");
   
   Int_t *index =new Int_t[ntot];   
   TMath::Sort(ntot,fChain->GetV1(),index);
   fChain->GetEntry(0);
   
   TTree *tree=(TTree*)fChain->CloneTree(0);
  
   GoodFile->cd();
   
   for(Int_t i=0; i<ntot;i++){
     fChain->GetEntry(index[i]);
     tree->Fill();
   }

It worked for a file with less than 1000 entries, but again, when I use a bigger tree, it does not work and I get the same kind of errors as before. I ran the script using valgrind, after some time the cpu time limit exceeded, here I copy the output related with the issue:

–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/cint/cint/stl/set.dll (0x2a5e2000)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/libsetDict.so (0x2a85f000)
–9871-- REDIR: 0x3a9b215840 (stpcpy) redirected to 0x4a09120 (stpcpy)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/cint/cint/stl/vectorbool.dll (0x2aa72000)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/cint/cint/stl/vector.dll (0x2ac86000)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/libvectorDict.so (0x2b082000)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/cint/cint/stl/map2.dll (0x2b2b1000)
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/libmap2Dict.so (0x2b5ab000)
==9871== Conditional jump or move depends on uninitialised value(s)
==9871== at 0xC93E30B: TBranchElement::SetAddress(void*) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC957DAD: TChain::SetBranchAddress(char const*, void*, TBranch**) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xA1B4FFE: int TTree::SetBranchAddress(char const*, RecEvent**, TBranch**) (TTree.h:492)
==9871== by 0xA1B24EA: RecEventFile::SetBuffers(RecEvent**) (RecEventFile.cc:308)
==9871== by 0x40E8F2: SelectHor::SelectHor() (SelectHor.cc:76)
==9871== by 0x40F6E0: main (SelectHor.cc:227)
==9871==
==9871== Conditional jump or move depends on uninitialised value(s)
==9871== at 0xC93E30B: TBranchElement::SetAddress(void*) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC957DAD: TChain::SetBranchAddress(char const*, void*, TBranch**) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xA1B4F66: int TTree::SetBranchAddress(char const*, EventInfo**, TBranch**) (TTree.h:492)
==9871== by 0xA1B2511: RecEventFile::SetBuffers(RecEvent**) (RecEventFile.cc:309)
==9871== by 0x40E8F2: SelectHor::SelectHor() (SelectHor.cc:76)
==9871== by 0x40F6E0: main (SelectHor.cc:227)
==9871==
NO.Events 1347
–9871-- Reading syms from /home/Offline/External/root/5.30.00/lib/root/libTreePlayer.so (0x2bbcd000)
–9871-- REDIR: 0x3a9b679d50 (strncat) redirected to 0x4a07f50 (strncat)

==9871==
==9871== Process terminating with default action of signal 24 (SIGXCPU)
==9871== at 0x3A9C60C78A: inflate_fast (in /lib64/libz.so.1.2.3)
==9871== by 0x3A9C60A118: inflate (in /lib64/libz.so.1.2.3)
==9871== by 0xE87A933: R__unzip (in /home/Offline/External/root/5.30.00/lib/root/libCore.so)
==9871== by 0xC92B3DE: TBasket::ReadBasketBuffers(long long, int, TFile*) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC931FB4: TBranch::GetBasket(int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC932B69: TBranch::GetEntry(long long, int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC939006: TBranchElement::GetEntry(long long, int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC938FBE: TBranchElement::GetEntry(long long, int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC938FBE: TBranchElement::GetEntry(long long, int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC98F4AD: TTree::GetEntry(long long, int) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0x40EE6E: SelectHor::MakeSelectHor() (SelectHor.cc:127)
==9871== by 0x40F6E8: main (SelectHor.cc:229)
–9871-- Discarding syms at 0x23dd9fe0-0x23de0268 in /lib64/libnss_files-2.5.so due to munmap()
–9871-- Discarding syms at 0x240064b0-0x2400d918 in /lib64/libnss_ldap.so.2 due to munmap()
–9871-- Discarding syms at 0x2420ffe0-0x24212828 in /lib64/libnss_dns-2.5.so due to munmap()
==9871==
==9871== HEAP SUMMARY:
==9871== in use at exit: 658,300,538 bytes in 211,869 blocks
==9871== total heap usage: 5,489,109 allocs, 5,277,240 frees, 5,178,201,365 bytes allocated
==9871==
==9871== Searching for pointers to 211,869 not-freed blocks
==9871== Checked 533,950,728 bytes
==9871==
==9871== LEAK SUMMARY:
==9871== definitely lost: 1,448,028 bytes in 20,112 blocks
==9871== indirectly lost: 17,640 bytes in 245 blocks
==9871== possibly lost: 613,052,592 bytes in 58,586 blocks
==9871== still reachable: 40,403,221 bytes in 90,158 blocks
==9871== suppressed: 3,379,057 bytes in 42,768 blocks
==9871== Rerun with --leak-check=full to see details of leaked memory
==9871==
==9871== Use --track-origins=yes to see where uninitialised values come from
==9871== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)
==9871==
==9871== 1 errors in context 1 of 2:
==9871== Conditional jump or move depends on uninitialised value(s)
==9871== at 0xC93E30B: TBranchElement::SetAddress(void*) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC957DAD: TChain::SetBranchAddress(char const*, void*, TBranch**) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xA1B4F66: int TTree::SetBranchAddress(char const*, EventInfo**, TBranch**) (TTree.h:492)
==9871== by 0xA1B2511: RecEventFile::SetBuffers(RecEvent**) (RecEventFile.cc:309)
==9871== by 0x40E8F2: SelectHor::SelectHor() (SelectHor.cc:76)
==9871== by 0x40F6E0: main (SelectHor.cc:227)
==9871==
==9871==
==9871== 1 errors in context 2 of 2:
==9871== Conditional jump or move depends on uninitialised value(s)
==9871== at 0xC93E30B: TBranchElement::SetAddress(void*) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xC957DAD: TChain::SetBranchAddress(char const*, void*, TBranch**) (in /home/Offline/External/root/5.30.00/lib/root/libTree.so)
==9871== by 0xA1B4FFE: int TTree::SetBranchAddress(char const*, RecEvent**, TBranch**) (TTree.h:492)
==9871== by 0xA1B24EA: RecEventFile::SetBuffers(RecEvent**) (RecEventFile.cc:308)
==9871== by 0x40E8F2: SelectHor::SelectHor() (SelectHor.cc:76)
==9871== by 0x40F6E0: main (SelectHor.cc:227)
==9871==
–9871–
–9871-- used_suppression: 9389 CINT’s function info
–9871-- used_suppression: 449 std::string uses in various place.
–9871-- used_suppression: 837 Anything allocated by TClass::Init: new()
–9871-- used_suppression: 6 ROOT’s list of types
–9871-- used_suppression: 501 Array of objects allocated in TStreamerInfo::Compile
–9871-- used_suppression: 201 Anything allocated by TClass::Init: new
–9871-- used_suppression: 25 TClass’s list of base classes (G__DataMemberInfo elements)
–9871-- used_suppression: 7901 CINT’s function parameter info
–9871-- used_suppression: 7382 CINT’s function info (name)
–9871-- used_suppression: 4 dl-hack3
==9871==
==9871== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 4 from 4)
Cputime limit exceeded

Thank you for any advice you can still give me. I am also ivestigating
Cheers

Karen

Hi Karen,

You need to use: GoodFile->cd(); // Good File must be the current directory when the clone is created. TTree *tree=(TTree*)fChain->CloneTree(0);

Cheers,
Philippe.

1 Like

Hi,

==9871== Conditional jump or move depends on uninitialised value(s) .... ==9871== by 0xA1B4FFE: int TTree::SetBranchAddress<RecEvent>(char const*, RecEvent**, TBranch**) (TTree.h:492) ==9871== by 0xA1B24EA: RecEventFile::SetBuffers(RecEvent**) (RecEventFile.cc:308)It also looks like RecEventFile might be passing uninitialized memory to the TTree. I.e. Move [coide] theEvent = new RecEvent(); [/code] before the SetBuffers …

Cheers,
Philippe.

Dear Philippe,

I thank you very much!!, it seems it works as well for more than 1000 entries.

Cheers!

Karen

1 Like