16#include "Gaudi/Property.h"
42 const std::string& name,
43 const IInterface* parent ) :
53 "StoreGate location of the reference McEventCollection" );
57 "Location of the 'to-be-validated' McEventCollection" );
61 "Name of the output text file which will contain the "
62 "hard-scattering vertices" );
67 "Tool to write the reference HepMC::GenEvent into a dedicated file" );
72 "Tool to write the \"to-be-checked\" HepMC::GenEvent "
73 "into a dedicated file" );
107 ATH_MSG_ERROR(
"Could not open output Hard-Scattering vertices file at : "
113 return StatusCode::FAILURE;
118 ATH_MSG_ERROR(
"Could not configure the HepMC::GenEvent writer tools !!");
119 return StatusCode::FAILURE;
122 return StatusCode::SUCCESS;
129 return StatusCode::SUCCESS;
137 nullptr == refMcEvents ) {
138 ATH_MSG_ERROR(
"Could not retrieve reference McEventCollection at ["
140 return StatusCode::FAILURE;
142 ATH_MSG_VERBOSE(
"Successfully retrieved reference McEventCollection at ["
154 nullptr == checkMcEvents ) {
155 ATH_MSG_ERROR(
"Could not retrieve 'to-be-validated' McEventCollection at ["
157 return StatusCode::FAILURE;
160 (
"Successfully retrieved 'to-be-validated' McEventCollection at ["
176 if (
nullptr == refMcEvents ) {
177 ATH_MSG_ERROR(
"NULL pointer to reference McEventCollection !!");
178 return StatusCode::FAILURE;
181 if (
nullptr == checkMcEvents ) {
182 ATH_MSG_ERROR(
"NULL pointer to the 'to-be-validated' McEventCollection !!");
183 return StatusCode::FAILURE;
186 if ( refMcEvents->
size() != checkMcEvents->
size() ) {
187 ATH_MSG_ERROR(
"McEventCollections to be compared don't have the same size !"
190 <<
"Current: " << checkMcEvents->
size());
193 const unsigned int nMaxEvts = std::min( refMcEvents->
size(),
194 checkMcEvents->
size() );
195 for (
unsigned int iEvt = 0; iEvt != nMaxEvts; ++iEvt ) {
198 (*checkMcEvents)[iEvt] ).isFailure() ) {
200 << (*refMcEvents)[iEvt]->event_number()
205 return StatusCode::SUCCESS;
212 if (
nullptr == refMcEvts ) {
213 ATH_MSG_ERROR(
"NULL pointer to reference HepMC::GenEvent !!");
214 return StatusCode::FAILURE;
217 if (
nullptr == checkMcEvts ) {
218 ATH_MSG_ERROR(
"NULL pointer to the 'to-be-validated' HepMC::GenEvent !!");
219 return StatusCode::FAILURE;
222 const unsigned int evtNbr = refMcEvts->event_number();
223 (*m_outFile) <<
">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"
225 <<
"Event: " << evtNbr
228 std::map<int,int> ref_bc_to_id;
229 const auto& refvertices = refMcEvts->vertices();
230 for (
const auto& vtx: refvertices) {
235 for (
auto& p: vtx->particles_out())
if (p->pdg_id() == 91||p->pdg_id() == 92||p->pdg_id() == 94) showerout++;
236 if ( partonsin >= 2 && showerout == 0 ) {
240 std::map<int,int> che_bc_to_id;
241 const auto& chevertices = checkMcEvts->vertices();
242 for (
const auto& checkVtx: chevertices) {
245 std::set<int> allbarcodes;
246 for (
const auto &[bc,
id]: ref_bc_to_id) allbarcodes.insert(bc);
247 for (
const auto &[bc,
id]: che_bc_to_id) allbarcodes.insert(bc);
248 for (
const auto &bc: allbarcodes){
249 auto ref_it = ref_bc_to_id.find(bc);
250 auto che_it = che_bc_to_id.find(bc);
251 if (ref_it == ref_bc_to_id.end()) {
ATH_MSG_WARNING(
"In Event [" << evtNbr <<
"]: got null ref-vertex (barcode: " << bc <<
")");
continue; }
252 if (che_it == che_bc_to_id.end()) {
ATH_MSG_WARNING(
"Output GenEvent is missing the selected HardScattering Vtx !!"<<
" (" << bc <<
")");
continue; }
253 if (-ref_it->second >
int(refvertices.size()) ) {
continue; }
254 if (-che_it->second >
int(chevertices.size()) ) {
continue; }
255 const auto& refvtx = refvertices[-ref_it->second-1];
256 const auto& chevtx = chevertices[-che_it->second-1];
257 (*m_outFile) << refvtx << std::endl;
258 (*m_outFile) << chevtx << std::endl;
259 (*m_outFile) <<
"---------" << std::endl;
261 ATH_MSG_WARNING(
"Selected HardScattering vertices are NOT the same !!"<<
" at Event [" << evtNbr <<
"]"<<
" refVtx = " << refvtx<<
" chevtx = " << chevtx);
264 (*m_outFile) <<
"<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<" << std::endl;
266 return StatusCode::SUCCESS;
271 if ( !vtx1 || !vtx2 ) {
273 <<
" vtx1: " << vtx1 <<
endmsg
274 <<
" vtx2: " << vtx2);
277 auto inVtx1 = vtx1->particles_in();
278 auto inVtx2 = vtx2->particles_in();
279 if (inVtx1.size() != inVtx2.size()) {
280 ATH_MSG_ERROR(
"Not the same number of branches !!" <<
endmsg <<
" in: " << inVtx1.size() <<
"\t" << inVtx2.size());
283 std::sort(inVtx1.begin(), inVtx1.end(), [](
auto&
a,
auto& b) ->
bool{return a->momentum().pz() > b->momentum().pz(); });
284 std::sort(inVtx2.begin(), inVtx2.end(), [](
auto&
a,
auto& b) ->
bool{return a->momentum().pz() > b->momentum().pz(); });
285 for (
size_t i=0; i<inVtx1.size(); ++i){
286 if (
compareParts( inVtx1.at(i), inVtx2.at(i) ) )
continue;
290 auto outVtx1 = vtx1->particles_out();
291 auto outVtx2 = vtx2->particles_out();
292 if (outVtx1.size() != outVtx2.size()) {
293 ATH_MSG_ERROR(
"Not the same number of branches !!" <<
endmsg <<
" out: " << outVtx1.size() <<
"\t" << outVtx2.size());
296 std::sort(outVtx1.begin(), outVtx1.end(), [](
auto&
a,
auto& b) ->
bool{return a->momentum().pz() > b->momentum().pz(); });
297 std::sort(outVtx2.begin(), outVtx2.end(), [](
auto&
a,
auto& b) ->
bool{return a->momentum().pz() > b->momentum().pz(); });
298 for (
size_t i=0; i<outVtx1.size(); ++i){
299 if (
compareParts( outVtx1.at(i), outVtx2.at(i) ) )
continue;
311 <<
" p1: " << p1 <<
endmsg
321 const int id1 = p1->pdg_id();
322 const int status1 = p1->status();
327 const int id2 = p2->pdg_id();
328 const int status2 = p2->status();
332 const bool isOK = ( hlv1 == hlv2 &&
334 status1 == status2 &&
341 (
"=============================" <<
endmsg
342 <<
"\thlv: " << std::boolalpha << (hlv1 == hlv2 ) <<
endmsg
343 <<
"\tid: " << std::boolalpha << (id1 == id2 ) <<
endmsg
344 <<
"\tstatus: " << std::boolalpha << (status1 == status2) <<
endmsg
345 <<
"\tflow: " << std::boolalpha << (flow1 == flow2 ) <<
endmsg
346 <<
"\tpolar: " << std::boolalpha << (pol1 == pol2 ) <<
endmsg
347 <<
"=============================");
367 return StatusCode::SUCCESS;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
ATLAS-specific HepMC functions.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
size_type size() const noexcept
Returns the number of elements in the collection.
This defines the McEventCollection, which is really just an ObjectVector of McEvent objectsFile: Gene...
TruthParticleValidationBaseTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
HepMC3::FourVector FourVector
Polarization polarization(const T &a)
HepMC3::ConstGenParticlePtr ConstGenParticlePtr
int flow(const HepMC3::GenParticlePtr &p, int i)
HepMC3::ConstGenVertexPtr ConstGenVertexPtr
HepMC3::GenEvent GenEvent
bool isQuark(const T &p)
PDG rule 2: Quarks and leptons are numbered consecutively starting from 1 and 11 respectively; to do ...
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.