ATLAS Offline Software
Loading...
Searching...
No Matches
HepMcTupleWriterTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
6// HepMcTupleWriterTool.cxx
7// Implementation file for class HepMcTupleWriterTool
8// Author: S.Binet<binet@cern.ch>
10
11// FrameWork includes
12#include "GaudiKernel/ITHistSvc.h"
13#include "Gaudi/Property.h"
14#include "GaudiKernel/GaudiException.h"
15
16// ROOT includes
17#include "TTree.h"
18
19// CLHEP includes
21#include "CLHEP/Units/SystemOfUnits.h"
22
23// McParticleTools includes
25
29 const std::string& name,
30 const IInterface* parent ) :
31 base_class( type, name, parent ),
32 m_tupleSvc ( "THistSvc", name ),
33 m_tuple ( nullptr )
34{
35 //
36 // Property declaration
37 //
38
39 declareProperty( "Output",
40 m_outputFileName = "hepmc.root",
41 "Name of the output file which will contain the HepMC tuple"
42 "\nEx: hepmc.root" );
43 m_outputFileName.declareUpdateHandler( &HepMcTupleWriterTool::setupBackend, this );
44
45 declareProperty( "OutputStream",
46 m_outputStreamName = "hepmc",
47 "Name of the stream which will contain the HepMC tuple"
48 "\nEx: hepmc" );
49
50 declareProperty( "McEvents",
51 m_mcEventsName = "GEN_EVENT",
52 "Input location of the McEventCollection to write out" );
53}
54
61
65{
66 ATH_MSG_INFO("Initializing " << name() << "...");
67
68 // Get pointer to StoreGateSvc and cache it :
69 if ( !evtStore().retrieve().isSuccess() ) {
70 ATH_MSG_ERROR("Unable to retrieve pointer to StoreGateSvc");
71 return StatusCode::FAILURE;
72 }
73
74 // Get pointer to ITHistSvc and cache it :
75 if ( !m_tupleSvc.retrieve().isSuccess() ) {
76 ATH_MSG_ERROR("Unable to retrieve pointer to ITHistSvc");
77 return StatusCode::FAILURE;
78 }
79
80 // setup backend
82
83 // book tuple
84 bookTuple();
85
86 return StatusCode::SUCCESS;
87}
88
90{
91 ATH_MSG_INFO("Finalizing " << name() << "...");
92 return StatusCode::SUCCESS;
93}
94
96{
97 // retrieve the McEventCollection
98 const McEventCollection * mcEvts = nullptr;
99 if ( evtStore()->retrieve( mcEvts, m_mcEventsName ).isFailure() || nullptr == mcEvts ) {
100 ATH_MSG_ERROR("Could not retrieve a McEventCollection at [" << m_mcEventsName << "] !!");
101 return StatusCode::FAILURE;
102 }
103
104 if ( mcEvts->empty() ) {
105 ATH_MSG_WARNING("McEventCollection at ["<<m_mcEventsName<<"] is EMPTY !!");
106 return StatusCode::FAILURE;
107 }
108
109 const HepMC::GenEvent * evt = mcEvts->front();
110 if ( !evt ) {
111 ATH_MSG_ERROR("Retrieved NULL pointer to HepMC::GenEvent !!");
112 return StatusCode::FAILURE;
113 }
114
115 return write(evt);
116}
117
121
122StatusCode HepMcTupleWriterTool::write( const HepMC::GenEvent* evt )
123{
124 m_particles.m_nParticles = std::min<std::size_t>( s_nMax, evt->particles_size() );
125 std::size_t i = 0;
126 for (const auto& p: *evt)
127 {
128 if (i == static_cast<std::size_t>(m_particles.m_nParticles)) break;
129 i++;
130 const HepMC::FourVector mom = p->momentum();
131 m_particles.m_px [i] = mom.px();
132 m_particles.m_py [i] = mom.py();
133 m_particles.m_pz [i] = mom.pz();
134 m_particles.m_m [i] = mom.m();
135 m_particles.m_ene[i] = mom.e();
136
137 m_particles.m_pdgId[i] = p->pdg_id();
138 m_particles.m_status[i] = p->status();
139 m_particles.m_barcode[i] = HepMC::barcode(p);
140 }
141 // commit event
142 m_tuple->Fill();
143
144 return StatusCode::SUCCESS;
145}
146
150
151void HepMcTupleWriterTool::setupBackend( Gaudi::Details::PropertyBase& /*m_outputFileName*/ )
152{
153 SmartIF<IProperty> tSvc{m_tupleSvc.get()};
154 if ( !tSvc ) {
155 ATH_MSG_ERROR("Could not retrieve THistSvc handle !!");
156 throw GaudiException( "Could not retrieve THistSvc", name(), StatusCode::FAILURE );
157 }
158
159 const std::string streamName = m_outputStreamName.value();
160
161 const std::string propName = "Output";
162 StringArrayProperty outputFileName;
163 outputFileName.assign( tSvc->getProperty( propName ) );
164 std::vector<std::string> updatedProp( outputFileName.value() );
165 updatedProp.push_back
166 ( streamName+" DATAFILE='"+m_outputFileName.value()+"' "
167 "TYP='ROOT' "
168 "OPT='RECREATE'" );
169 outputFileName.set( updatedProp );
170 outputFileName.setName( std::move(propName) );
171 if ( !tSvc->setProperty( outputFileName ).isSuccess() ) {
172 ATH_MSG_ERROR("Could not configure the THistSvc's output filename ["<< m_outputFileName.value() << "] !!");
173 throw GaudiException( "Could not configure THistSvc output file !!", name(), StatusCode::FAILURE );
174 }
175
176 }
177
179{
180 const std::string streamName = m_outputStreamName.value();
181 TTree* t = new TTree("hepmc","HepMC validation tuple");
182 if ( !m_tupleSvc->regTree( "/" + streamName + "/hepmc", t ).isSuccess() ) {
183 ATH_MSG_ERROR("Could not register HepMC validation tuple !!");
184 delete t; t = nullptr;
185 throw GaudiException( "Could not register HepMC validation tuple !!", name(), StatusCode::FAILURE );
186 }
187
188 // booking branches
189 t->Branch( "nParts", &m_particles.m_nParticles, "nParts/I" );
190
191 t->Branch( "px", m_particles.m_px.data(), "px[nParts]/D" );
192 t->Branch( "py", m_particles.m_py.data(), "py[nParts]/D" );
193 t->Branch( "pz", m_particles.m_pz.data(), "pz[nParts]/D" );
194 t->Branch( "m", m_particles.m_m.data(), "m[nParts]/D" );
195 t->Branch( "e", m_particles.m_ene.data(), "e[nParts]/D" );
196
197 t->Branch( "pdgId", m_particles.m_pdgId.data(), "pdgId[nParts]/I" );
198 t->Branch( "sc", m_particles.m_status.data(), "sc[nParts]/I" );
199 t->Branch( "bc", m_particles.m_barcode.data(), "bc[nParts]/I" );
200
201 m_tuple = t;
202}
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const std::string outputFileName
const T * front() const
Access the first element in the collection as an rvalue.
bool empty() const noexcept
Returns true if the collection is empty.
StatusCode write(const HepMC::GenEvent *evt)
Process the HepMC::GenEvent through the I/O backend.
TTree * m_tuple
cached pointer to the tuple
StringProperty m_outputStreamName
Name of the output tuple stream.
StringProperty m_mcEventsName
Location of the McEventCollection to be written out If there is more than 1 HepMC::GenEvent in the Mc...
StringProperty m_outputFileName
Name of the output tuple file.
static const int s_nMax
maximum number of particles per event
void setupBackend(Gaudi::Details::PropertyBase &outputFileName)
Method to configure the back-end to write out the HepMC::GenEvent.
void bookTuple()
book the tuple
ServiceHandle< ITHistSvc > m_tupleSvc
Pointer to @ ITHistSvc.
HepMcParticles m_particles
our cached particles
HepMcTupleWriterTool()
Default constructor:
StatusCode initialize()
Athena Algorithm's Hooks.
virtual ~HepMcTupleWriterTool()
Destructor:
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
int barcode(const T *p)
Definition Barcode.h:16