#include "hloop.h"
#include "hades.h"
#include "htree.h"
#include "hrecevent.h"
#include "hpartialevent.h"
#include "heventheader.h"
#include "hgeantheader.h"
#include "hcategory.h"
#include "htool.h"
#include "htime.h"
#include "hrootsource.h"
#include "hruntimedb.h"
#include "htaskset.h"
#include "TDirectory.h"
#include "TROOT.h"
#include "TGlobal.h"
#include "TList.h"
#include "TKey.h"
#include "TObject.h"
#include "TString.h"
#include "TObjString.h"
#include "TObjArray.h"
#include "TCollection.h"
#include "TOrdCollection.h"
#include "TChainElement.h"
#include "TSystem.h"
#include <iostream>
#include <fstream>
#include <iomanip>
ClassImp(HLoop)
HLoop *gLoop=0;
HLoop::HLoop(Bool_t createHades)
{
gLoop = this;
fChain = new TChain("T");
fHead = NULL;
fTree = NULL;
fFileCurrent = NULL;
fGeantMedia = NULL;
fMaxEntries = 0;
fCurrentEntry = 0;
fCurrentName ="unset";
fIsNewFile = kTRUE;
fIsSkipped = kFALSE;
fUseTaskSet = kFALSE;
fHasCreatedHades = kFALSE;
fRefID = -1;
fFirstEvent = kTRUE;
fTreeCacheSize = 8000000;
fTreeCacheDefaultSize = 8000000;
fIsCacheSet = kFALSE;
fRecEvent = new HRecEvent();
for(Int_t s=0;s<6;s++) fsectors[s]=1;
if(createHades){
if(gHades == 0) {
fHasCreatedHades = kTRUE;
Hades* hades = new Hades();
hades->setEvent(fRecEvent);
Info("HLoop()","HADES created and event structure set !" );
} else {
Error("HLoop()","HADES already exists, but should be created new! Check your macro ..." );
exit(1);
}
} else {
if(gHades != 0) {
gHades->setEvent(fRecEvent);
Info("HLoop()","HADES already exists, event structure replaced !" );
} else {
Info("HLoop()","HADES does not exists! No functions via gHades will be available!" );
}
}
}
HLoop::~HLoop()
{
delete fChain;
if(fHasCreatedHades && gHades) delete gHades;
if(fGeantMedia) delete fGeantMedia;
}
void HLoop::setTreeCacheSize(Long64_t cs )
{
fTreeCacheSize = cs;
fIsCacheSet = kTRUE;
}
Bool_t HLoop::addFile (TString infile)
{
TObjArray* elements = fChain->GetListOfFiles();
Int_t nfiles = elements->GetEntries();
if(gSystem->AccessPathName(infile.Data()) == 0) {
cout<<setw(4)<<nfiles<<" add file : "<<infile.Data()<<endl;
fChain->AddFile(infile.Data());
return kTRUE;
} else {
Error("addFile()","File = %s not found! Will be skipped .... ",infile.Data());
return kFALSE;
}
}
Bool_t HLoop::addFiles(TString expression){
TObjArray* arr = HTool::glob(expression);
Int_t n = arr->GetEntries();
if(n == 0) {
Warning("addFiles()","No file matching expression '%s' found !",expression.Data());
} else {
for(Int_t i = 0; i < n; i ++){
TString name = ((TObjString*)arr->At(i))->GetString();
addFile(name);
}
}
delete arr;
return kTRUE;
}
Bool_t HLoop::addFilesList(TString filelist)
{
if(gSystem->AccessPathName(filelist.Data()) == 0 )
{
ifstream in;
in.open(filelist.Data());
TString name;
Char_t line[10000];
while(!in.eof()){
in.getline(line,10000);
name=line;
name.ReplaceAll(" ","");
if(!in.fail() &&
name.CompareTo("") !=0 &&
name.BeginsWith("#")==0
)
{
addFile(name);
}
}
in.close();
return kTRUE;
} else {
Error("addFilesList()","File = %s not found! Will be skipped .... ",filelist.Data());
return kFALSE;
}
}
Bool_t HLoop::addMultFiles(TString commaSeparatedList)
{
TObjArray* arr = commaSeparatedList.Tokenize(",");
Int_t n = arr->GetEntries();
if(n == 0) {
Warning("addMultFiles()","No file in input string '%s' found !",commaSeparatedList.Data());
} else {
for(Int_t i = 0; i < n; i ++){
TString name = ((TObjString*)arr->At(i))->GetString();
if(!addFile(name)){
delete arr;
return kFALSE;
}
}
}
delete arr;
return kTRUE;
}
Bool_t HLoop::setInput(TString readCategories)
{
TObjArray* fList = fChain->GetListOfFiles();
if(fList->GetEntries() == 0){
Error("setInput()","No File in List!");
return kFALSE;
}
TChainElement* el = (TChainElement*)fList->At(0);
TString file = el->GetTitle();
TFile* fIn = (TFile*)gROOT->GetListOfFiles()->FindObject(file.Data());
if (!fIn) {
fIn = new TFile(file.Data());
if (!fIn) {
Error("setFile()","Could not open infile %s",file.Data());
return kFALSE;
}
}
fIn->cd();
fChain->LoadTree(0);
fTree = (HTree*) fChain->GetTree();
if(!fTree) {
Error("setInput()","Could not find Tree in infile %s",file.Data());
return kFALSE;
}
fGeantMedia = (HGeantMedia*) fIn->Get("GeantMedia");
fHead = fRecEvent->getHeader();
TBranch* brhead = fTree->GetBranch("EventHeader.");
if(!brhead) {
Error("setFile()","Eventheader Branch not found !");
return kFALSE;
} else {
fChain->SetBranchAddress("EventHeader.",&fHead);
fChain->SetBranchStatus("EventHeader.",1);
fChain->SetBranchStatus("EventHeader.*",1);
}
fChain->SetBranchStatus("Event.",0);
fChain->SetBranchStatus("Event.*",0);
TList* dirkeys = gDirectory->GetListOfKeys();
for(Int_t d = 0; d < dirkeys->GetEntries(); d ++){
TKey* kdir = (TKey*)dirkeys->At(d);
TString dirname = kdir->GetName();
if(dirname.BeginsWith("dir"))
{
TString partialEvent = dirname;
partialEvent.ReplaceAll("dir","");
if(fIn->cd(dirname.Data()) )
{
TList* catkeys = gDirectory->GetListOfKeys();
for(Int_t c = 0; c <catkeys->GetEntries(); c ++)
{
fIn->cd(dirname.Data());
TKey* kcat = (TKey*) catkeys->At(c);
TString catname = kcat->GetName();
TString classname = kcat->GetClassName();
if(classname == "HPartialEvent") {
fPartial[catname] = (HPartialEvent*) gDirectory->Get(catname.Data());
if(!fPartial[catname]) {
Error("setInput()","NULL pointer for partial event %s retrieved!",catname.Data()) ;
return kFALSE;
}
TBranch* br = fTree->GetBranch(Form("%s.",catname.Data()));
if(!br) {
Error("setInput()","Branch not found : %s !",Form("%s.",catname.Data()));
return kFALSE;
} else {
fChain->SetBranchAddress(Form("%s.",catname.Data()),&fPartial[catname]);
fChain->SetBranchStatus (Form("%s.",catname.Data()),1);
fChain->SetBranchStatus (Form("%s.*",catname.Data()),1);
}
fRecEvent->addPartialEvent(fPartial[catname]);
continue;
}
if(classname == "HLinearCategory" || classname == "HMatrixCategory")
{
fEvent[catname] = (HCategory*) gDirectory->Get(catname.Data());
if(!fEvent[catname]) {
Error("setInput()","NULL pointer for category %s retrieved!",catname.Data()) ;
return kFALSE;
}
fStatus [catname] = 0;
fPartialN[catname] = partialEvent;
TBranch* br = fTree->GetBranch(Form("%s.",catname.Data()));
if(!br) {
Error("setInput()","Branch not found : %s !",Form("%s.",catname.Data()));
return kFALSE;
} else {
fChain->SetBranchAddress(Form("%s.",catname.Data()),&fEvent[catname]);
fChain->SetBranchStatus (Form("%s.",catname.Data()),1);
fChain->SetBranchStatus (Form("%s.*",catname.Data()),1);
fStatus[catname] = 1;
}
}
}
} else {
Error("setInput()","Could no enter dir %s !",dirname.Data());
return kFALSE;
}
}
}
fIn->cd();
fMaxEntries = fTree->GetEntries();
TString readCat = readCategories;
readCat.ReplaceAll(" ","");
TObjArray* catNames = readCat.Tokenize(",");
Int_t n = catNames->GetEntries();
for(Int_t i = 0; i < n; i ++){
TString name = ((TObjString*)catNames->At(i))->GetString();
if(i == 0){
if(name.CompareTo("-*") == 0){
setStatus("-*", 0);
continue;
}
} else {
if(name.Contains("*") != 0){
Warning("setInput()","Wild cards are only supported for '-*' in the first position of the string! Will ignore this one!");
continue;
}
}
if(name.BeginsWith("+")) {
name.ReplaceAll("+","");
if(getCategory(name)) {
setStatus(name, 1);
}
}
if(name.BeginsWith("-")) {
name.ReplaceAll("-","");
if(getCategory(name)) {
setStatus(name, 0);
}
}
}
if(n == 0) {
map<TString,HCategory*>::iterator iter;
for( iter = fEvent.begin(); iter != fEvent.end(); ++iter ) {
addCatName(iter->first,getCategory(iter->first)->getCategory());
}
} else {
map<TString,Int_t>::iterator iter;
for( iter = fStatus.begin(); iter != fStatus.end(); ++iter ) {
if(iter->second == 1 ) {
addCatName(iter->first,getCategory(iter->first)->getCategory());
}
}
}
fIn->Close();
printChain();
Long64_t cs = fChain->GetCacheSize();
if(!fIsCacheSet ){
cs = fTreeCacheDefaultSize;
} else {
cs = fTreeCacheSize;
}
if(fTreeCacheSize > 0) Info("setInput()","Setting Tree Cache size = %lld byte.",cs);
else Info("setInput()","Tree cache is disabled");
if(cs > 0){
fChain->SetCacheSize(cs);
}
return kTRUE;
}
void HLoop::printCategories()
{
cout<<"--------------------------------------"<<endl;
cout<<"current event :"<<endl;
map<TString,HCategory*>::iterator iter;
for( iter = fEvent.begin(); iter != fEvent.end(); ++iter ) {
cout << setw(20)<<iter->first.Data() << " = " << iter->second <<" status = "<<fStatus[iter->first]<< endl;
}
cout<<"--------------------------------------"<<endl;
}
void HLoop::printChain()
{
TObjArray* elements = fChain->GetListOfFiles();
cout<<"--------------------------------------"<<endl;
cout<<" Analize Chain : .... Can take while for N file = "<<elements->GetEntries()<<endl;
fMaxEntries = fChain->GetEntries();
cout<<"N total entries = "<<fMaxEntries<<endl;
for(Int_t i = 0; i < elements->GetEntries(); ++i ) {
TChainElement* element = (TChainElement*)elements->At(i);
cout <<setw(4)<<i<< setw(80)<<element->GetTitle() << ", N entries = " << element->GetEntries()<< endl;
}
cout<<"--------------------------------------"<<endl;
}
void HLoop::printBranchStatus()
{
cout<<"--------------------------------------"<<endl;
cout<<"Branch status :"<<endl;
TObjArray* branches = fChain->GetListOfBranches();
for(Int_t i = 0; i < branches ->GetEntries(); ++i ) {
TBranch* br = (TBranch*) branches->At(i);
cout <<setw(4)<<i<< setw(30)<<br->GetName() << ", status = " <<(Int_t) fChain->GetBranchStatus(br->GetName())<< endl;
}
cout<<"--------------------------------------"<<endl;
}
void HLoop::clearCategories()
{
map<TString,HCategory*>::iterator iter;
for( iter = fEvent.begin(); iter != fEvent.end(); ++iter ) {
if(fStatus[iter->first]) iter->second->Clear();
}
}
HCategory* HLoop::getCategory(TString catname,Bool_t silent)
{
TString simname = catname;
TString realname = catname;
if(realname.EndsWith("Sim")==1) realname.Replace(realname.Length(),3,"");
if(simname .EndsWith("Sim")==0) simname+="Sim";
map<TString,HCategory*>::iterator iter = fEvent.find(realname);
if( iter == fEvent.end() ){
iter = fEvent.find(simname);
if(iter == fEvent.end()){
if(!silent)Error("getCategory()","Category \"%s\" not found!",catname.Data());
return 0;
} else return iter->second;
} else return iter->second;
}
Bool_t HLoop::getCategoryStatus(TString catname,Bool_t silent)
{
map<TString,Int_t>::iterator iter = fStatus.find(catname);
if( iter == fStatus.end() ){
if(!silent)Error("getCategory()","Category \"%s\" not found!",catname.Data());
return kFALSE;
} else {
return (Bool_t)fStatus[catname];
}
}
HPartialEvent* HLoop::getPartialEvent(TString catname,Bool_t silent)
{
map<TString,HPartialEvent*>::iterator iter = fPartial.find(catname);
if( iter == fPartial.end() ){
if(!silent)Error("getPartialEvent()","PartialEvent \"%s\" not found!",catname.Data());
return 0;
}
else return iter->second;
}
HGeantHeader* HLoop::getGeantHeader(Bool_t silent)
{
HPartialEvent* pEvt = getPartialEvent("Simul",silent);
HGeantHeader* header = NULL;
if(pEvt) header = (HGeantHeader*) pEvt->getSubHeader();
return header;
}
Bool_t HLoop::setStatus(TString catname, Int_t stat )
{
if(catname.CompareTo("-*") == 0 || catname.CompareTo("+*") == 0 ){
map<TString,HCategory*>::iterator iter;
for( iter = fEvent.begin(); iter != fEvent.end(); ++iter ) {
if(catname.CompareTo("-*") == 0) {
fChain->SetBranchStatus(Form("%s.",iter->first.Data()),0);
fChain->SetBranchStatus(Form("%s.*",iter->first.Data()),0);
fStatus[iter->first] = 0;
}
if(catname.CompareTo("+*") == 0) {
fChain->SetBranchStatus(Form("%s.",iter->first.Data()),1);
fChain->SetBranchStatus(Form("%s.*",iter->first.Data()),1);
fStatus[iter->first] = 1;
}
}
return kTRUE;
}
if(!getCategory(catname)) {
return kFALSE;
}
TString simname = catname;
TString realname = catname;
if(realname.EndsWith("Sim")==1) realname.Replace(realname.Length(),3,"");
if(simname .EndsWith("Sim")==0) simname+="Sim";
map<TString,Int_t>::iterator iter = fStatus.find(realname);
if( iter == fStatus.end() ){
iter = fStatus.find(simname);
if( iter == fStatus.end() ) {
Error("getCategory()","Category \"%s\" not found!",catname.Data());
return kFALSE;
} else {
fChain->SetBranchStatus(Form("%s.",simname.Data()),stat);
fChain->SetBranchStatus(Form("%s.*",simname.Data()),stat);
iter->second = stat;
return kTRUE;
}
}
else {
fChain->SetBranchStatus(Form("%s.",realname.Data()),stat);
fChain->SetBranchStatus(Form("%s.*",realname.Data()),stat);
iter->second = stat;
return kTRUE;
}
return kFALSE;
}
Int_t HLoop::nextEvent(Int_t iev)
{
if(!fHead) {
Warning("nextEvent()","File not initialized ! Call setInput(....) before!");
exit(1);
}
fCurrentEntry = iev;
clearCategories();
Int_t nbytes = fChain->GetEntry(fCurrentEntry);
if(nbytes == 0) {
Warning("nextEvent()","Entry %i not found!",(Int_t)fCurrentEntry);
} else if(nbytes == -1) {
Warning("nextEvent()","Entry %i read with Io error!",(Int_t)fCurrentEntry);
}
TString name = fChain->GetFile()->GetName();
if(name != fCurrentName) {
fIsNewFile = kTRUE;
Int_t entries = 0;
TObjArray* elements = fChain->GetListOfFiles();
for(Int_t i = 0; i < elements->GetEntries(); ++i ) {
TChainElement* element = (TChainElement*)elements->At(i);
if(name.CompareTo(element->GetTitle() ) == 0) {
entries = element->GetEntries();
break;
}
}
fCurrentName = fChain->GetFile()->GetName() ;
fFileCurrent = fChain->GetFile() ;
fTree = fChain->GetTree() ;
for (Int_t s=0;s<6;s++){ fsectors[s]=1;}
if(fSectorSelector.getNFiles() > 0){
TString hldname = HTime::stripFileName(fCurrentName,kTRUE,kTRUE);
if(hldname != "" ) {
fSectorSelector.getSectors(fsectors,hldname);
}
}
cout<<"---------------------------------------------------------"<<endl;
cout<<name.Data() <<", sectors : "<<fsectors[0]<<" "<<fsectors[1]<<" "<<fsectors[2]<<" "<<fsectors[3]<<" "<<fsectors[4]<<" "<<fsectors[5]<<" "<<endl;
cout<<"at entry "<<setw(8)<<fCurrentEntry<<" with entries = "<<entries<<endl;
cout<<"---------------------------------------------------------"<<endl;
} else {
fIsNewFile = kFALSE;
}
if(fFirstEvent){
if(gHades){
const TObjArray* l = gHades->getTaskList();
HTaskSet* task;
TIter iter(l);
Int_t ct = 0 ;
while((task = (HTaskSet*)iter())) {
TOrdCollection* list = task->getSetOfTask();
ct += list->GetEntries();
}
if(ct > 0) fUseTaskSet = kTRUE;
if(fUseTaskSet && gHades->getSetup() == 0 ) {
Error("","TaskSet used, but Spectrometer not set!"); exit(1);
fUseTaskSet = kFALSE;
}
if(fUseTaskSet){
HRootSource* source = new HRootSource();
source->addFile((Text_t*)fCurrentName.Data());
source->setCurrentRunId(fHead->getEventRunNumber());
source->setGlobalRefId(fRefID);
gHades->setDataSource(source);
if(!gHades->init(kTRUE)){ Error("","HADES init failed!"); exit(1);}
HRuntimeDb* rtdb = gHades->getRuntimeDb();
if (rtdb){
if(!rtdb->initContainers(fHead->getEventRunNumber(),
fRefID,
fCurrentName.Data())
){
Error("","Rtdb init failed!"); exit(1);
}
}
gHades->reinitTasks();
gHades->printDefinedTaskSets ();
rtdb->disconnectInputs();
}
}
fFirstEvent = kFALSE;
}
if(fUseTaskSet && !fFirstEvent && gHades && fIsNewFile){
HRootSource* source = (HRootSource*)gHades->getDataSource();
if(source){
HRuntimeDb* rtdb = gHades->getRuntimeDb();
rtdb->reconnectInputs();
source->setCurrentRunId(fHead->getEventRunNumber());
source->setGlobalRefId(fRefID);
if(!rtdb->initContainers(fHead->getEventRunNumber(),
fRefID,
fCurrentName.Data())
){
Error("","Rtdb init failed!"); exit(1);
}
gHades->reinitTasks();
rtdb->disconnectInputs();
}
}
if(fUseTaskSet && gHades){
Int_t retVal = gHades->executeTasks();
if(retVal == kSkipEvent){
fIsSkipped = kTRUE;
fRecEvent->Clear();
} else {
fIsSkipped = kFALSE;
}
}
return nbytes;
}
Bool_t HLoop::addCatName(TString catname,Short_t catNum)
{
if(fHead == 0) {
Error("addCatName()","You have to call setInput() before calling this function !");
exit(1);
}
map<TString,Short_t>::iterator iter = fNameToCat.find(catname);
if( iter == fNameToCat.end() ){
if(getCategory(catname,kTRUE)){
Bool_t ret = fRecEvent->addCategory((Cat_t)catNum,getCategory(catname),fPartialN[catname].Data());
fNameToCat[catname] = catNum;
return ret;
} else {
Error("addCatName()","Category \"%s\" does not exists in input! Will skip ...",catname.Data());
return kFALSE;
}
} else {
Error("addCatName()","Category \"%s\" already exists with number = %i!",catname.Data(),fNameToCat[catname]);
return kFALSE;
}
return kTRUE;
}
Bool_t HLoop::isNewFile(TString& name)
{
name = fCurrentName;
return fIsNewFile;
}
TObject* HLoop::getFromInputFile(TString name)
{
if(name=="") return 0;
if(fFileCurrent){
TDirectory* dold = gDirectory;
fFileCurrent->cd();
TObject* obj = fFileCurrent->Get(name.Data());
dold->cd();
return obj;
} else return 0;
}