.. _program_listing_file_Root_TreeAlgo.cxx: Program Listing for File TreeAlgo.cxx ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``Root/TreeAlgo.cxx``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp #include #include #include #include #include #include #include #include #include #include #include #include #include // this is needed to distribute the algorithm to the workers ClassImp(TreeAlgo) TreeAlgo :: TreeAlgo () : Algorithm("TreeAlgo") { } EL::StatusCode TreeAlgo :: setupJob (EL::Job& job) { job.useXAOD(); xAOD::Init("TreeAlgo").ignore(); EL::OutputStream outForTree(m_treeStreamName); if(!job.outputHas(m_treeStreamName)) job.outputAdd (outForTree); return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: initialize () { ANA_MSG_INFO( m_name ); m_event = wk()->xaodEvent(); m_store = wk()->xaodStore(); // get the file we created already TFile* treeFile = wk()->getOutputFile (m_treeStreamName); treeFile->mkdir(m_name.c_str()); treeFile->cd(m_name.c_str()); // to handle more than one jet collections (reco, trig and truth) std::string token; std::istringstream ss_reco_containers(m_jetContainerName); while ( std::getline(ss_reco_containers, token, ' ') ){ m_jetContainers.push_back(token); } std::istringstream ss_reco_names(m_jetBranchName); while ( std::getline(ss_reco_names, token, ' ') ){ m_jetBranches.push_back(token); } if( !m_jetContainerName.empty() && m_jetContainers.size()!=m_jetBranches.size()){ ANA_MSG_ERROR( "The number of jet containers must be equal to the number of jet name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_trig_containers(m_trigJetContainerName); while ( std::getline(ss_trig_containers, token, ' ') ){ m_trigJetContainers.push_back(token); } std::istringstream ss_trig_names(m_trigJetBranchName); while ( std::getline(ss_trig_names, token, ' ') ){ m_trigJetBranches.push_back(token); } if( !m_trigJetContainerName.empty() && m_trigJetContainers.size()!=m_trigJetBranches.size()){ ANA_MSG_ERROR( "The number of trig jet containers must be equal to the number of trig jet name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_truth_containers(m_truthJetContainerName); while ( std::getline(ss_truth_containers, token, ' ') ){ m_truthJetContainers.push_back(token); } std::istringstream ss_truth_names(m_truthJetBranchName); while ( std::getline(ss_truth_names, token, ' ') ){ m_truthJetBranches.push_back(token); } if( !m_truthJetContainerName.empty() && m_truthJetContainers.size()!=m_truthJetBranches.size()){ ANA_MSG_ERROR( "The number of truth jet containers must be equal to the number of truth jet name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_fat_containers(m_fatJetContainerName); while ( std::getline(ss_fat_containers, token, ' ') ){ m_fatJetContainers.push_back(token); } std::istringstream ss_fat_names(m_fatJetBranchName); while ( std::getline(ss_fat_names, token, ' ') ){ m_fatJetBranches.push_back(token); } if( m_fatJetBranches.size() == 0 ) { for(auto fatJetContainer : m_fatJetContainers) { m_fatJetBranches.push_back(fatJetContainer); } } if( !m_fatJetContainerName.empty() && m_fatJetContainers.size()!=m_fatJetBranches.size()){ ANA_MSG_ERROR( "The number of fat jet containers must be equal to the number of fat jet name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_l1_containers(m_l1JetContainerName); while ( std::getline(ss_l1_containers, token, ' ') ){ m_l1JetContainers.push_back(token); } std::istringstream ss_l1_names(m_l1JetBranchName); while ( std::getline(ss_l1_names, token, ' ') ){ m_l1JetBranches.push_back(token); } if( !m_l1JetContainerName.empty() && m_l1JetContainers.size()!=m_l1JetBranches.size()){ ANA_MSG_ERROR( "The number of L1 jet containers must be equal to the number of L1 jet name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_vertex_containers(m_vertexContainerName); while ( std::getline(ss_vertex_containers, token, ' ') ){ m_vertexContainers.push_back(token); } std::istringstream ss_vertex_names(m_vertexBranchName); while ( std::getline(ss_vertex_names, token, ' ') ){ m_vertexBranches.push_back(token); } if( m_vertexContainers.size()!=m_vertexBranches.size()){ ANA_MSG_ERROR( "The number of vertex containers must be equal to the number of vertex name branches. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_cluster_containers(m_clusterContainerName); while ( std::getline(ss_cluster_containers, token, ' ') ){ m_clusterContainers.push_back(token); } std::istringstream ss_cluster_names(m_clusterBranchName); while ( std::getline(ss_cluster_names, token, ' ') ){ m_clusterBranches.push_back(token); } if( !m_clusterContainerName.empty() && m_clusterContainers.size()!=m_clusterBranches.size()){ ANA_MSG_ERROR( "The number of cluster containers must be equal to the number of cluster name branches. Exiting"); return EL::StatusCode::FAILURE; } // allow to store different variables for each jet collection (reco, trig, fat only, default: store the same) std::istringstream ss(m_jetDetailStr); while ( std::getline(ss, token, '|') ){ m_jetDetails.push_back(token); } if( m_jetDetails.size()!=1 && m_jetContainers.size()!=m_jetDetails.size()){ ANA_MSG_ERROR( "The size of m_jetContainers should be equal to the size of m_jetDetailStr. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_trig_details(m_trigJetDetailStr); while ( std::getline(ss_trig_details, token, '|') ){ m_trigJetDetails.push_back(token); } if( m_trigJetDetails.size()!=1 && m_trigJetContainers.size()!=m_trigJetDetails.size()){ ANA_MSG_ERROR( "The size of m_trigJetContainers should be equal to the size of m_trigJetDetailStr. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_vertex_details(m_vertexDetailStr); while ( std::getline(ss_vertex_details, token, '|') ){ m_vertexDetails.push_back(token); } if( m_vertexDetails.size()>1 && m_vertexContainers.size()!=m_vertexDetails.size()){ ANA_MSG_ERROR( "The size of m_vertexContainers should be equal to the size of m_vertexDetailStr. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_fat_details(m_fatJetDetailStr); while ( std::getline(ss_fat_details, token, '|') ){ m_fatJetDetails.push_back(token); } if( m_fatJetDetails.size()!=1 && m_fatJetContainers.size()!=m_fatJetDetails.size()){ ANA_MSG_ERROR( "The size of m_fatJetContainers should be equal to the size of m_fatJetDetailStr. Exiting"); return EL::StatusCode::FAILURE; } std::istringstream ss_cluster_details(m_clusterDetailStr); while ( std::getline(ss_cluster_details, token, '|') ){ m_clusterDetails.push_back(token); } if( m_clusterDetails.size()!=1 && m_clusterContainers.size()!=m_clusterDetails.size()){ ANA_MSG_ERROR( "The size of m_clusterContainers should be equal to the size of m_clusterDetailStr. Exiting"); return EL::StatusCode::FAILURE; } // to handle more than one truth particles collections std::istringstream ss_truthParticlesContainers(m_truthParticlesContainerName); while ( std::getline(ss_truthParticlesContainers, token, ' ') ){ m_truthParticlesContainers.push_back(token); } std::istringstream ss_truthParticlesNames(m_truthParticlesBranchName); while ( std::getline(ss_truthParticlesNames, token, ' ') ){ m_truthParticlesBranches.push_back(token); } if( !m_truthParticlesContainerName.empty() && m_truthParticlesContainers.size()!=m_truthParticlesBranches.size()){ ANA_MSG_ERROR( "The number of truth particles containers must be equal to the number of truth particles name branches. Exiting"); return EL::StatusCode::FAILURE; } return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: histInitialize () { ANA_MSG_INFO( m_name ); ANA_CHECK( xAH::Algorithm::algInitialize()); return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: fileExecute () { return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: changeInput (bool /*firstFile*/) { return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: execute () { // what systematics do we need to process for this event? // handle the nominal case (merge all) on every event, always std::vector event_systNames({""}); std::vector muSystNames; std::vector elSystNames; std::vector tauSystNames; std::vector jetSystNames; std::vector photonSystNames; std::vector fatJetSystNames; std::vector metSystNames; // this is a temporary pointer that gets switched around to check each of the systematics std::vector* systNames(nullptr); // note that the way we set this up, none of the below ##SystNames vectors contain the nominal case // TODO: do we really need to check for duplicates? Maybe, maybe not. if(!m_muSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_muSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ muSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_elSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_elSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ elSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_tauSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_tauSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ tauSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_jetSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_jetSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ jetSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_fatJetSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_fatJetSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ fatJetSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_photonSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_photonSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ photonSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } if(!m_metSystsVec.empty()){ ANA_CHECK( HelperFunctions::retrieve(systNames, m_metSystsVec, 0, m_store, msg()) ); for(const auto& systName: *systNames){ metSystNames.push_back(systName); if (std::find(event_systNames.begin(), event_systNames.end(), systName) != event_systNames.end()) continue; event_systNames.push_back(systName); } } TFile* treeFile = wk()->getOutputFile (m_treeStreamName); // let's make the tdirectory and ttrees for(const auto& systName: event_systNames){ // check if we have already created the tree if(m_trees.find(systName) != m_trees.end()) continue; std::string treeName = systName; if(systName.empty()) treeName = "nominal"; ANA_MSG_INFO( "Making tree " << m_name << "/" << treeName ); TTree * outTree = new TTree(treeName.c_str(),treeName.c_str()); if ( !outTree ) { ANA_MSG_ERROR("Failed to instantiate output tree!"); return EL::StatusCode::FAILURE; } m_trees[systName] = createTree( m_event, outTree, treeFile, m_units, msgLvl(MSG::DEBUG), m_store ); const auto& helpTree = m_trees[systName]; helpTree->m_vertexContainerName = m_vertexContainers.at(0); // tell the tree to go into the file outTree->SetDirectory( treeFile->GetDirectory(m_name.c_str()) ); if(m_autoFlush != 0) outTree->SetAutoFlush(m_autoFlush); // choose if want to add tree to same directory as ouput histograms if ( m_outHistDir ) { if(m_trees.size() > 1) ANA_MSG_WARNING( "You're running systematics! You may find issues in writing all of the output TTrees to the output histogram file... Set `m_outHistDir = false` if you run into issues!"); wk()->addOutput( outTree ); } // initialize all branch addresses since we just added this tree helpTree->AddEvent( m_evtDetailStr ); if (!m_trigDetailStr.empty() ) { helpTree->AddTrigger(m_trigDetailStr); } if (!m_muContainerName.empty() ) { helpTree->AddMuons(m_muDetailStr); } if (!m_elContainerName.empty() ) { helpTree->AddElectrons(m_elDetailStr); } if (!m_jetContainerName.empty() ) { for(unsigned int ll=0; llAddJets (m_jetDetailStr, m_jetBranches.at(ll).c_str()); else{ helpTree->AddJets (m_jetDetails.at(ll), m_jetBranches.at(ll).c_str()); } } } if (!m_l1JetContainerName.empty() ) { for(unsigned int ll=0; llAddL1Jets(m_l1JetBranches.at(ll).c_str()); } } if (!m_trigJetContainerName.empty() ) { for(unsigned int ll=0; llAddJets (m_trigJetDetailStr, m_trigJetBranches.at(ll).c_str()); else{ helpTree->AddJets (m_trigJetDetails.at(ll), m_trigJetBranches.at(ll).c_str()); } } } if (!m_truthJetContainerName.empty() ) { for(unsigned int ll=0; llAddJets (m_truthJetDetailStr, m_truthJetBranches.at(ll).c_str()); } } if ( !m_fatJetContainerName.empty() ) { for(unsigned int ll=0; llAddFatJets (m_fatJetDetailStr, m_fatJetBranches.at(ll).c_str()); else{ helpTree->AddFatJets (m_fatJetDetails.at(ll), m_fatJetBranches.at(ll).c_str()); } } } if ( !m_vertexContainerName.empty() && !m_vertexDetailStr.empty() ) { for(unsigned int ll=0; llAddVertices(m_vertexDetailStr, m_vertexBranches.at(ll).c_str()); else{ helpTree->AddVertices(m_vertexDetails.at(ll), m_vertexBranches.at(ll).c_str()); } } } if (!m_truthFatJetContainerName.empty() ) { helpTree->AddTruthFatJets(m_truthFatJetDetailStr, m_truthFatJetBranchName); } if (!m_tauContainerName.empty() ) { helpTree->AddTaus(m_tauDetailStr); } if (!m_METContainerName.empty() ) { helpTree->AddMET(m_METDetailStr); } if (!m_METReferenceContainerName.empty() ) { helpTree->AddMET(m_METReferenceDetailStr, "referenceMet"); } if (!m_photonContainerName.empty() ) { helpTree->AddPhotons(m_photonDetailStr); } if (!m_truthParticlesContainerName.empty()) { for(unsigned int ll=0; llAddTruthParts(m_truthParticlesDetailStr, m_truthParticlesBranches.at(ll).c_str()); } } if (!m_trackParticlesContainerName.empty()) { helpTree->AddTrackParts(m_trackParticlesDetailStr, m_trackParticlesContainerName); } if (!m_clusterContainerName.empty() ) { for(unsigned int ll=0; llAddClusters (m_clusterDetailStr, m_clusterBranches.at(ll).c_str()); else helpTree->AddClusters (m_clusterDetails.at(ll), m_clusterBranches.at(ll).c_str()); } } } /* THIS IS WHERE WE START PROCESSING THE EVENT AND PLOTTING THINGS */ const xAOD::EventInfo* eventInfo(nullptr); ANA_CHECK( HelperFunctions::retrieve(eventInfo, m_eventInfoContainerName, m_event, m_store, msg()) ); const xAOD::VertexContainer* vertices(nullptr); if (m_retrievePV) { ANA_CHECK( HelperFunctions::retrieve(vertices, m_vertexContainers.at(0), m_event, m_store, msg()) ); } const xAOD::Vertex* primaryVertex = m_retrievePV ? HelperFunctions::getPrimaryVertex( vertices , msg() ) : nullptr; for(const auto& systName: event_systNames){ auto& helpTree = m_trees[systName]; // assume the nominal container by default std::string muSuffix(""); std::string elSuffix(""); std::string tauSuffix(""); std::string jetSuffix(""); std::string photonSuffix(""); std::string clusterSuffix(""); std::string fatJetSuffix(""); std::string metSuffix(""); /* if we find the systematic in the corresponding vector, we will use that container's systematic version instead of nominal version NB: since none of these contain the "" (nominal) case because of how I filter it, we handle the merging.. why? - in each loop to make the ##systNames vectors, we check to see if the systName exists in event_systNames which is initialized - to {""} - the nominal case. If the systName exists, we do not add it to the corresponding ##systNames vector, otherwise, we do. - This precludes the nominal case in all of the ##systNames vectors, which means the default will always be to run nominal. */ if (std::find(muSystNames.begin(), muSystNames.end(), systName) != muSystNames.end()) muSuffix = systName; if (std::find(elSystNames.begin(), elSystNames.end(), systName) != elSystNames.end()) elSuffix = systName; if (std::find(tauSystNames.begin(), tauSystNames.end(), systName) != tauSystNames.end()) tauSuffix = systName; if (std::find(jetSystNames.begin(), jetSystNames.end(), systName) != jetSystNames.end()) jetSuffix = systName; if (std::find(photonSystNames.begin(), photonSystNames.end(), systName) != photonSystNames.end()) photonSuffix = systName; if (std::find(fatJetSystNames.begin(), fatJetSystNames.end(), systName) != fatJetSystNames.end()) fatJetSuffix = systName; if (std::find(metSystNames.begin(), metSystNames.end(), systName) != metSystNames.end()) metSuffix = systName; helpTree->FillEvent( eventInfo, m_event, vertices ); // Fill trigger information if ( !m_trigDetailStr.empty() ) { helpTree->FillTrigger( eventInfo ); } // Fill jet trigger information - this can be used if with layer/cleaning info we need to turn off some variables? /*if ( !m_trigJetDetailStr.empty() ) { helpTree->FillJetTrigger(); }*/ // for the containers the were supplied, fill the appropriate vectors if ( !m_muContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_muContainerName + muSuffix, m_event, m_store, msg()) ) continue; const xAOD::MuonContainer* inMuon(nullptr); ANA_CHECK( HelperFunctions::retrieve(inMuon, m_muContainerName+muSuffix, m_event, m_store, msg()) ); helpTree->FillMuons( inMuon, primaryVertex ); } if ( !m_elContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_elContainerName + elSuffix, m_event, m_store, msg()) ) continue; const xAOD::ElectronContainer* inElec(nullptr); ANA_CHECK( HelperFunctions::retrieve(inElec, m_elContainerName+elSuffix, m_event, m_store, msg()) ); helpTree->FillElectrons( inElec, primaryVertex ); } if ( !m_jetContainerName.empty() ) { bool reject = false; for ( unsigned int ll = 0; ll < m_jetContainers.size(); ++ll ) { // Systs for all jet containers const xAOD::JetContainer* inJets(nullptr); if ( !HelperFunctions::isAvailable(m_jetContainers.at(ll)+jetSuffix, m_event, m_store, msg()) ) { ANA_MSG_DEBUG( "The jet container " + m_jetContainers.at(ll)+jetSuffix + " is not available. Skipping all remaining jet collections"); reject = true; break; } ANA_CHECK( HelperFunctions::retrieve(inJets, m_jetContainers.at(ll)+jetSuffix, m_event, m_store, msg()) ); helpTree->FillJets( inJets, HelperFunctions::getPrimaryVertexLocation(vertices, msg()), m_jetBranches.at(ll) ); } if ( reject ) { ANA_MSG_DEBUG( "There was a jet container problem - not writing the event"); continue; } } if ( !m_l1JetContainerName.empty() ){ bool reject = false; for ( unsigned int ll = 0; ll < m_l1JetContainers.size(); ++ll ) { if(m_l1JetContainers.at(ll).find("Fex")== std::string::npos){ // Legacy L1 jets const xAOD::JetRoIContainer* inL1Jets(nullptr); if ( !HelperFunctions::isAvailable(m_l1JetContainers.at(ll), m_event, m_store, msg()) ){ ANA_MSG_DEBUG( "The L1 jet container " + m_l1JetContainers.at(ll) + " is not available. Skipping all remaining L1 jet collections"); reject = true; } ANA_CHECK( HelperFunctions::retrieve(inL1Jets, m_l1JetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillLegacyL1Jets( inL1Jets, m_l1JetBranches.at(ll), m_sortL1Jets ); }else{ // Phase 1 L1 jets if(m_l1JetContainers.at(ll).find("jFexSR")!= std::string::npos){ // jFEX small-R const xAOD::jFexSRJetRoIContainer* inL1Jets(nullptr); if ( !HelperFunctions::isAvailable(m_l1JetContainers.at(ll), m_event, m_store, msg()) ){ ANA_MSG_DEBUG( "The L1 jet container " + m_l1JetContainers.at(ll) + " is not available. Skipping all remaining L1 jet collections"); reject = true; } ANA_CHECK( HelperFunctions::retrieve(inL1Jets, m_l1JetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillPhase1L1Jets( inL1Jets, m_l1JetBranches.at(ll), m_sortL1Jets ); }else if(m_l1JetContainers.at(ll).find("jFexLR")!= std::string::npos){ // jFEX large-R const xAOD::jFexLRJetRoIContainer* inL1Jets(nullptr); if ( !HelperFunctions::isAvailable(m_l1JetContainers.at(ll), m_event, m_store, msg()) ){ ANA_MSG_DEBUG( "The L1 jet container " + m_l1JetContainers.at(ll) + " is not available. Skipping all remaining L1 jet collections"); reject = true; } ANA_CHECK( HelperFunctions::retrieve(inL1Jets, m_l1JetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillPhase1L1Jets( inL1Jets, m_l1JetBranches.at(ll), m_sortL1Jets ); }else if(m_l1JetContainers.at(ll).find("gFex")!= std::string::npos){ // gFEX small-R/large-R jets const xAOD::gFexJetRoIContainer* inL1Jets(nullptr); if ( !HelperFunctions::isAvailable(m_l1JetContainers.at(ll), m_event, m_store, msg()) ){ ANA_MSG_DEBUG( "The L1 jet container " + m_l1JetContainers.at(ll) + " is not available. Skipping all remaining L1 jet collections"); reject = true; } ANA_CHECK( HelperFunctions::retrieve(inL1Jets, m_l1JetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillPhase1L1Jets( inL1Jets, m_l1JetBranches.at(ll), m_sortL1Jets ); }else{ ANA_MSG_DEBUG( "Phase 1 L1 jet container " + m_l1JetContainers.at(ll) + " is not known." ); } } } if ( reject ) { ANA_MSG_DEBUG( "There was a L1 jet container problem - not writing the event"); continue; } } if ( !m_trigJetContainerName.empty() ) { bool reject = false; for(unsigned int ll=0;ll(m_trigJetContainers.at(ll), m_event, m_store, msg()) ) { ANA_MSG_DEBUG( "The trigger jet container " + m_trigJetContainers.at(ll) + " is not available. Skipping all remaining trigger jet collections"); reject = true; break; } const xAOD::JetContainer* inTrigJets(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTrigJets, m_trigJetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillJets( inTrigJets, HelperFunctions::getPrimaryVertexLocation(vertices, msg()), m_trigJetBranches.at(ll) ); } if ( reject ) { ANA_MSG_DEBUG( "There was a trigger jet container problem - not writing the event"); continue; } } if ( !m_truthJetContainerName.empty() ) { bool reject = false; for ( unsigned int ll = 0; ll < m_truthJetContainers.size(); ++ll) { if ( !HelperFunctions::isAvailable(m_truthJetContainers.at(ll), m_event, m_store, msg()) ) { ANA_MSG_DEBUG( "The truth jet container " + m_truthJetContainers.at(ll) + " is not available. Skipping all remaining truth jet collections"); reject = true; break; } const xAOD::JetContainer* inTruthJets(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTruthJets, m_truthJetContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillJets( inTruthJets, HelperFunctions::getPrimaryVertexLocation(vertices, msg()), m_truthJetBranches.at(ll) ); } if ( reject ) { ANA_MSG_DEBUG( "There was a truth jet container problem - not writing the event"); continue; } } if ( !m_fatJetContainerName.empty() ) { // bool reject = false; // std::string token; // std::istringstream ss(m_fatJetContainerName); // while ( std::getline(ss, token, ' ') ){ // if ( !HelperFunctions::isAvailable(token+fatJetSuffix, m_event, m_store, msg()) ) { // reject = true; // break; // } // const xAOD::JetContainer* inFatJets(nullptr); // ANA_CHECK( HelperFunctions::retrieve(inFatJets, token+fatJetSuffix, m_event, m_store, msg()) ); // helpTree->FillFatJets( inFatJets, token ); // } // if ( reject ) continue; bool reject = false; for(unsigned int ll=0;ll(m_fatJetContainers.at(ll)+fatJetSuffix, m_event, m_store, msg()) ) { ANA_MSG_DEBUG( "The fatjet container " + m_fatJetContainers.at(ll)+fatJetSuffix + " was not retrieved. Skipping all remaining fat jet collections"); reject = true; break; } const xAOD::JetContainer* inFatJets(nullptr); ANA_CHECK( HelperFunctions::retrieve(inFatJets, m_fatJetContainers.at(ll)+fatJetSuffix, m_event, m_store, msg()) ); helpTree->FillFatJets( inFatJets, HelperFunctions::getPrimaryVertexLocation(vertices, msg()), m_fatJetBranches.at(ll) ); } if ( reject ) { ANA_MSG_DEBUG( "There was a fat jet container problem - not writing the event"); continue; } } if ( !m_truthFatJetContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_truthFatJetContainerName, m_event, m_store, msg()) ) continue; const xAOD::JetContainer* inTruthFatJets(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTruthFatJets, m_truthFatJetContainerName, m_event, m_store, msg()) ); helpTree->FillTruthFatJets( inTruthFatJets, HelperFunctions::getPrimaryVertexLocation(vertices, msg()), m_truthFatJetBranchName ); } if ( !m_tauContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_tauContainerName, m_event, m_store, msg()) ) continue; const xAOD::TauJetContainer* inTaus(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTaus, m_tauContainerName, m_event, m_store, msg()) ); helpTree->FillTaus( inTaus ); } if ( !m_METContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_METContainerName + metSuffix, m_event, m_store, msg()) ) continue; const xAOD::MissingETContainer* inMETCont(nullptr); ANA_CHECK( HelperFunctions::retrieve(inMETCont, m_METContainerName + metSuffix, m_event, m_store, msg()) ); helpTree->FillMET( inMETCont ); } if ( !m_METReferenceContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_METReferenceContainerName, m_event, m_store, msg()) ) continue; const xAOD::MissingETContainer* inMETCont(nullptr); ANA_CHECK( HelperFunctions::retrieve(inMETCont, m_METReferenceContainerName, m_event, m_store, msg()) ); helpTree->FillMET( inMETCont, "referenceMet" ); } if ( !m_photonContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_photonContainerName + photonSuffix, m_event, m_store, msg()) ) continue; const xAOD::PhotonContainer* inPhotons(nullptr); ANA_CHECK( HelperFunctions::retrieve(inPhotons, m_photonContainerName+photonSuffix, m_event, m_store, msg()) ); helpTree->FillPhotons( inPhotons ); } if ( !m_truthParticlesContainerName.empty() ) { for ( unsigned int ll = 0; ll < m_truthParticlesContainers.size(); ++ll) { if ( !HelperFunctions::isAvailable(m_truthParticlesContainers.at(ll), m_event, m_store, msg()) ) continue; const xAOD::TruthParticleContainer* inTruthParticles(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTruthParticles, m_truthParticlesContainers.at(ll), m_event, m_store, msg())); helpTree->FillTruth(inTruthParticles, m_truthParticlesBranches.at(ll)); } } if ( !m_trackParticlesContainerName.empty() ) { if ( !HelperFunctions::isAvailable(m_trackParticlesContainerName, m_event, m_store, msg()) ) continue; const xAOD::TrackParticleContainer* inTrackParticles(nullptr); ANA_CHECK( HelperFunctions::retrieve(inTrackParticles, m_trackParticlesContainerName, m_event, m_store, msg())); helpTree->FillTracks(inTrackParticles,m_trackParticlesContainerName); } if ( !m_vertexContainerName.empty() && !m_vertexDetailStr.empty() ){ bool reject = false; for ( unsigned int ll = 0; ll < m_vertexContainers.size(); ++ll ) { const xAOD::VertexContainer* inVertices(nullptr); if ( !HelperFunctions::isAvailable(m_vertexContainers.at(ll), m_event, m_store, msg()) ){ ANA_MSG_DEBUG( "The vertex container " + m_vertexContainers.at(ll) + " is not available. Skipping all remaining vertex collections"); reject = true; } ANA_CHECK( HelperFunctions::retrieve(inVertices, m_vertexContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillVertices( inVertices, m_vertexBranches.at(ll)); } if ( reject ) { ANA_MSG_DEBUG( "There was a vertex container problem - not writing the event"); continue; } } if ( !m_clusterContainerName.empty() ) { bool reject = false; for(unsigned int ll=0;ll(m_clusterContainers.at(ll), m_event, m_store, msg()) ) { ANA_MSG_DEBUG( "The cluster container " + m_clusterContainers.at(ll) + " is not available. Skipping all remaining cluster collections"); reject = true; break; } const xAOD::CaloClusterContainer* inClusters(nullptr); ANA_CHECK( HelperFunctions::retrieve(inClusters, m_clusterContainers.at(ll), m_event, m_store, msg()) ); helpTree->FillClusters( inClusters, m_clusterBranches.at(ll) ); } if ( reject ) { ANA_MSG_DEBUG( "There was a cluster container problem - not writing the event"); continue; } } // fill the tree helpTree->Fill(); } return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: postExecute () { return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: finalize () { ANA_MSG_INFO( "Deleting tree instances..."); for(auto& item: m_trees){ if(item.second) {delete item.second; item.second = nullptr; } } m_trees.clear(); return EL::StatusCode::SUCCESS; } EL::StatusCode TreeAlgo :: histFinalize () { return EL::StatusCode::SUCCESS; } HelpTreeBase* TreeAlgo :: createTree(xAOD::TEvent *event, TTree* tree, TFile* file, const float units, bool debug, xAOD::TStore* store) { return new HelpTreeBase( event, tree, file, units, debug, store ); }