ATLAS Offline Software
Loading...
Searching...
No Matches
HepMcFloatWriterTool.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// HepMcFloatWriterTool.cxx
7// Implementation file for class HepMcFloatWriterTool
8// Author: S.Binet<binet@cern.ch>
10
11
12// STL includes
13#include <algorithm>
14#include <cctype>
15#include <fstream>
16#include <sstream>
17#include <limits>
18
19// FrameWork includes
20
22
23// McParticleTools includes
25#include "AtlasHepMC/Flow.h"
27static const char * const s_protocolSep = ":";
28
30 const std::string& name,
31 const IInterface* parent ) :
32 base_class( type, name, parent ),
33 m_ioBackend( nullptr )
34{
35 //
36 // Property declaration
37 //
38
39 declareProperty( "Output",
40 m_ioBackendURL = "ascii:hepmc.genevent.txt",
41 "Name of the back-end we'll use to write out the HepMC::GenEvent."
42 "\nEx: ascii:hepmc.genevent.txt" );
43 m_ioBackendURL.declareUpdateHandler( &HepMcFloatWriterTool::setupBackend,this );
44
45 declareProperty( "McEvents",
46 m_mcEventsName = "GEN_EVENT",
47 "Input location of the McEventCollection to write out" );
48}
49
53{
54 ATH_MSG_DEBUG("Calling destructor");
55
56 if ( m_ioBackend ) {
57 delete m_ioBackend;
58 m_ioBackend = nullptr;
59 }
60}
61
65{
66 ATH_MSG_INFO("Initializing " << name() << "...");
67
68 // setup backend
69 if ( nullptr == m_ioBackend ) {
71 }
72
73 (*m_ioBackend) << "# epsilon<float> = "
74 << std::numeric_limits<float>::epsilon()
75 << "\n"
76 << "# dbl precision = "
77 << std::numeric_limits<double>::digits10 + 1
78 << "\n"
79 << "# flt precision = "
80 << std::numeric_limits<float>::digits10 + 1
81 << "\n";
82
83 return StatusCode::SUCCESS;
84}
85
87{
88 ATH_MSG_INFO("Finalizing " << name() << "...");
89 return StatusCode::SUCCESS;
90}
91
93{
94 // retrieve the McEventCollection
95 const McEventCollection * mcEvts = nullptr;
96 if ( evtStore()->retrieve( mcEvts, m_mcEventsName ).isFailure() || nullptr == mcEvts ) {
97 ATH_MSG_ERROR("Could not retrieve a McEventCollection at [" << m_mcEventsName << "] !!");
98 return StatusCode::FAILURE;
99 }
100
101 if ( mcEvts->empty() ) {
102 ATH_MSG_WARNING("McEventCollection at [" << m_mcEventsName << "] is EMPTY !!");
103 return StatusCode::FAILURE;
104 }
105
106 const HepMC::GenEvent * evt = mcEvts->front();
107 if ( !evt ) {
108 ATH_MSG_ERROR("Retrieved NULL pointer to HepMC::GenEvent !!");
109 return StatusCode::FAILURE;
110 }
111
112 return write(evt);
113}
114
116{
117 std::ostringstream out;
118
119 // precision 8 (# digits following decimal point) is the minimum that
120 // will capture the full information stored in a float
121 out.precision( std::numeric_limits<double>::digits10 + 1 );
122 // we use decimal to store integers, because it is smaller than hex!
123 out.setf(std::ios::dec,std::ios::basefield);
124 out.setf(std::ios::scientific,std::ios::floatfield);
125
126 long evt_vertices_size=evt->vertices().size();
127 std::shared_ptr<HepMC3::DoubleAttribute> A_alphaQCD=evt->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQCD);
128 double evt_alphaQCD=(A_alphaQCD?(A_alphaQCD->value()):0.0);
129 std::shared_ptr<HepMC3::DoubleAttribute> A_alphaQED=evt->attribute<HepMC3::DoubleAttribute>(HepMCStr::alphaQED);
130 double evt_alphaQED=(A_alphaQED?(A_alphaQED->value()):0.0);
131 std::shared_ptr<HepMC3::DoubleAttribute> A_event_scale=evt->attribute<HepMC3::DoubleAttribute>(HepMCStr::event_scale);
132 double evt_event_scale=(A_event_scale?(A_event_scale->value()):0.0);
133 std::shared_ptr<HepMC3::VectorLongIntAttribute> A_random_states=evt->attribute<HepMC3::VectorLongIntAttribute>(HepMCStr::random_states);
134 std::vector<long int> random_states=(A_random_states?(A_random_states->value()):std::vector<long int>());
135 long random_states_size=random_states.size();
136 out << "# -- GenEvent -->\n";
137 out << "#" << evt->event_number()
138 << " " << evt_event_scale
139 << " " << evt_alphaQCD
140 << " " << evt_alphaQED
141 << " " << HepMC::signal_process_id(evt)
143 << " " << evt_vertices_size
144 << " " << random_states_size
145 << "\n";
146 out << "#";
147 std::copy( random_states.begin(), random_states.end(), std::ostream_iterator<long int>(out, " ") );
148 out << evt->weights().size() << "\n";
149
150 out << "#";
151 std::copy( evt->weights().begin(), evt->weights().end(), std::ostream_iterator<double>(out, " ") );
152 out << '\n';
153
154 out << "#-- particles --\n";
155 for (const auto& p: *evt) {
156 if ( p ) {
157 out << "# " << HepMC::barcode(p) << " " << p->pdg_id() << "\n";
158
159 const HepMC::FourVector mom = p->momentum();
160 std::ostringstream buf;
161 buf.precision( std::numeric_limits<float>::digits10 + 1 );
162 buf.setf(std::ios::dec,std::ios::basefield);
163 buf.setf(std::ios::scientific,std::ios::floatfield);
164
165 const float px = static_cast<float>(mom.px());
166 const float py = static_cast<float>(mom.py());
167 const float pz = static_cast<float>(mom.pz());
168 const float m = static_cast<float>(mom.m());
169 const float e = static_cast<float>(std::sqrt( std::pow( px, 2 ) + std::pow( py, 2 ) + std::pow( pz, 2 ) + std::pow( m, 2 ) ) );
170 buf << px << " " << py << " " << pz << " " << e << " " << m << "\n";
171
172 out << buf.str();
173 auto pol=HepMC::polarization(p);
174 out << "# "<< p->status()
175 << " " << pol.theta()
176 << " " << pol.phi()
177 << " " << ( p->end_vertex() ? HepMC::barcode(p->end_vertex()) : 0 )
178 << " " << HepMC::flow(p)
179 << "\n";
180 }
181 }
182
183 out << "#-- vertices -- \n";
184 for (const auto& v: evt->vertices()) {
185 if ( v ) {
186 out << "# " << HepMC::barcode(v) << " " << v->status() << "\n";
187 const HepMC::FourVector pos = v->position();
188 std::ostringstream buf;
189 buf.precision( std::numeric_limits<float>::digits10 + 1 );
190 buf.setf(std::ios::dec,std::ios::basefield);
191 buf.setf(std::ios::scientific,std::ios::floatfield);
192
193 buf << pos.x() << " " << pos.y() << " " << pos.z() << " " << pos.t() << "\n";
194
195 out << buf.str();
196 out << "#";
197 std::string svertexeights("1.0");
198 auto vertexeights=v->attribute<HepMC3::VectorDoubleAttribute>(HepMCStr::weights);
199 if (vertexeights) vertexeights->to_string(svertexeights);
200 out << svertexeights;
201 out << '\n';
202 }
203 }
204 out << "#<-- GenEvent --\n";
205
206 (*m_ioBackend) << out.str() << std::flush;
207 return StatusCode::SUCCESS;
208}
209
213
214void HepMcFloatWriterTool::setupBackend( Gaudi::Details::PropertyBase& /*prop*/ )
215{
216 // defaults
217 std::string protocol = "ascii";
218 std::string fileName = "hepmc.genevent.txt";
219
220 // reset internal state
221 if ( m_ioBackend ) {
222 delete m_ioBackend;
223 m_ioBackend = nullptr;
224 }
225
226 // caching URL
227 const std::string& url = m_ioBackendURL.value();
228
229 std::string::size_type protocolPos = url.find(s_protocolSep);
230
231 if ( std::string::npos != protocolPos ) {
232 protocol = url.substr( 0, protocolPos );
233 fileName = url.substr( protocolPos+1, std::string::npos );
234 } else {
235 //protocol = "ascii";
236 fileName = url;
237 }
238
239 // get the protocol name in lower cases
240 std::transform( protocol.begin(), protocol.end(), protocol.begin(), [](unsigned char c){ return std::tolower(c); } );
241 if ( "ascii" == protocol ) {
242 m_ioBackend = new std::ofstream( fileName.c_str(), std::ios::out | std::ios::trunc );
243
244 } else {
245 ATH_MSG_WARNING("UNKNOWN protocol [" << protocol << "] !!" << endmsg << "Will use [ascii] instead...");
246 protocol = "ascii";
247 m_ioBackend = new std::ofstream( fileName.c_str(), std::ios::out | std::ios::trunc );
248 }
249 ATH_MSG_DEBUG("Using protocol [" << protocol << "] and write to ["<< fileName << "]");
250}
#define endmsg
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
static const char *const s_protocolSep
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.
StringProperty m_ioBackendURL
URL of the I/O back-end (only "ASCII" for now...) glued with the name of the output file name.
StatusCode initialize()
Athena Algorithm's Hooks.
HepMcFloatWriterTool()
Default constructor:
StringProperty m_mcEventsName
Location of the McEventCollection to be written out If there is more than 1 HepMC::GenEvent in the Mc...
virtual ~HepMcFloatWriterTool()
Destructor:
void setupBackend(Gaudi::Details::PropertyBase &ioBackendURL)
Method to configure the back-end to write out the HepMC::GenEvent.
StatusCode write(const HepMC::GenEvent *evt)
Process the HepMC::GenEvent through the I/O backend.
std::ostream * m_ioBackend
Abstract base class for the back-end.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
const std::string event_scale
const std::string weights
const std::string random_states
const std::string alphaQED
const std::string alphaQCD
int signal_process_id(const GenEvent &evt)
Definition GenEvent.h:572
int barcode(const T *p)
Definition Barcode.h:15
HepMC3::FourVector FourVector
ConstGenVertexPtr signal_process_vertex(const GenEvent *e)
Definition GenEvent.h:597
Polarization polarization(const T &a)
int flow(const HepMC3::GenParticlePtr &p, int i)
Definition Flow.h:13
HepMC3::GenEvent GenEvent
Definition GenEvent.h:39