Very big TClonesArray

Hi all.
I’m using Root 5.10 on SLC4.
I create root tree based on Event example. But I have events with more than 1 million particles (tracks). I use TClonesArray to store tracks in the event, but I have a problem when reading the tree. The problem occurs at the event no. 36405. I guess it might be because TClonesArray::At(Int) works on Int_t so from -32,768 to +32,767. How to put longer TClonesArrays into a class?
The error message is:
Error in TClonesArray::At: index 36405 out of bounds (size: 36405, this: 0x0aa771d8)

Cheers, Mariusz

[quote=“sapinski”]Hi all.
I’m using Root 5.10 on SLC4.

[/quote]

Ignore my previous mail.
The problem is different.
I’m trying to read a root file with a tree and 3 branches made of Events.
Every event has particles.
I try to loop over particles in the largest branch (cryo) but somehow I cannot go further than the particles in branch d4… why?

{

gROOT->Reset();
gSystem->Load("libEvent.so");

// or:
TChain chws(“tree”);
chws.Add(“rint.root”);

TClonesArray *fgParticles = 0;
Event* evO = new Event();  // event Outside the Cryostat
Event* evD = new Event();  // event in D4
Event* evQ = new Event();  // event in Q5

TBranch *cryo = chws.GetBranch("outCryo");    
cryo->SetAddress(&evO);   
TBranch *q5 = chws.GetBranch("Q5hits");    
q5->SetAddress(&evQ);   
TBranch *d4 = chws.GetBranch("D4hits");    
d4->SetAddress(&evD);    

Int_t nevent = (Int_t)tree->GetEntries();

// output file
TFile* hfile = new TFile (“ana.root”, “RECREATE”);

Int_t npartO=0;
Int_t npartQ=0;
Int_t npartD=0;
for(Int_t i=0; i<nevent; i++) {
    npartQ=0;
npartD=0;
npartO=0; 

    if( cryo->GetEvent(i) ) {
   cout << "cryo GetEvent OK " << endl;
}	
    if( q5->GetEntry(i) ) {
   cout << "Q5 GetEvent OK " << endl;
}   
if( d4->GetEntry(i) ) {
   cout << "D4 GetEvent OK " << endl;
}   
if(evO->GetNparticle()) {
   cout << "Out OK" << endl;
       Int_t npartO=evO->GetNparticle();
}   	   
if(evQ->GetNparticle()) {
    cout << "Q5 OK" << endl;
    Int_t npartQ=evQ->GetNparticle();	    
}    
if(evD->GetNparticle()) {
    cout << "D4 OK" << endl;
    Int_t npartD=evD->GetNparticle();	    
}    

    cout << " npartO = " << npartO <<
    " and npartQ = " << npartQ <<
    " and npartD = " << npartD << endl;
    TClonesArray *partsO = evO->GetParticles();
hnpartO_2d->Fill(nevent,npartO);

TClonesArray *parts = 0;
parts = evO->GetParticles();

for(Int_t j=0; j<npartO; j++) {
      if(npartO<5000000) {
   Particle *p = evO->GetParticle(j);	
       p->Clear(""); 
      } // end of if npartO<50000
} // end of loop over particles
   parts->Clear();	
} // end of loop over events

hfile->Close();

}

You have several problems in your example:
1- In the statement “Int_t nevent = (Int_t)tree->GetEntries()”, the variable tree is undefined.
It should be chws instead.
2-You should never set the address of a Tree in a TChain explicitly, but rather do

[code] Event* evO = new Event(); // event Outside the Cryostat
Event* evD = new Event(); // event in D4
Event* evQ = new Event(); // event in Q5

chws.SetBranchAddress(“outCryo”,&evO);
chws.SetBranchAddress(“Q5hits”,&evQ);
chws.SetBranchAddress(“D4hits”),&evD);
[/code]
This way, TChain will correctly set the address of the effective branches when
loading each Tree from its file.

Rene

Can I ask about what role the static TClonesArray fgTracks has in Event class… I have impression I do need that in my analysis, but I’d like to understand better why you have it in your example? Is it because you can have different Events based on the same tracks?
Mariusz

You do not need to declare the TClonesArray as a static object. The important thing is to create the TClonesArray only once for all events and not for each event.

Rene

[quote=“brun”]You do not need to declare the TClonesArray as a static object. The important thing is to create the TClonesArray only once for all events and not for each event.
[/quote]

Thank you for the suggestion. My problem is specyfic. I do not have many events - on the order of 100. But every one of them is huge. In the largest detector I register a 1-4 million of particles. I have 3 detectors. The Event structure in each of them is the same, but measurements are independent. So I use the same Event class (with TClonesArray) and write them to 3 branches of a Tree. I fill the tree with tree->Fill() - all 3 branches together, so I need to have at least 3 TClonesArray in memory in that moment. I will need to make simulations with different number of detectors, so with different number of Events … this gives me flexibility. Do you think that different structure would have more sense?
Mariusz

Yes it is OK to have several TClonesArray as top level branches.
This is the usual situation in HEP events

Rene