/** @file CbmFileSource.cxx ** @author Mohammad Al-Turany ** @author Christian Simon ** @since 08.02.2014 ** @date 17.05.2017 **/ #include "CbmFileSource.h" #include "TString.h" #include "FairEventHeader.h" #include "FairFileHeader.h" #include "FairFileInfo.h" #include "FairMCEventHeader.h" #include "FairLogger.h" #include "TObjArray.h" #include #include #include // for find #include "TChainElement.h" #include "TFolder.h" #include "FairRuntimeDb.h" // for FairRuntimeDb #include "FairRootManager.h" #include "TRandom.h" // for TRandom, gRandom #include "TRegexp.h" #include "TSystemDirectory.h" #include "TSystem.h" #include "TROOT.h" #include // for _List_iterator, list, etc using std::map; using std::set; //_____________________________________________________________________________ CbmFileSource::CbmFileSource(TFile *f, const char* Title, UInt_t) :FairSource() , fInputTitle(Title) , fRootFile(f) , fCurrentEntryNr(0) , fFriendFileList() , fInputChainList() , fFriendTypeList() , fCheckInputBranches() , fInputLevel() , fRunIdInfoAll() , fInChain(0) , fInTree(0) , fListFolder(new TObjArray(16)) , fRtdb(FairRuntimeDb::instance()) , fCbmout(0) , fCbmroot(0) , fSourceIdentifier(0) , fNoOfEntries(-1) , IsInitialized(kFALSE) , fMCHeader(0) , fEvtHeader(0) , fFileHeader(0) , fEventTimeInMCHeader(kTRUE) , fEvtHeaderIsNew(kFALSE) , fCurrentEntryNo(0) , fTimeforEntryNo(-1) , fEventTimeMin(0.) , fEventTimeMax(0.) , fEventTime(0.) , fBeamTime(-1.) , fGapTime(-1.) , fEventMeanTime(0.) , fEventTimeOffset(0.) , fTimeProb(0) , fCheckFileLayout(kTRUE) , fiMaxSpillNo(-1) , fiCurrentSpillIndex(0) { if (fRootFile->IsZombie()) { LOG(FATAL) << "Error opening the Input file" << FairLogger::endl; } LOG(DEBUG) << "CbmFileSource created------------" << FairLogger::endl; } //_____________________________________________________________________________ //_____________________________________________________________________________ CbmFileSource::CbmFileSource(const TString* RootFileName, const char* Title, UInt_t) :FairSource() , fInputTitle(Title) , fRootFile(0) , fCurrentEntryNr(0) , fFriendFileList() , fInputChainList() , fFriendTypeList() , fCheckInputBranches() , fInputLevel() , fRunIdInfoAll() , fInChain(0) , fInTree(0) , fListFolder(new TObjArray(16)) , fRtdb(FairRuntimeDb::instance()) , fCbmout(0) , fCbmroot(0) , fSourceIdentifier(0) , fNoOfEntries(-1) , IsInitialized(kFALSE) , fMCHeader(0) , fEvtHeader(0) , fFileHeader(0) , fEventTimeInMCHeader(kTRUE) , fEvtHeaderIsNew(kFALSE) , fCurrentEntryNo(0) , fTimeforEntryNo(-1) , fEventTimeMin(0.) , fEventTimeMax(0.) , fEventTime(0.) , fBeamTime(-1.) , fGapTime(-1.) , fEventMeanTime(0.) , fEventTimeOffset(0.) , fTimeProb(0) , fCheckFileLayout(kTRUE) , fiMaxSpillNo(-1) , fiCurrentSpillIndex(0) { fRootFile = new TFile(RootFileName->Data()); if (fRootFile->IsZombie()) { LOG(FATAL) << "Error opening the Input file" << FairLogger::endl; } LOG(DEBUG) << "CbmFileSource created------------" << FairLogger::endl; } //_____________________________________________________________________________ //_____________________________________________________________________________ CbmFileSource::CbmFileSource(const TString RootFileName, const char* Title, UInt_t) :FairSource() , fInputTitle(Title) , fRootFile(0) , fCurrentEntryNr(0) , fFriendFileList() , fInputChainList() , fFriendTypeList() , fCheckInputBranches() , fInputLevel() , fRunIdInfoAll() , fInChain(0) , fInTree(0) , fListFolder(new TObjArray(16)) , fRtdb(FairRuntimeDb::instance()) , fCbmout(0) , fCbmroot(0) , fSourceIdentifier(0) , fNoOfEntries(-1) , IsInitialized(kFALSE) , fMCHeader(0) , fEvtHeader(0) , fFileHeader(0) , fEventTimeInMCHeader(kTRUE) , fEvtHeaderIsNew(kFALSE) , fCurrentEntryNo(0) , fTimeforEntryNo(-1) , fEventTimeMin(0.) , fEventTimeMax(0.) , fEventTime(0.) , fBeamTime(-1.) , fGapTime(-1.) , fEventMeanTime(0.) , fEventTimeOffset(0.) , fTimeProb(0) , fCheckFileLayout(kTRUE) , fiMaxSpillNo(-1) , fiCurrentSpillIndex(0) { fRootFile = new TFile(RootFileName.Data()); if (fRootFile->IsZombie()) { LOG(FATAL) << "Error opening the Input file" << FairLogger::endl; } LOG(DEBUG) << "CbmFileSource created------------" << FairLogger::endl; } //_____________________________________________________________________________ //_____________________________________________________________________________ CbmFileSource::~CbmFileSource() { } //_____________________________________________________________________________ //_____________________________________________________________________________ Bool_t CbmFileSource::Init() { if(IsInitialized){ LOG(INFO) << "CbmFileSource already initialized" << FairLogger::endl; return kTRUE; } // Check if (first) input file has been added to FairFileHeader. // If not, add it here. if(fFileHeader) { FairFileInfo* tInputFileInfo = fFileHeader->GetFileInfo(0, 0); if(tInputFileInfo) { tInputFileInfo->SetName(fRootFile->GetName()); tInputFileInfo->SetSize(fRootFile->GetSize()); // (Absolute) file paths are not properly treated in FairFileInfo if(((TString)fRootFile->GetName()).BeginsWith("/")) { tInputFileInfo->SetPath((TString)fRootFile->GetName()); } else { tInputFileInfo->SetPath((TString)gSystem->WorkingDirectory() + "/" + (TString)fRootFile->GetName()); } } else { fFileHeader->AddInputFile(fRootFile, 0, 0); // (Absolute) file paths are not properly treated in FairFileInfo tInputFileInfo = fFileHeader->GetFileInfo(0, 0); if(((TString)fRootFile->GetName()).BeginsWith("/")) { tInputFileInfo->SetPath((TString)fRootFile->GetName()); } else { tInputFileInfo->SetPath((TString)gSystem->WorkingDirectory() + "/" + (TString)fRootFile->GetName()); } } } else { LOG(FATAL) << "FairFileHeader not known to CbmFileSource!" << FairLogger::endl; } if (!fInChain ) { fInChain = new TChain(FairRootManager::GetTreeName(), "/cbmroot"); LOG(DEBUG) << "CbmFileSource::Init() chain created" << FairLogger::endl; FairRootManager::Instance()->SetInChain(fInChain); } fInChain->Add( fRootFile->GetName() ); // Get the folder structure from file which describes the input tree. // There are two different names possible, so check both. fCbmroot= dynamic_cast (fRootFile->Get("cbmroot")); if(!fCbmroot) { fCbmroot= dynamic_cast (fRootFile->Get("cbmout")); if(!fCbmroot) { fCbmroot= gROOT->GetRootFolder()->AddFolder("cbmroot", "Main Folder"); } else { fCbmroot->SetName("cbmroot"); } } // Get The list of branches from the input file and add it to the // actual list of existing branches. // Add this list of branches also to the map of input trees, which // stores the information which branches belong to which input tree. // There is at least one primary input tree, but there can be many // additional friend trees. // This information is needed to add new files to the correct friend // tree. With this information it is also possible to check if the // input files which are added to the input chain all have the same // branch structure. Without this check it is possible to add trees // with a different branch structure but the same tree name. ROOT // probably only checks if the name of the tree is the same. TList* list= dynamic_cast (fRootFile->Get("BranchList")); if(list==0) { LOG(FATAL) << "No Branch list in input file" << FairLogger::endl; } TString chainName = fInputTitle; TString ObjName; fInputLevel.push_back(chainName); fCheckInputBranches[chainName] = new std::list; if(list) { TObjString* Obj=0; LOG(DEBUG) << "Enteries in the list " << list->GetEntries() << FairLogger::endl; for(Int_t i =0; i< list->GetEntries(); i++) { Obj=dynamic_cast (list->At(i)); if(Obj!=0){ ObjName=Obj->GetString(); LOG(DEBUG) << "Branch name " << ObjName.Data() << FairLogger::endl; fCheckInputBranches[chainName]->push_back(ObjName.Data()); FairRootManager::Instance()->AddBranchToList(ObjName.Data()); } } } gROOT->GetListOfBrowsables()->Add(fCbmroot); fListFolder->Add( fCbmroot ); // Store the information about the unique runids in the input file // together with the filename and the number of events for each runid // this information is needed later to check if inconsitencies exist // between the main input chain and any of the friend chains. // GetRunIdInfo(fInFile->GetName(), chainName); // Add all additional input files to the input chain and do a // consitency check Int_t iFileInChain(1); std::list::const_iterator iter; for(iter = fInputChainList.begin(); iter != fInputChainList.end(); iter++) { // Store global gFile pointer for safety reasons. // Set gFile to old value at the end of the routine.R TFile* temp = gFile; // Temporarily open the input file to extract information which // is needed to bring the friend trees in the correct order TFile* inputFile = new TFile((*iter)); if (inputFile->IsZombie()) { LOG(FATAL) << "Error opening the file " << (*iter).Data() << " which should be added to the input chain or as friend chain" << FairLogger::endl; } if (fCheckFileLayout) { // Check if the branchlist is the same as for the first input file. Bool_t isOk = CompareBranchList(inputFile, chainName); if ( !isOk ) { LOG(FATAL) << "Branch structure of the input file " << fRootFile->GetName() << " and the file to be added " << (*iter).Data() << " are different." << FairLogger::endl; return kFALSE; } } // Add the runid information for all files in the chain. //GetRunIdInfo(inputFile->GetName(), chainName); // Add the file to the input chain fInChain->Add( (*iter) ); // Add input file to FairFileHeader fFileHeader->AddInputFile(inputFile, 0, iFileInChain); // (Absolute) file paths are not properly treated in FairFileInfo FairFileInfo* tInputFileInfo = fFileHeader->GetFileInfo(0, iFileInChain); if(((TString)inputFile->GetName()).BeginsWith("/")) { tInputFileInfo->SetPath((TString)inputFile->GetName()); } else { tInputFileInfo->SetPath((TString)gSystem->WorkingDirectory() + "/" + (TString)inputFile->GetName()); } // Close the temporarly file and restore the gFile pointer. inputFile->Close(); gFile = temp; iFileInChain++; } fNoOfEntries = fInChain->GetEntries(); LOG(DEBUG) << "Entries in this Source " << fNoOfEntries << FairLogger::endl; for(Int_t i=0; iGetEntriesFast(); i++) { TFolder* fold = static_cast(fListFolder->At(i)); fEvtHeader = static_cast(fold->FindObjectAny("EventHeader.")); fMCHeader = static_cast(fold->FindObjectAny("MCEventHeader.")); if ( fEvtHeader ) { ActivateObject(reinterpret_cast(&fEvtHeader),"EventHeader."); } if ( fMCHeader ) { ActivateObject(reinterpret_cast(&fMCHeader),"MCEventHeader."); } } FairRootManager::Instance()->SetListOfFolders(fListFolder); AddFriendsToChain(); TList* timebasedlist= dynamic_cast (fRootFile->Get("TimeBasedBranchList")); if(timebasedlist==0) { LOG(WARNING) << "No time based branch list in input file" << FairLogger::endl; }else{ FairRootManager::Instance()->SetTimeBasedBranchNameList(timebasedlist); } fEventTime = fEventTimeOffset; return kTRUE; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetInTree(TTree* tempTree) { fInTree = NULL; fInTree = tempTree; fRootFile=static_cast(tempTree->GetCurrentFile()); fInChain->Reset(); IsInitialized=kFALSE; Init(); } //_____________________________________________________________________________ //_____________________________________________________________________________ Int_t CbmFileSource::ReadEvent(UInt_t i) { fCurrentEntryNo = i; SetEventTime(); if(0 > fiMaxSpillNo || fiCurrentSpillIndex < fiMaxSpillNo) { if ( fInChain->GetEntry(i) ) return 0; } // When the maximum number of spills has been simulated, the start time of // a hypothetical event after the last one is set to the end time of // the last simulated spill to keep untreated interference between detector // noise from the current simulation run and data from a subsequent run // to be concatenated in time with the current one at a minimal level. if(fiCurrentSpillIndex == fiMaxSpillNo) { fEventTime = fEventTimeOffset + static_cast(fiCurrentSpillIndex)*(fBeamTime + fGapTime); } return 1; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::Close() { CloseInFile(); } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::Reset() { } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::AddFriend(TString fName) { fFriendFileList.push_back(fName); } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::AddFile(TString FileName) { fInputChainList.push_back(FileName); } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::AddPath(const TString& directoryName, const TString& fileNameWildCard) { FileStat_t tFileStat; if(1 == gSystem->GetPathInfo(directoryName.Data(), tFileStat)) { LOG(FATAL) << TString::Format("\nInput data file directory %s does not " "exist.", directoryName.Data() ).Data() << FairLogger::endl; } TRegexp* tRegexp = new TRegexp(fileNameWildCard.Data(), kTRUE); TSystemDirectory* tSystemDirectory = new TSystemDirectory("dir", directoryName.Data()); TString tTargetDirectoryName(directoryName); if(!tTargetDirectoryName.EndsWith("/")) { tTargetDirectoryName += "/"; } TList* tList = tSystemDirectory->GetListOfFiles(); tList->Sort(); TIterator* tIter = tList->MakeIterator(); TSystemFile* tSystemFile; TString tFileName; Bool_t bIsFirstFile(kTRUE); while(NULL != (tSystemFile = (TSystemFile*)tIter->Next())) { tFileName = tSystemFile->GetName(); if(tFileName.Contains(*tRegexp)) { tFileName = tTargetDirectoryName + tFileName; if(bIsFirstFile) { SetInputFile(tFileName); bIsFirstFile = kFALSE; } else { AddFile(tFileName); } } } tList->Delete(); } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::AddFriendsToChain() { // Loop over all Friend files and extract the type. The type is defined by // the tree which is stored in the file. If there is already a chain of with // this type of tree then the file will be added to this chain. // If there is no such chain it will be created. // // Check if the order of runids and the event numbers per runid for all // friend chains is the same as the one defined by the input chain. // TODO: Should the order be corrected or should the execution be stopped. // The order in the input tree defined by the order in which the files have // been added. A file is defined by the runid. // In the old way it was needed sometimes to add a freind file more // than once. This is not needed any longer, so we remove deuplicates // from the list and display a warning. std::list friendList; std::list::iterator iter1; for(iter1 = fFriendFileList.begin(); iter1 != fFriendFileList.end(); iter1++) { if (find(friendList.begin(), friendList.end(), (*iter1)) == friendList.end()) { friendList.push_back(*iter1); } } // TODO: print a warning if it was neccessary to remove a filname from the // list. This can be chacked by comparing the size of both list TFile* temp = gFile; Int_t friendType = 1; // Loop over all files which have been added as friends for(iter1 = friendList.begin(); iter1 != friendList.end(); iter1++) { std::list::iterator iter; TString inputLevel; // Loop over all already defined input levels to check if this type // of friend tree is already added. // If this type of friend tree already exist add the file to the // then already existing friend chain. If this type of friend tree // does not exist already create a new friend chain and add the file. Bool_t inputLevelFound = kFALSE; TFile* inputFile; for ( iter = fInputLevel.begin(); iter !=fInputLevel.end(); iter++ ) { inputLevel = (*iter); inputFile = new TFile((*iter1)); if (inputFile->IsZombie()) { LOG(FATAL) << "Error opening the file " << (*iter).Data() << " which should be added to the input chain or as friend chain" << FairLogger::endl; } // Check if the branchlist is already stored in the map. If it is // already stored add the file to the chain. Bool_t isOk = CompareBranchList(inputFile, inputLevel); if ( isOk ) { inputLevelFound = kTRUE; inputFile->Close(); continue; } inputFile->Close(); } if (!inputLevelFound) { inputLevel= Form("FriendTree_%i",friendType); CreateNewFriendChain((*iter1), inputLevel); friendType++; } TChain* chain = static_cast(fFriendTypeList[inputLevel]); chain->AddFile((*iter1), 1234567890, FairRootManager::GetTreeName()); } gFile=temp; // Check if all friend chains have the same runids and the same // number of event numbers as the corresponding input chain // CheckFriendChains(); // Add all the friend chains which have been created to the // main input chain. std::map< TString, TChain* >::iterator mapIterator; for (mapIterator = fFriendTypeList.begin(); mapIterator != fFriendTypeList.end(); mapIterator++ ) { TChain* chain = static_cast(mapIterator->second); fInChain->AddFriend(chain); } // Print some output about the input structure PrintFriendList(); } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::PrintFriendList( ) { // Print information about the input structure // List files from the input chain together with all files of // all friend chains LOG(INFO) << "The input consists out of the following trees and files: " <GetName() << FairLogger::endl; TObjArray* fileElements=fInChain->GetListOfFiles(); TIter next(fileElements); TChainElement* chEl=0; while (( chEl=static_cast(next()) )) { LOG(INFO) << " - " << chEl->GetTitle() << FairLogger::endl; } map< TString, TChain* >::iterator mapIterator; for (mapIterator = fFriendTypeList.begin(); mapIterator != fFriendTypeList.end(); mapIterator++ ) { TChain* chain = static_cast(mapIterator->second); LOG(INFO) << " - " << chain->GetName() << FairLogger::endl; fileElements=chain->GetListOfFiles(); TIter next1(fileElements); chEl=0; while (( chEl=static_cast(next1()) )) { LOG(INFO) << " - " << chEl->GetTitle() << FairLogger::endl; } } } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::CheckFriendChains() { std::multimap< TString, std::multimap >::iterator it1; std::multimap map1; // Get the structure from the input chain it1=fRunIdInfoAll.find("InputChain"); map1 = it1->second; std::vector runid; std::vector events; std::multimap::iterator it; for ( it=map1.begin() ; it != map1.end(); it++ ) { TArrayI bla = (*it).second; runid.push_back(bla[0]); events.push_back(bla[1]); } // Now loop over all chains except the input chain and comapare the // runids and event numbers. // If there is a mismatch stop the execution. Int_t errorFlag = 0; TString inputLevel; std::list::iterator listit; for ( listit=fInputLevel.begin() ; listit != fInputLevel.end(); listit++ ) { inputLevel = (*listit); if ( !inputLevel.Contains("InputChain") ) { it1=fRunIdInfoAll.find(inputLevel); map1 = it1->second; if ( runid.size() != map1.size()) { errorFlag = 1; // goto error_label; break; } Int_t counter = 0; for ( it=map1.begin() ; it != map1.end(); it++ ) { TArrayI bla = (*it).second; if ( (bla[0] != runid[counter]) || (bla[1] != events[counter]) ) { errorFlag = 2; // goto error_label; break; } counter++; } if (errorFlag>0) { break; } } } // Use goto to leave double loop at once in case of error // error_label: if (errorFlag>0) { LOG(ERROR) << "The input chain and the friend chain " << inputLevel.Data() << " have a different structure:" << FairLogger::endl; if (errorFlag == 1) { LOG(ERROR) << "The input chain has the following runids and event numbers:" << FairLogger::endl; for ( UInt_t i=0; i (f->Get("cbmout")); if(!added) { folderName = "/cbmroot"; folderName1 = "cbmroot"; added = dynamic_cast (f->Get("cbmroot")); if (!added) { LOG(FATAL) << "Could not find folder cbmout nor cbmroot." <SetName(folderName1); fListFolder->Add( added ); /**Get The list of branches from the friend file and add it to the actual list*/ TList* list= dynamic_cast (f->Get("BranchList")); TString chainName = inputLevel; fInputLevel.push_back(chainName); fCheckInputBranches[chainName] = new std::list; if(list) { TObjString* Obj=0; for(Int_t i =0; i< list->GetEntries(); i++) { Obj=dynamic_cast (list->At(i)); fCheckInputBranches[chainName]->push_back(Obj->GetString().Data()); FairRootManager::Instance()->AddBranchToList(Obj->GetString().Data()); } } TChain* chain = new TChain(inputLevel,folderName); fFriendTypeList[inputLevel]=chain; f->Close(); gFile = temp; } //_____________________________________________________________________________ //_____________________________________________________________________________ Bool_t CbmFileSource::CompareBranchList(TFile* fileHandle, TString inputLevel) { // fill a set with the original branch structure // This allows to use functions find and erase std::set branches; std::list::const_iterator iter; for(iter = fCheckInputBranches[inputLevel]->begin(); iter != fCheckInputBranches[inputLevel]->end(); iter++) { branches.insert(*iter); } // To do so we have to loop over the branches in the file and to compare // the branches in the file with the information stored in // fCheckInputBranches["InputChain"]. If both lists are equal everything // is okay // Get The list of branches from the input file one by one and compare // it to the reference list of branches which is defined for this tree. // If a branch with the same name is found, this branch is removed from // the list. If in the end no branch is left in the list everything is // fine. set::iterator iter1; TList* list= dynamic_cast (fileHandle->Get("BranchList")); if(list) { TObjString* Obj=0; for(Int_t i =0; i< list->GetEntries(); i++) { Obj=dynamic_cast (list->At(i)); iter1=branches.find(Obj->GetString().Data()); if (iter1 != branches.end() ) { branches.erase (iter1); } else { // Not found is an error because branch structure is // different. It is impossible to add to tree with a // different branch structure return kFALSE; } } } // If the size of branches is !=0 after removing all branches also in the // reference list, this is also a sign that both branch list are not the // same if (branches.size() != 0 ) { LOG(INFO) << "Compare Branch List will return kFALSE. The list has " << branches.size() << " branches:" << FairLogger::endl; for (std::set::iterator it=branches.begin(); it!=branches.end(); ++it) LOG(INFO) << " -> " << *it << FairLogger::endl; return kFALSE; } return kTRUE; } //_____________________________________________________________________________ //_____________________________________________________________________________ Bool_t CbmFileSource::ActivateObject(TObject** obj, const char* BrName) { if ( fInTree ) { fInTree->SetBranchStatus(BrName,1); fInTree->SetBranchAddress(BrName,obj); } if ( fInChain ) { fInChain->SetBranchStatus(BrName,1); fInChain->SetBranchAddress(BrName,obj); } return kTRUE; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetInputFile(TString name) { if(fRootFile) { fRootFile->Close(); delete fRootFile; } fRootFile = new TFile(name.Data()); if (fRootFile->IsZombie()) { LOG(FATAL) << "Error opening the Input file" << FairLogger::endl; } LOG(INFO) << "CbmFileSource set------------" << FairLogger::endl; } //_____________________________________________________________________________ //_____________________________________________________________________________ Int_t CbmFileSource::CheckMaxEventNo(Int_t EvtEnd) { Int_t MaxEventNo=0; if(EvtEnd!=0) { MaxEventNo=EvtEnd; } else { MaxEventNo=fInChain->GetEntries(); } return MaxEventNo; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetEventMeanTime(Double_t mean) { fEventMeanTime =mean; /* TString form="(1/"; form+= mean; form+=")*exp(-x/"; form+=mean; form+=")"; fTimeProb= new TF1("TimeProb.", form.Data(), 0., mean*10); */ fTimeProb = new TF1("TimeProb","(1/[0])*exp(-x/[0])", 0., mean*1000.); fTimeProb->SetParameter(0,mean); // fTimeProb->SetNpx(1000000); fTimeProb->GetRandom(); fEventTimeInMCHeader=kFALSE; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetEventTimeInterval(Double_t min, Double_t max) { fEventTimeMin=min; fEventTimeMax=max; fEventMeanTime=(fEventTimeMin+fEventTimeMax)/2; fEventTimeInMCHeader=kFALSE; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetBeamTime(Double_t beamTime, Double_t gapTime) { fBeamTime = beamTime; fGapTime = gapTime; } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::SetEventTime() { //Check if the time for the current entry is already set if(fTimeforEntryNo==fCurrentEntryNo) return; LOG(DEBUG) << "Set event time for Entry = " << fTimeforEntryNo << " , where the current entry is " << fCurrentEntryNo << " and eventTime is " << fEventTime << FairLogger::endl; if (fBeamTime < 0){ fEventTime += GetDeltaEventTime(); } else { /* do { fEventTime += GetDeltaEventTime(); } while( fmod(fEventTime, fBeamTime + fGapTime) > fBeamTime ); */ fEventTime += GetDeltaEventTime(); if(fmod(fEventTime, fBeamTime + fGapTime) > fBeamTime) { // The hypothetical start time of the next event would fall into a spill // break. Thus, the actual start time will fall into a new spill. fiCurrentSpillIndex++; } while(fmod(fEventTime, fBeamTime + fGapTime) > fBeamTime) { fEventTime += GetDeltaEventTime(); } } LOG(DEBUG) << "New time = " << fEventTime << FairLogger::endl; fTimeforEntryNo=fCurrentEntryNo; } //_____________________________________________________________________________ //_____________________________________________________________________________ Double_t CbmFileSource::GetDeltaEventTime() { Double_t deltaTime = 0; if (fTimeProb != 0) { // deltaTime = fTimeProb->GetRandom(); deltaTime = gRandom->Exp(fEventMeanTime); LOG(DEBUG) << "Time set via sampling method : " << deltaTime << FairLogger::endl; } else { deltaTime = gRandom->Uniform(fEventTimeMin, fEventTimeMax); LOG(DEBUG) << "Time set via Uniform Random : " << deltaTime << FairLogger::endl; } return deltaTime; } //_____________________________________________________________________________ //_____________________________________________________________________________ Double_t CbmFileSource::GetEventTime() { LOG(DEBUG) << "-- Get Event Time --" << FairLogger::endl; if(!fEvtHeaderIsNew && fEvtHeader!=0) { Double_t EvtTime=fEvtHeader->GetEventTime(); if( !(EvtTime<0)) { return EvtTime; } } if (fEventTimeInMCHeader && !fMCHeader) { LOG(DEBUG) << "No MCEventHeader, time is set to 0" << FairLogger::endl; return 0; } else if(fEventTimeInMCHeader && fMCHeader) { fEventTime=fMCHeader->GetT(); LOG(DEBUG) << "Get event time from MCEventHeader : " << fEventTime << " ns" << FairLogger::endl; return fEventTime; } else { if(fTimeforEntryNo!=fCurrentEntryNo) { SetEventTime(); } LOG(DEBUG) << "Calculate event time from user input : " << fEventTime << " ns" << FairLogger::endl; return fEventTime; } } //_____________________________________________________________________________ //_____________________________________________________________________________ void CbmFileSource::ReadBranchEvent(const char* BrName) { /**fill the object with content if the other branches in this tree entry were already read**/ if(fEvtHeader == 0) { return; } //No event header, Reading will start later if ( fInTree ) { fInTree->FindBranch(BrName)->GetEntry(fEvtHeader->GetMCEntryNumber()); return; } if ( fInChain ) { fInChain->FindBranch(BrName)->GetEntry(fEvtHeader->GetMCEntryNumber()); return; } return; } //_____________________________________________________________________________ void CbmFileSource::ReadBranchEvent(const char* BrName, Int_t Entry) { if ( fInTree ) { fInTree->FindBranch(BrName)->GetEntry(Entry); return; } if ( fInChain ) { fInChain->FindBranch(BrName)->GetEntry(Entry); return; } return; } //_____________________________________________________________________________ void CbmFileSource::FillEventHeader(FairEventHeader* feh) { feh->SetEventTime(fEventTime); if ( fEvtHeader ) { feh->SetRunId(fEvtHeader->GetRunId()); feh->SetMCEntryNumber(fEvtHeader->GetMCEntryNumber()); } if ( fMCHeader ) { feh->SetRunId(fMCHeader->GetRunID()); feh->SetMCEntryNumber(fCurrentEntryNo); } feh->SetInputFileId(0); return; } //_____________________________________________________________________________ ClassImp(CbmFileSource)