#include <Riostream.h>
#include <TTree.h>
#include <TROOT.h>
#include "AliRun.h"
#include "TClonesArray.h"
#include "TDirectory.h"
#include <TArrayI.h>
#include "TError.h"
#include "TClass.h"
#include "TFile.h"
#include "AliSegmentID.h"
#include "AliSegmentArray.h"
#include "TObjString.h"
using std::endl;
using std::cout;
ClassImp(AliSegmentArray)
AliSegmentArray::AliSegmentArray()
:TNamed(),
fSegment(0),
fTreeIndex(0),
fNSegment(0),
fTree(0),
fTreeOwner(kFALSE),
fBranch(0),
fClass(0)
{
}
AliSegmentArray::AliSegmentArray(const char *classname, Int_t n)
:TNamed("SegmentArray","SegmentArray"),
fSegment(0),
fTreeIndex(0),
fNSegment(0),
fTree(0),
fTreeOwner(kFALSE),
fBranch(0),
fClass(0)
{
SetClass(classname);
if (MakeArray(n)==kFALSE){
Error("AliSegmentArray", "can't allocate %d segments in memory",n);
return;
}
}
AliSegmentArray::AliSegmentArray(const AliSegmentArray &segment)
:TNamed(segment),
fSegment(0),
fTreeIndex(0),
fNSegment(0),
fTree(0),
fTreeOwner(kFALSE),
fBranch(0),
fClass(0)
{
}
AliSegmentArray &AliSegmentArray::operator = (const AliSegmentArray & )
{
return (*this);
}
AliSegmentArray::~AliSegmentArray()
{
if (fNSegment>0){
fSegment->Delete();
delete fSegment;
}
if (fTree) {
if (fTreeOwner) delete fTree;
else fTree->Reset();}
if (fTreeIndex) delete fTreeIndex;
}
Bool_t AliSegmentArray::SetClass(const char *classname)
{
if ( fClass !=0 ) {
fClass = 0;
}
if (fTree !=0) {
if (fTreeOwner) delete fTree;
else fTree->Reset();
fTree = 0;
fBranch = 0;
delete fTreeIndex;
fTreeIndex = 0;
}
if (fSegment != 0) {
fSegment->Delete();
delete fSegment;
fSegment = 0;
}
if (!gROOT)
::Fatal("AliSegmentArray::AliSegmentArray", "ROOT system not initialized");
fClass = gROOT->GetClass(classname);
if (!fClass) {
Error("AliSegmentArray", "%s is not a valid class name", classname);
return kFALSE;
}
if (!fClass->InheritsFrom(AliSegmentID::Class())) {
Error("AliSegmentArray", "%s does not inherit from AliSegmentID", classname);
return kFALSE;
}
return kTRUE;
}
AliSegmentID * AliSegmentArray::NewSegment()
{
if (fClass==0) return 0;
AliSegmentID * segment = (AliSegmentID * )fClass->New();
if (segment == 0) return 0;
return segment;
}
Bool_t AliSegmentArray::AddSegment(AliSegmentID *segment)
{
if (segment==0) return kFALSE;
if (fSegment==0) return kFALSE;
if (fClass==0) return kFALSE;
if (!(segment->IsA()->InheritsFrom(fClass))){
Error("AliSegmentArray", "added class %s is not of proper type ",
segment->IsA()->GetName());
return kFALSE;
}
fSegment->AddAt(segment,segment->GetID());
fNSegment = fSegment->GetLast()+1;
return kTRUE;
}
AliSegmentID * AliSegmentArray::AddSegment(Int_t index)
{
if (fSegment==0) return 0;
if (fClass==0) return 0;
AliSegmentID * segment = NewSegment();
if (segment == 0) return 0;
fSegment->AddAt(segment,index);
segment->SetID(index);
fNSegment = fSegment->GetLast()+1;
return segment;
}
void AliSegmentArray::ClearSegment(Int_t index)
{
if (fSegment->At(index)){
delete fSegment->RemoveAt(index);
}
}
Bool_t AliSegmentArray::MakeArray(Int_t n)
{
if (fSegment) {
fSegment->Delete();
delete fSegment;
}
fSegment = new TObjArray(n);
fNSegment=n;
if (fSegment) return kTRUE;
else return kFALSE;
}
void AliSegmentArray::MakeTree(TTree* tree)
{
AliSegmentID * psegment = NewSegment();
fTree = tree;
fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,99);
}
void AliSegmentArray::MakeTree(char *file)
{
AliSegmentID * psegment = NewSegment();
if (fTree) {
if (fTreeOwner)
{
delete fTree;
fTree = new TTree("Segment Tree","Tree with segments");
}
else fTree->Reset();
}
else {
cout << "Tree with segments does not exist"<<endl;
return;
}
fBranch = fTree->Branch("Segment",psegment->IsA()->GetName(),&psegment,64000,99);
if (file) {
TString outFile = gAlice->GetBaseFile();
outFile = outFile + "/" + file;
fBranch->SetFile(outFile.Data());
TDirectory *wd = gDirectory;
TBranch *b = fBranch;
TIter next( b->GetListOfBranches());
while ((b=(TBranch*)next())) {
b->SetFile(outFile.Data());
}
cout << "Diverting branch " << "Segment" << " to file " << outFile << endl;
wd->cd();
}
delete psegment;
}
Bool_t AliSegmentArray::MakeDictionary(Int_t size)
{
if (size<1) return kFALSE;
if (fTreeIndex) delete fTreeIndex;
fTreeIndex = new TArrayI();
fTreeIndex->Set(size);
AliSegmentID * psegment = NewSegment();
fBranch->SetAddress(&psegment);
TBranch * brindix = fTree->GetBranch("fSegmentID");
Int_t nevent = (Int_t)fTree->GetEntries();
for (Int_t i = 0; i<nevent; i++){
brindix->GetEvent(i);
Int_t treeIndex=psegment->GetID();
if (fTreeIndex->fN<treeIndex) fTreeIndex->Set(Int_t(Float_t(treeIndex)*1.5)+1);
(*fTreeIndex)[treeIndex]=i+1;
}
if (psegment) delete psegment;
return kTRUE;
}
Bool_t AliSegmentArray::ConnectTree(TTree* tree)
{
fTree =tree;
if (fTree == 0) return kFALSE;
fBranch = fTree->GetBranch("Segment");
if (fBranch==0) return kFALSE;
MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
MakeArray(fTreeIndex->fN);
return kTRUE;
}
Bool_t AliSegmentArray::ConnectTree(const char * treeName)
{
if (fTree){
if (fTreeOwner)
{
delete fTree;
fTree = 0;
}
else fTree->Reset();
fBranch = 0;
}
fTree =(TTree*)gDirectory->Get(treeName);
if (fTree == 0) return kFALSE;
fBranch = fTree->GetBranch("Segment");
if (fBranch==0) return kFALSE;
MakeDictionary(TMath::Max(fNSegment,Int_t(fTree->GetEntries())));
MakeArray(fTreeIndex->fN);
return kTRUE;
}
AliSegmentID *AliSegmentArray::LoadSegment(Int_t index)
{
if (fTreeIndex ==0 ) MakeDictionary(3000);
if (fTreeIndex ==0 ) return 0;
if (fBranch==0) return 0;
if (index>fTreeIndex->fN) return 0;
AliSegmentID *s = (AliSegmentID*)fSegment->At(index);
if (s==0) s= NewSegment();
if (s!=0) {
s->SetID(index);
Int_t treeIndex =(*fTreeIndex)[index];
if (treeIndex<1) return 0;
else treeIndex--;
fBranch->SetAddress(&s);
fTree->GetEvent(treeIndex);
fSegment->AddAt((TObject*) s, index);
}
else
return 0;
return s;
}
AliSegmentID *AliSegmentArray::LoadEntry(Int_t index)
{
if (fBranch==0) return 0;
if (index>fTree->GetEntries()) return 0;
AliSegmentID * s = NewSegment();
if (s) {
fBranch->SetAddress(&s);
fTree->GetEvent(index);
}
else
return 0;
Int_t nindex = s->GetID();
ClearSegment(nindex);
fSegment->AddAt((TObject*) s, nindex);
return s;
}
void AliSegmentArray::StoreSegment(Int_t index)
{
const AliSegmentID * ksegment = (*this)[index];
if (ksegment == 0 ) return;
if (fTree==0) MakeTree();
fBranch->SetAddress(&ksegment);
fTree->Fill();
}
void AliSegmentArray::Streamer(TBuffer &R__b)
{
TObjString treeName, * ptreeName=&treeName;
if (R__b.IsReading()) {
Version_t R__v = R__b.ReadVersion(); if (R__v) { }
TNamed::Streamer(R__b);
R__b>>ptreeName;
if (fTree && fTreeOwner) delete fTree;
ConnectTree(ptreeName->String());
} else {
R__b.WriteVersion(AliSegmentArray::IsA());
TNamed::Streamer(R__b);
treeName.String() = fTree->GetTitle();
R__b<<ptreeName;
fTree->Write();
}
}