.. _program_listing_file_Root_MinixAOD.cxx: Program Listing for File MinixAOD.cxx ===================================== |exhale_lsh| :ref:`Return to documentation for file <file_Root_MinixAOD.cxx>` (``Root/MinixAOD.cxx``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // c++ include(s): #include <iostream> #include <typeinfo> #include <sstream> // EL include(s): #include <EventLoop/Job.h> #include <EventLoop/StatusCode.h> #include <EventLoop/Worker.h> // output stream #include "EventLoop/OutputStream.h" // EDM include(s): #include "xAODCore/AuxContainerBase.h" #include "xAODBase/IParticleContainer.h" #include "xAODCore/ShallowCopy.h" #include "xAODEgamma/ElectronContainer.h" #include "xAODEgamma/ElectronAuxContainer.h" #include "xAODJet/JetContainer.h" #include "xAODJet/JetAuxContainer.h" #include "xAODJet/Jet.h" #include "xAODMissingET/MissingETContainer.h" #include "xAODMissingET/MissingETAuxContainer.h" #include "xAODMissingET/MissingET.h" #include "xAODMuon/MuonContainer.h" #include "xAODMuon/MuonAuxContainer.h" #include "xAODMuon/Muon.h" #include "xAODEgamma/PhotonContainer.h" #include "xAODEgamma/PhotonAuxContainer.h" #include "xAODEgamma/Photon.h" #include "xAODTau/TauJetContainer.h" #include "xAODTau/TauJetAuxContainer.h" #include "xAODTau/TauJet.h" // package include(s): #include "xAODAnaHelpers/MinixAOD.h" #include "xAODAnaHelpers/HelperClasses.h" #include "xAODAnaHelpers/HelperFunctions.h" // this is needed to distribute the algorithm to the workers ClassImp(MinixAOD) MinixAOD :: MinixAOD () : Algorithm("MinixAOD") { } EL::StatusCode MinixAOD :: setupJob (EL::Job& job) { ANA_MSG_DEBUG("Calling setupJob"); job.useXAOD (); xAOD::Init( "MinixAOD" ).ignore(); // call before opening first file // only create the output xaod if requested if(m_createOutputFile){ EL::OutputStream out_xAOD (m_outputFileName, "xAOD"); job.outputAdd (out_xAOD); } return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: histInitialize () { ANA_CHECK( xAH::Algorithm::algInitialize()); return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: changeInput (bool firstFile) { // // Update CutBookkeeper if(m_copyCutBookkeeper) { // Retrieve the input container: const xAOD::CutBookkeeperContainer* inputCBKContainer(nullptr); ANA_CHECK( wk()->xaodEvent()->retrieveMetaInput(inputCBKContainer, "CutBookkeepers")); if(firstFile) { // Create an output container m_outputCBKContainer = new xAOD::CutBookkeeperContainer(); m_outputCBKContainer_aux = new xAOD::CutBookkeeperAuxContainer(); m_outputCBKContainer->setStore( m_outputCBKContainer_aux ); // Create an empty incomplete output container m_outputInCBKContainer = new xAOD::CutBookkeeperContainer(); m_outputInCBKContainer_aux = new xAOD::CutBookkeeperAuxContainer(); m_outputInCBKContainer->setStore( m_outputInCBKContainer_aux ); // Create our cutbookkeeper m_outputCBK=new xAOD::CutBookkeeper(); m_outputCBK->setName("MinixAODKernel"); m_outputCBK->setCycle(inputCBKContainer->maxCycle()+1); } // Merge m_outputCBKContainer->merge(inputCBKContainer); } return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: fileExecute () { return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: initialize () { ANA_MSG_DEBUG("Calling initialize"); m_event = wk()->xaodEvent(); m_store = wk()->xaodStore(); // always do this, obviously TFile *file_xAOD = wk()->getOutputFile(m_outputFileName); ANA_CHECK( m_event->writeTo(file_xAOD)); if(m_copyFileMetaData){ m_fileMetaDataTool = new xAODMaker::FileMetaDataTool(); ANA_CHECK( m_fileMetaDataTool->setProperty("OutputLevel", msg().level() )); ANA_CHECK( m_fileMetaDataTool->initialize()); ANA_MSG_DEBUG("FileMetaDataTool initialized..."); } if(m_copyTriggerInfo){ // m_trigMetaDataTool = new xAODMaker::TriggerMenuMetaDataTool(); // ANA_CHECK( m_trigMetaDataTool->setProperty("OutputLevel", msg().level() )); // ANA_CHECK( m_trigMetaDataTool->initialize()); // ANA_MSG_DEBUG("TriggerMenuMetaDataTool initialized..."); ANA_MSG_DEBUG("Adding xTrigDecision and TrigConfKeys to the list of keys copied from the input file."); m_simpleCopyKeys_vec.push_back("xTrigDecision"); m_simpleCopyKeys_vec.push_back("TrigConfKeys"); } // parse and split by comma std::string token; std::istringstream ss(""); // A B C D ... Z -> {A, B, C, D, ..., Z} ss.clear(); ss.str(m_simpleCopyKeys); while(std::getline(ss, token, ' ')) m_simpleCopyKeys_vec.push_back(token); // A B C D ... Z -> {A, B, C, D, ..., Z} ss.clear(); ss.str(m_storeCopyKeys); while(std::getline(ss, token, ' ')) m_copyFromStoreToEventKeys_vec.push_back(token); // A1|A2 B1|B2 C1|C2 ... Z1|Z2 -> {(A1, A2), (B1, B2), ..., (Z1, Z2)} ss.clear(); ss.str(m_shallowCopyKeys); while(std::getline(ss, token, ' ')){ int pos = token.find_first_of('|'); m_shallowCopyKeys_vec.push_back(std::pair<std::string, std::string>(token.substr(0, pos), token.substr(pos+1))); } // A1|A2 B1|B2 C1|C2 ... Z1|Z2 -> {(A1, A2), (B1, B2), ..., (Z1, Z2)} ss.clear(); ss.str(m_deepCopyKeys); while(std::getline(ss, token, ' ')){ int pos = token.find_first_of('|'); m_deepCopyKeys_vec.push_back(std::pair<std::string, std::string>(token.substr(0, pos), token.substr(pos+1))); } // A1|A2 B1|B2 C1|C2 ... Z1|Z2 -> {(A1, A2), (B1, B2), ..., (Z1, Z2)} ss.clear(); ss.str(m_vectorCopyKeys); while(std::getline(ss, token, ' ')){ int pos = token.find_first_of('|'); m_vectorCopyKeys_vec.push_back(std::pair<std::string, std::string>(token.substr(0, pos), token.substr(pos+1))); } ANA_MSG_DEBUG("MinixAOD Interface succesfully initialized!" ); return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: execute () { ANA_MSG_VERBOSE( "Dumping objects..."); const xAOD::EventInfo* eventInfo(nullptr); ANA_CHECK( HelperFunctions::retrieve(eventInfo, "EventInfo", m_event, m_store, msg()) ); // // Fill cutbookkeeper if(m_copyCutBookkeeper) { float eventWeight(1); if ( eventInfo->eventType(xAOD::EventInfo::IS_SIMULATION) ) eventWeight = eventInfo->mcEventWeight(); m_outputCBK->addNAcceptedEvents(1); m_outputCBK->addSumOfEventWeights(eventWeight); m_outputCBK->addSumOfEventWeightsSquared(eventWeight*eventWeight); } // // Copy code // simple copy is easiest - it's in the input, copy over, no need for types for(const auto& key: m_simpleCopyKeys_vec){ ANA_CHECK( m_event->copy(key)); ANA_MSG_DEBUG("Copying " << key << " from input file"); } // we need to make deep copies for(const auto& keypair: m_deepCopyKeys_vec){ auto in_key = keypair.first; auto out_key = keypair.second; const xAOD::IParticleContainer* cont(nullptr); ANA_CHECK( HelperFunctions::retrieve(cont, in_key, nullptr, m_store, msg())); if(const xAOD::ElectronContainer* t_cont = dynamic_cast<const xAOD::ElectronContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::ElectronContainer, xAOD::ElectronAuxContainer, xAOD::Electron>(m_store, out_key.c_str(), t_cont))); } else if(const xAOD::JetContainer* t_cont = dynamic_cast<const xAOD::JetContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::JetContainer, xAOD::JetAuxContainer, xAOD::Jet>(m_store, out_key.c_str(), t_cont))); } else if(const xAOD::MissingETContainer* t_cont = dynamic_cast<const xAOD::MissingETContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::MissingETContainer, xAOD::MissingETAuxContainer, xAOD::MissingET>(m_store, out_key.c_str(), t_cont))); } else if(const xAOD::MuonContainer* t_cont = dynamic_cast<const xAOD::MuonContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::MuonContainer, xAOD::MuonAuxContainer, xAOD::Muon>(m_store, out_key.c_str(), t_cont))); } else if(const xAOD::PhotonContainer* t_cont = dynamic_cast<const xAOD::PhotonContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::PhotonContainer, xAOD::PhotonAuxContainer, xAOD::Photon>(m_store, out_key.c_str(), t_cont))); } else if(const xAOD::TauJetContainer* t_cont = dynamic_cast<const xAOD::TauJetContainer*>(cont)){ ANA_CHECK( (HelperFunctions::makeDeepCopy<xAOD::TauJetContainer, xAOD::TauJetAuxContainer, xAOD::TauJet>(m_store, out_key.c_str(), t_cont))); } else { ANA_MSG_ERROR("Could not identify what container " << in_key << " corresponds to for deep-copying."); return EL::StatusCode::FAILURE; } m_copyFromStoreToEventKeys_vec.push_back(out_key); ANA_MSG_DEBUG("Deep-Copied " << in_key << " to " << out_key << " to record to output file"); } // shallow IO handling (if no parent, assume deep copy) for(const auto& keypair: m_shallowCopyKeys_vec){ auto key = keypair.first; auto parent = keypair.second; // only add the parent if it doesn't exist if(!parent.empty()) m_copyFromStoreToEventKeys_vec.push_back(parent); ANA_MSG_DEBUG("Copying " << key); if(!parent.empty()) ANA_MSG_DEBUG(" as well as it's parent " << parent); m_copyFromStoreToEventKeys_vec.push_back(key); } // vector handling (if no parent, assume deep copy) for(const auto& keypair: m_vectorCopyKeys_vec){ auto vectorName = keypair.first; auto parent = keypair.second; std::vector<std::string>* vector(nullptr); ANA_CHECK( HelperFunctions::retrieve(vector, vectorName, nullptr, m_store, msg())); // only add the parent if it doesn't exist if(!parent.empty()) m_copyFromStoreToEventKeys_vec.push_back(parent); ANA_MSG_INFO("The following containers are being copied over:"); for(const auto& key: *vector){ ANA_MSG_DEBUG("\t" << key); m_copyFromStoreToEventKeys_vec.push_back(key); } if(!parent.empty()) ANA_MSG_DEBUG("... along with their parent " << parent); } // remove duplicates from m_copyFromStoreToEventKeys_vec // - see http://stackoverflow.com/a/1041939/1532974 std::set<std::string> s; unsigned size = m_copyFromStoreToEventKeys_vec.size(); for( unsigned i = 0; i < size; ++i ) s.insert( m_copyFromStoreToEventKeys_vec[i] ); m_copyFromStoreToEventKeys_vec.assign( s.begin(), s.end() ); // all we need to do is retrieve it and figure out what type it is to record it and we're done for(const auto& key: m_copyFromStoreToEventKeys_vec){ const xAOD::IParticleContainer* cont(nullptr); ANA_CHECK( HelperFunctions::retrieve(cont, key, nullptr, m_store, msg())); if(dynamic_cast<const xAOD::ElectronContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::ElectronContainer, xAOD::ElectronAuxContainer>(m_event, m_store, key))); } else if(dynamic_cast<const xAOD::JetContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::JetContainer, xAOD::JetAuxContainer>(m_event, m_store, key))); } else if(dynamic_cast<const xAOD::MissingETContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::MissingETContainer, xAOD::MissingETAuxContainer>(m_event, m_store, key))); } else if(dynamic_cast<const xAOD::MuonContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::MuonContainer, xAOD::MuonAuxContainer>(m_event, m_store, key))); } else if(dynamic_cast<const xAOD::PhotonContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::PhotonContainer, xAOD::PhotonAuxContainer>(m_event, m_store, key))); } else if(dynamic_cast<const xAOD::TauJetContainer*>(cont)){ ANA_CHECK( (HelperFunctions::recordOutput<xAOD::TauJetContainer, xAOD::TauJetAuxContainer>(m_event, m_store, key))); } else { ANA_MSG_ERROR("Could not identify what container " << key << " corresponds to for copying from TStore to TEvent."); return EL::StatusCode::FAILURE; } ANA_MSG_DEBUG("Copied " << key << " and it's auxiliary container from TStore to TEvent"); } m_event->fill(); ANA_MSG_DEBUG("Finished dumping objects..."); return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: postExecute () { return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: finalize () { // // Save cutbookkeeper if(m_copyCutBookkeeper) { ANA_CHECK( wk()->xaodEvent()->recordMeta(m_outputCBKContainer ,"CutBookkeepers") ); ANA_CHECK( wk()->xaodEvent()->recordMeta(m_outputCBKContainer_aux ,"CutBookkeepersAux.") ); ANA_CHECK( wk()->xaodEvent()->recordMeta(m_outputInCBKContainer ,"IncompleteCutBookkeepers") ); ANA_CHECK( wk()->xaodEvent()->recordMeta(m_outputInCBKContainer_aux,"IncompleteCutBookkeepersAux.")); m_outputCBKContainer->push_back(m_outputCBK); } // // Close file TFile *file_xAOD = wk()->getOutputFile(m_outputFileName); ANA_CHECK( m_event->finishWritingTo(file_xAOD)); if(m_fileMetaDataTool) delete m_fileMetaDataTool; // if(m_trigMetaDataTool) delete m_trigMetaDataTool; return EL::StatusCode::SUCCESS; } EL::StatusCode MinixAOD :: histFinalize () { ANA_CHECK( xAH::Algorithm::algFinalize()); return EL::StatusCode::SUCCESS; }