#ifndef _DEventWriterROOT_ #define _DEventWriterROOT_ #include #include #include "TClonesArray.h" #include "TLorentzVector.h" #include "TVector3.h" #include "TTree.h" #include "TFile.h" #include "TROOT.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; using namespace jana; class DEventWriterROOT : public JObject { public: JOBJECT_PUBLIC(DEventWriterROOT); DEventWriterROOT(JEventLoop* locEventLoop); ~DEventWriterROOT(void); void Create_DataTrees(JEventLoop* locEventLoop) const; void Create_ThrownTree(string locOutputFileName) const; void Fill_DataTrees(JEventLoop* locEventLoop, string locDReactionTag) const; //fills all from this factory tag void Fill_DataTree(JEventLoop* locEventLoop, const DReaction* locReaction, deque& locParticleCombos) const; void Fill_ThrownTree(JEventLoop* locEventLoop) const; private: DEventWriterROOT(void){}; //don't allow default constructor //UTILITY FUNCTIONS void Get_Reactions(jana::JEventLoop* locEventLoop, vector& locReactions) const; string Convert_ToBranchName(string locInputName) const; ULong64_t Calc_ParticleMultiplexID(Particle_t locPID) const; void Get_DecayProductNames(const DReaction* locReaction, size_t locReactionStepIndex, TMap* locPositionToNameMap, TList*& locDecayProductNames, deque& locSavedSteps) const; //TREE CREATION: void Create_DataTree(const DReaction* locReaction, bool locIsMCDataFlag) const; void Create_Branches_FinalStateParticle(TTree* locTree, string locParticleBranchName, bool locIsChargedFlag, bool locKinFitFlag, bool locIsMCDataFlag) const; void Create_Branches_Beam(TTree* locTree, string locParticleBranchName, bool locKinFitFlag) const; void Create_Branches_UnusedParticle(TTree* locTree, string locParticleBranchName, string locArraySizeString, bool locIsMCDataFlag) const; void Create_Branches_ThrownParticle(TTree* locTree, string locParticleBranchName, string locArraySizeString, bool locIsOnlyThrownFlag) const; template string Create_Branch_Fundamental(TTree* locTree, string locParticleBranchName, string locVariableName, string locTypeString) const; template string Create_Branch_NoSplitTObject(TTree* locTree, string locParticleBranchName, string locVariableName, map& locTObjectMap) const; template string Create_Branch_FundamentalArray(TTree* locTree, string locParticleBranchName, string locVariableName, string locArraySizeString, unsigned int locMinimumSize, string locTypeString) const; string Create_Branch_ClonesArray(TTree* locTree, string locParticleBranchName, string locVariableName, string locClassName, unsigned int locSize) const; //TREE FILLING: void Fill_ThrownParticleData(TTree* locTree, unsigned int locArrayIndex, unsigned int locMinArraySize, const DMCThrown* locMCThrown, map locThrownObjectIDMap) const; void Fill_ThrownParticleData(TTree* locTree, unsigned int locArrayIndex, unsigned int locMinArraySize, const DMCThrown* locMCThrown, map locThrownObjectIDMap, const DMCThrownMatching* locMCThrownMatching, double locMinThrownMatchFOM, const map& locShowerToIDMap) const; void Fill_UnusedParticleData(TTree* locTree, unsigned int locArrayIndex, unsigned int locMinArraySize, const DKinematicData* locKinematicData, const DEventRFBunch* locEventRFBunch, const map& locShowerToIDMap, const DMCThrownMatching* locMCThrownMatching, double locMinThrownMatchFOM, map locThrownObjectIDMap, const DDetectorMatches* locDetectorMatches) const; void Fill_BeamParticleData(TTree* locTree, string locParticleBranchName, const DKinematicData* locKinematicData, const DKinematicData* locKinematicData_Measured, const map& locBeamToIDMap) const; void Fill_ParticleData(bool locKinFitFlag, TTree* locTree, string locParticleBranchName, const DKinematicData* locKinematicData, const DKinematicData* locKinematicData_Measured, const DEventRFBunch* locEventRFBunch, const map& locShowerToIDMap, const DMCThrownMatching* locMCThrownMatching, double locMinThrownMatchFOM, map locThrownObjectIDMap, const DDetectorMatches* locDetectorMatches) const; template DType* Get_BranchAddress(TTree* locTree, string locBranchName, unsigned int locMinimumSize, unsigned int locCurrentSize) const; template void Fill_FundamentalData(TTree* locTree, string locVariableName, DType locValue) const; template void Fill_FundamentalData(TTree* locTree, string locParticleBranchName, string locVariableName, DType locValue) const; template void Fill_FundamentalData(TTree* locTree, string locParticleBranchName, string locVariableName, DType locValue, unsigned int locArrayIndex, unsigned int locMinArraySize, unsigned int locCurrentArraySize) const; template void Fill_ClonesData(TTree* locTree, string locParticleBranchName, string locVariableName, DType* locObject, unsigned int locArrayIndex, const map& locClonesArrayMap) const; template void Fill_TObjectData(TTree* locTree, string locParticleBranchName, string locVariableName, DType* locObject, const map& locTObjectMap) const; const DAnalysisUtilities* dAnalysisUtilities; }; template string DEventWriterROOT::Create_Branch_Fundamental(TTree* locTree, string locParticleBranchName, string locVariableName, string locTypeString) const { string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; string locTypeName = locBranchName + string("/") + locTypeString; locTree->Branch(locBranchName.c_str(), new DType(), locTypeName.c_str()); return locBranchName; } template string DEventWriterROOT::Create_Branch_NoSplitTObject(TTree* locTree, string locParticleBranchName, string locVariableName, map& locTObjectMap) const { string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; locTObjectMap.insert(pair(locBranchName, (TObject*)(new DType()))); locTree->Branch(locBranchName.c_str(), (DType**)&(locTObjectMap[locBranchName]), 32000, 0); //0: don't split return locBranchName; } template string DEventWriterROOT::Create_Branch_FundamentalArray(TTree* locTree, string locParticleBranchName, string locVariableName, string locArraySizeString, unsigned int locMinimumSize, string locTypeString) const { string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; string locArrayName = locBranchName + string("[") + locArraySizeString + string("]/") + locTypeString; locTree->Branch(locBranchName.c_str(), new DType[locMinimumSize], locArrayName.c_str()); return locBranchName; } template DType* DEventWriterROOT::Get_BranchAddress(TTree* locTree, string locBranchName, unsigned int locMinimumSize, unsigned int locCurrentSize) const { //only works for fundamental types!!! if(locMinimumSize > locCurrentSize) //creates a new array if it is too small { delete (DType*)locTree->GetBranch(locBranchName.c_str())->GetAddress(); locTree->SetBranchAddress(locBranchName.c_str(), new DType[locMinimumSize]); } return (DType*)locTree->GetBranch(locBranchName.c_str())->GetAddress(); } template void DEventWriterROOT::Fill_FundamentalData(TTree* locTree, string locParticleBranchName, string locVariableName, DType locValue) const { //only call if the variable is NOT an array!! Fill_FundamentalData(locTree, locParticleBranchName, locVariableName, locValue, 0, 1, 1); } template void DEventWriterROOT::Fill_FundamentalData(TTree* locTree, string locVariableName, DType locValue) const { //only call if the variable is NOT an array!! Fill_FundamentalData(locTree, "", locVariableName, locValue, 0, 1, 1); } template void DEventWriterROOT::Fill_FundamentalData(TTree* locTree, string locParticleBranchName, string locVariableName, DType locValue, unsigned int locArrayIndex, unsigned int locMinArraySize, unsigned int locCurrentArraySize) const { string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; DType* locBranchPointer = Get_BranchAddress(locTree, locBranchName, locMinArraySize, locCurrentArraySize); if(locMinArraySize == 1) *locBranchPointer = locValue; else locBranchPointer[locArrayIndex] = locValue; } template void DEventWriterROOT::Fill_ClonesData(TTree* locTree, string locParticleBranchName, string locVariableName, DType* locObject, unsigned int locArrayIndex, const map& locClonesArrayMap) const { //only call for objects inheriting from TObject*!!! string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; TClonesArray* locClonesArray = locClonesArrayMap.find(locBranchName)->second; DType* locConstructedObject = (DType*)locClonesArray->ConstructedAt(locArrayIndex); *locConstructedObject = *locObject; } template void DEventWriterROOT::Fill_TObjectData(TTree* locTree, string locParticleBranchName, string locVariableName, DType* locObject, const map& locTObjectMap) const { //only call for objects inheriting from TObject*!!! string locBranchName = (locParticleBranchName != "") ? locParticleBranchName + string("__") + locVariableName : locVariableName; DType* locDType = (DType*)locTObjectMap.find(locBranchName)->second; *locDType = *locObject; } #endif //_DEventWriterROOT_