diff --git a/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.cxx b/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.cxx index 825212d40d9a5205e08b4bebfeda1ead1845f9f6..b65d6934ccf70ac28cce8e1a2540162536ab0241 100755 --- a/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.cxx +++ b/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.cxx @@ -18,6 +18,7 @@ #include "GeneratorObjectsTPCnv/McEventCollectionCnv_p3.h" #include "GeneratorObjectsTPCnv/McEventCollectionCnv_p4.h" #include "GeneratorObjectsTPCnv/McEventCollectionCnv_p5.h" +#include "GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h" // GeneratorObjectsAthenaPool includes #include "McEventCollectionCnv.h" @@ -28,6 +29,7 @@ McEventCollectionCnv::createPersistent( McEventCollection* transCont ) MsgStream msg( msgSvc(), "McEventCollectionCnv" ); McEventCollectionCnv_p5 cnv; +// v6 McEventCollectionCnv_p6 cnv; McEventCollection_PERS *persObj = cnv.createPersistent( transCont, msg ); msg << MSG::DEBUG << "::createPersistent [Success]" << endmsg; @@ -46,6 +48,7 @@ McEventCollection* McEventCollectionCnv::createTransient() static pool::Guid p3_guid("6FC41599-64D6-4DB9-973E-9493166F6291"); static pool::Guid p4_guid("C517102A-94DE-407C-B07F-09BD81F6172E"); static pool::Guid p5_guid("D52391A4-F951-46BF-A0D5-E407698D2917"); + static pool::Guid p6_guid("6B78A751-B31A-4597-BFB6-DDCE62646CF9"); // Hook to disable datapool if we are doing pileup bool isPileup(false); @@ -86,6 +89,12 @@ McEventCollection* McEventCollectionCnv::createTransient() McEventCollectionCnv_p5 cnv; if(isPileup) cnv.setPileup(); transObj = cnv.createTransient( persObj.get(), msg ); + } else if ( compareClassGuid(p6_guid) ) { + + std::unique_ptr<McEventCollection_p6> persObj( poolReadObject<McEventCollection_p6>() ); + McEventCollectionCnv_p6 cnv; + if(isPileup) cnv.setPileup(); + transObj = cnv.createTransient( persObj.get(), msg ); } else { throw std::runtime_error("Unsupported persistent version of McEventCollection"); } diff --git a/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.h b/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.h index 1470384cf5c05daa973d582afcfffb23f527067a..6d5a2953ddf79e022e217a8a8d8e5b73ae06bb5f 100644 --- a/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.h +++ b/Generators/GeneratorObjectsAthenaPool/src/McEventCollectionCnv.h @@ -18,11 +18,13 @@ // GeneratorObjectsTPCnv includes #include "GeneratorObjectsTPCnv/McEventCollection_p5.h" +// v6 #include "GeneratorObjectsTPCnv/McEventCollection_p6.h" // Forward declaration // the latest persistent representation type of DataCollection: typedef McEventCollection_p5 McEventCollection_PERS; +// v6 typedef McEventCollection_p6 McEventCollection_PERS; class McEventCollectionCnv: public T_AthenaPoolCustomCnv< McEventCollection, diff --git a/Generators/GeneratorObjectsTPCnv/CMakeLists.txt b/Generators/GeneratorObjectsTPCnv/CMakeLists.txt index 0811c6b1be25e9d3f726797f88619fa2c3309336..7f10c1714293fbcb5f404630cbf336e2be8b2fd2 100644 --- a/Generators/GeneratorObjectsTPCnv/CMakeLists.txt +++ b/Generators/GeneratorObjectsTPCnv/CMakeLists.txt @@ -51,3 +51,10 @@ atlas_add_test( HepMcParticleLinkCnv_p2_test test/HepMcParticleLinkCnv_p2_test.cxx INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} LINK_LIBRARIES ${CLHEP_LIBRARIES} GeneratorObjectsTPCnv StoreGateLib TestTools ) + +atlas_add_test( McEventCollectionCnv_p6_test + SOURCES + test/McEventCollectionCnv_p6_test.cxx + INCLUDE_DIRS ${CLHEP_INCLUDE_DIRS} + LINK_LIBRARIES ${CLHEP_LIBRARIES} GeneratorObjectsTPCnv TestTools + LOG_IGNORE_PATTERN "HepMCWeightSvc +INFO|No run info" ) diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenEvent_p6.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenEvent_p6.h new file mode 100755 index 0000000000000000000000000000000000000000..dce3f0261cbab7e678f2bc8204ad831a7867aa7a --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenEvent_p6.h @@ -0,0 +1,250 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// GenEvent_p6.h +// Header file for class GenEvent_p6 +// Author: S.Binet<binet@cern.ch> +// Date: March 2007 +/////////////////////////////////////////////////////////////////// +#ifndef GENERATOROBJECTSTPCNV_GENEVENT_P6_H +#define GENERATOROBJECTSTPCNV_GENEVENT_P6_H + +// STL includes +#include <vector> +#include <utility> //> for std::pair + +// forward declarations +class McEventCollectionCnv_p6; + +class GenEvent_p6 +{ + /////////////////////////////////////////////////////////////////// + // Friend classes + /////////////////////////////////////////////////////////////////// + + // Make the AthenaPoolCnv class our friend + friend class McEventCollectionCnv_p6; + + /////////////////////////////////////////////////////////////////// + // Public methods + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor + */ + GenEvent_p6(); + + /** Constructor with parameters + */ + GenEvent_p6( int signalProcessId, + int eventNbr, + int mpi, + double eventScale, + double alphaQCD, + double alphaQED, + int signalProcessVtx, + int beamParticle1, + int beamParticle2, + const std::vector<double>& weights, + const std::vector<long int>& randomStates, + const std::vector<double>& crossSection, + const std::vector<float>& heavyIon, + const std::vector<double>& pdfinfo, + int momentumUnit, + int lengthUnit, + unsigned int verticesBegin, + unsigned int verticesEnd, + unsigned int particlesBegin, + unsigned int particlesEnd + ,std::vector<int> e_attribute_id = std::vector<int>() + ,std::vector<std::string> e_attribute_name = std::vector<std::string>() + ,std::vector<std::string> e_attribute_string = std::vector<std::string>() + ,std::vector<std::string> r_attribute_name = std::vector<std::string>() + ,std::vector<std::string> r_attribute_string = std::vector<std::string>() + ); + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + /** Id of the processus being generated + */ + int m_signalProcessId; + + /** Event number + */ + int m_eventNbr; + + /** Number of multi particle interactions + */ + int m_mpi; + + /** Energy scale. see hep-ph/0109068 + */ + double m_eventScale; + + /** value of the QCD coupling. see hep-ph/0109068 + */ + double m_alphaQCD; + + /** value of the QED coupling. see hep-ph/0109068 + */ + double m_alphaQED; + + /** Barcode of the GenVertex holding the signal process. + * 0 means that no signal process vertex has been written out. + * This may come from upstream limitations (like HEPEVT) + */ + int m_signalProcessVtx; + + /** Barcode of the beam particle 1 + */ + int m_beamParticle1; + + /** Barcode of the beam particle 2 + */ + int m_beamParticle2; + + /** Weights for this event. + * First weight is used by default for hit and miss. + */ + std::vector<double> m_weights; + + /** Container of random numbers for the generator states + */ + std::vector<long int> m_randomStates; + + /** Container of HepMC::GenCrossSection object translated to vector<double> + */ + std::vector<double> m_crossSection; + + /** Container of HepMC::HeavyIon object translated to vector<double> + */ + std::vector<float> m_heavyIon; + + /** Container of HepMC::PdfInfo object translated to + * vector<double> for simplicity + */ + std::vector<double> m_pdfinfo; + + /** HepMC::Units::MomentumUnit casted to int + */ + int m_momentumUnit; + + /** HepMC::Units::LengthUnit casted to int + */ + int m_lengthUnit; + + /** Begin position in the vector of vertices composing this event. + */ + unsigned int m_verticesBegin; + + /** End position in the vector of vertices composing this event. + */ + unsigned int m_verticesEnd; + + /** Begin position in the vector of particles composing this event. + */ + unsigned int m_particlesBegin; + + /** End position in the vector of particles composing this event. + */ + unsigned int m_particlesEnd; + + /** We define those exactly as in the HepMC3::GenEvent */ + std::vector<int> m_e_attribute_id; ///< Attribute owner id for event + std::vector<std::string> m_e_attribute_name; ///< Attribute name for event + std::vector<std::string> m_e_attribute_string; ///< Attribute serialized as string for event + std::vector<std::string> m_r_attribute_name; ///< Attribute name for run info + std::vector<std::string> m_r_attribute_string; ///< Attribute serialized as string for run info +}; + +/////////////////////////////////////////////////////////////////// +/// Inline methods: +/////////////////////////////////////////////////////////////////// +inline GenEvent_p6::GenEvent_p6(): + m_signalProcessId ( -1 ), + m_eventNbr ( -1 ), + m_mpi ( -1 ), + m_eventScale ( -1 ), + m_alphaQCD ( -1 ), + m_alphaQED ( -1 ), + m_signalProcessVtx ( 0 ), + m_beamParticle1 ( 0 ), + m_beamParticle2 ( 0 ), + m_weights ( ), + m_randomStates ( ), + m_crossSection ( ), + m_heavyIon ( ), + m_pdfinfo ( ), + m_momentumUnit ( 0 ), + m_lengthUnit ( 0 ), + m_verticesBegin ( 0 ), + m_verticesEnd ( 0 ), + m_particlesBegin ( 0 ), + m_particlesEnd ( 0 ) + ,m_e_attribute_id ( ) + ,m_e_attribute_name ( ) + ,m_e_attribute_string( ) + ,m_r_attribute_name ( ) + ,m_r_attribute_string( ) +{} + +inline GenEvent_p6::GenEvent_p6( int signalProcessId, + int eventNbr, + int mpi, + double eventScale, + double alphaQCD, + double alphaQED, + int signalProcessVtx, + int beamParticle1, + int beamParticle2, + const std::vector<double>& weights, + const std::vector<long int>& randomStates, + const std::vector<double>& crossSection, + const std::vector<float>& heavyIon, + const std::vector<double>& pdfinfo, + int momentumUnit, + int lengthUnit, + unsigned int verticesBegin, + unsigned int verticesEnd, + unsigned int particlesBegin, + unsigned int particlesEnd + ,std::vector<int> e_attribute_id + ,std::vector<std::string> e_attribute_name + ,std::vector<std::string> e_attribute_string + ,std::vector<std::string> r_attribute_name + ,std::vector<std::string> r_attribute_string + ) : + m_signalProcessId ( signalProcessId ), + m_eventNbr ( eventNbr ), + m_mpi ( mpi ), + m_eventScale ( eventScale ), + m_alphaQCD ( alphaQCD ), + m_alphaQED ( alphaQED ), + m_signalProcessVtx ( signalProcessVtx ), + m_beamParticle1 ( beamParticle1 ), + m_beamParticle2 ( beamParticle2 ), + m_weights ( weights ), + m_randomStates ( randomStates ), + m_crossSection ( crossSection ), + m_heavyIon ( heavyIon ), + m_pdfinfo ( pdfinfo ), + m_momentumUnit ( momentumUnit ), + m_lengthUnit ( lengthUnit ), + m_verticesBegin ( verticesBegin ), + m_verticesEnd ( verticesEnd ), + m_particlesBegin ( particlesBegin ), + m_particlesEnd ( particlesEnd ) + ,m_e_attribute_id ( e_attribute_id ) + ,m_e_attribute_name ( e_attribute_name ) + ,m_e_attribute_string( e_attribute_string ) + ,m_r_attribute_name ( r_attribute_name ) + ,m_r_attribute_string( r_attribute_string ) +{} + +#endif //> GENERATOROBJECTSTPCNV_GENEVENT_p6_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenParticle_p6.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenParticle_p6.h new file mode 100755 index 0000000000000000000000000000000000000000..66bd436fc1fc049d1d7370c79f04f255d9db0a60 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenParticle_p6.h @@ -0,0 +1,183 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// GenParticle_p6.h +// Header file for class GenParticle_p6 +// Author: S.Binet<binet@cern.ch> +/////////////////////////////////////////////////////////////////// +#ifndef GENERATOROBJECTSTPCNV_GENPARTICLE_p6_H +#define GENERATOROBJECTSTPCNV_GENPARTICLE_p6_H + +// STL includes +#include <vector> +#include <utility> //> for std::pair + +// Forward declaration +class McEventCollectionCnv_p6; + +class GenParticle_p6 +{ + // Make the AthenaPoolCnv class our friend + friend class McEventCollectionCnv_p6; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor: + */ + GenParticle_p6(); + + /// Constructor with (almost all) parameters (can't construct right + /// away the flow vector) + GenParticle_p6( const double px, const double py, const double pz, + const double mass, const int pdgId, + const int status, + const std::size_t flowSize, + const double thetaPolarization, + const double phiPolarization, + const int prodVtx, + const int endVtx, + const int barcode, + const double generated_mass, + const short recoMethod ); + + /////////////////////////////////////////////////////////////////// + // Const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Non-const methods: + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + /** x-component of the 4-momentum of this particle + */ + float m_px; + + /** y-component of the 4-momentum of this particle + */ + float m_py; + + /** z-component of the 4-momentum of this particle + */ + float m_pz; + + /** m-component of the 4-momentum of this particle + */ + float m_m; + + /** identity of this particle, according to the Particle Data Group notation + */ + int m_pdgId; + + /** Status of this particle, as defined for HEPEVT + */ + int m_status; + + /** Flow for this particle + */ + std::vector< std::pair<int, int> > m_flow; + + /** polarization + */ + //std::pair<double, double> m_polarization; + + /** theta polarization + */ + float m_thetaPolarization; + + /** phi polarization + */ + float m_phiPolarization; + + /** Barcode of the production vertex of this particle. + * 0 means no production vertex + */ + int m_prodVtx; + + /** Barcode of the decay vertex of this particle. + * 0 means no production vertex + */ + int m_endVtx; + + /** barcode of this particles (uniquely identifying this particle within + * a given GenEvent) + */ + int m_barcode; + + /** mass of this particle when it was generated + */ + float m_generated_mass; + + /// switch to know which method to chose to better recover the original + /// HepLorentzVector. + /// It is based on isTimelike(), isSpacelike(), isLightlike() and sign(ene) + /// If m_recoMethod == + /// 0: use HepLorentzVector::setVectM( 3vect(px,py,pz), m ) + /// 1: use +(p**2 + m**2) to get the energy (where m**2 is signed) + /// 2: use -(p**2 + m**2) to get the energy (where m**2 is signed) + /// (ex: gluon with negative energy) + short m_recoMethod; +}; + +/////////////////////////////////////////////////////////////////// +/// Inline methods: +/////////////////////////////////////////////////////////////////// + +inline GenParticle_p6::GenParticle_p6(): + m_px ( 0 ), + m_py ( 0 ), + m_pz ( 0 ), + m_m ( 0 ), + m_pdgId ( 0 ), + m_status ( 0 ), + m_flow ( 0 ), + m_thetaPolarization ( 0. ), + m_phiPolarization ( 0. ), + m_prodVtx ( 0 ), + m_endVtx ( 0 ), + m_barcode ( 0 ), + m_generated_mass( 0 ), + m_recoMethod ( 0 ) +{} + +inline GenParticle_p6::GenParticle_p6( const double px, + const double py, + const double pz, + const double m, + const int pdgId, + const int status, + const std::size_t flowSize, + const double thetaPolarization, + const double phiPolarization, + const int prodVtx, + const int endVtx, + const int barcode, + const double generated_mass, + const short recoMethod ): + m_px ( px ), + m_py ( py ), + m_pz ( pz ), + m_m ( m ), + m_pdgId ( pdgId ), + m_status ( status ), + m_flow ( flowSize ), + m_thetaPolarization ( thetaPolarization ), + m_phiPolarization ( phiPolarization ), + m_prodVtx ( prodVtx ), + m_endVtx ( endVtx ), + m_barcode ( barcode ), + m_generated_mass( static_cast<float>(generated_mass) ), + m_recoMethod ( recoMethod ) +{} + +#endif //> GENERATOROBJECTSTPCNV_GENPARTICLE_p6_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenVertex_p6.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenVertex_p6.h new file mode 100755 index 0000000000000000000000000000000000000000..f393b39f3f87332c65010525cb2251eed2257fe4 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GenVertex_p6.h @@ -0,0 +1,120 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// GenVertex_p6.h +// Header file for class GenVertex_p6 +// Author: S.Binet<binet@cern.ch> +/////////////////////////////////////////////////////////////////// +#ifndef GENERATOROBJECTSTPCNV_GENVERTEX_p6_H +#define GENERATOROBJECTSTPCNV_GENVERTEX_p6_H + +// STL includes +#include <vector> + + +// Gaudi includes + +// Forward declaration +class McEventCollectionCnv_p6; + +class GenVertex_p6 +{ + + // Make the AthenaPoolCnv class our friend + friend class McEventCollectionCnv_p6; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor: + */ + GenVertex_p6(); + + /// Constructor with a fair number of parameters + GenVertex_p6( const double x, const double y, const double z, const double t, + const int id, + const std::vector<double>::const_iterator weightsBegin, + const std::vector<double>::const_iterator weightsEnd, + const int barcode); + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + /** x-coordinate of the vertex + */ + float m_x; + + /** y-coordinate of the vertex + */ + float m_y; + + /** z-coordinate of the vertex + */ + float m_z; + + /** t-coordinate of the vertex + */ + float m_t; + + /** collection of barcodes of in-going particles connected to this vertex + */ + std::vector<int> m_particlesIn; + + /** collection of barcodes of out-going particles connected to this vertex + */ + std::vector<int> m_particlesOut; + + /** Id of this vertex + */ + int m_id; + + /** Weights for this vertex + */ + std::vector<float> m_weights; + + /** barcode of this vertex (uniquely identifying a vertex within an event) + */ + int m_barcode; + +}; + +/////////////////////////////////////////////////////////////////// +/// Inline methods: +/////////////////////////////////////////////////////////////////// +inline GenVertex_p6::GenVertex_p6(): + m_x ( 0 ), + m_y ( 0 ), + m_z ( 0 ), + m_t ( 0 ), + m_particlesIn ( ), + m_particlesOut ( ), + m_id ( 0 ), + m_weights ( ), + m_barcode ( 0 ) +{} + +inline GenVertex_p6::GenVertex_p6( const double x, const double y, + const double z, const double t, + const int id, + const std::vector<double>::const_iterator weightsBegin, + const std::vector<double>::const_iterator weightsEnd, + const int barcode ): + m_x ( static_cast<float>(x) ), + m_y ( static_cast<float>(y) ), + m_z ( static_cast<float>(z) ), + m_t ( static_cast<float>(t) ), + m_particlesIn ( ), + m_particlesOut ( ), + m_id ( id ), + m_weights ( weightsBegin, weightsEnd ), + m_barcode ( barcode ) +{} + +#endif //> GENERATOROBJECTSTPCNV_GENVERTEX_p6_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GeneratorObjectsTPCnvDict.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GeneratorObjectsTPCnvDict.h index 25f26646382cd6a4ee2ea96a5d272134eba25919..7a3f9c4f0adb74faaccb3215c2a3468abed8d440 100755 --- a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GeneratorObjectsTPCnvDict.h +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/GeneratorObjectsTPCnvDict.h @@ -41,5 +41,10 @@ #include "GeneratorObjectsTPCnv/GenEvent_p5.h" #include "GeneratorObjectsTPCnv/McEventCollection_p5.h" +#include "GeneratorObjectsTPCnv/GenParticle_p6.h" +#include "GeneratorObjectsTPCnv/GenVertex_p6.h" +#include "GeneratorObjectsTPCnv/GenEvent_p6.h" +#include "GeneratorObjectsTPCnv/McEventCollection_p6.h" + #endif // GENERATOROBJECTSTPCNV_GENERATOROBJECTSTPCNVDICT_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h new file mode 100755 index 0000000000000000000000000000000000000000..76c40db2d8f61e18289fabd9cdb80f974f754bc9 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h @@ -0,0 +1,158 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +// McEventCollectionCnv_p6.h +// Header file for class McEventCollectionCnv_p6 +// Author: S.Binet<binet@cern.ch> +/////////////////////////////////////////////////////////////////// +#ifndef GENERATOROBJECTSTPCNV_MCEVENTCOLLECTIONCNV_p6_H +#define GENERATOROBJECTSTPCNV_MCEVENTCOLLECTIONCNV_p6_H + +// STL includes +#include <unordered_map> + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wkeyword-macro" +#endif +#define private public +#define protected public +#include "AtlasHepMC/GenEvent.h" +#include "AtlasHepMC/GenVertex.h" +#include "AtlasHepMC/GenParticle.h" +#undef private +#undef protected +#ifdef __clang__ +#pragma clang diagnostic pop +#endif +#include "GeneratorObjects/McEventCollection.h" + +// AthenaPoolCnvSvc includes +#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h" + +// GeneratorObjectsTPCnv includes +#include "GeneratorObjectsTPCnv/McEventCollection_p6.h" + +#include "GaudiKernel/ServiceHandle.h" + +class IHepMCWeightSvc; + +// Forward declaration +class MsgStream; +namespace HepMC { struct DataPool; } + +class McEventCollectionCnv_p6 : public T_AthenaPoolTPCnvBase< + McEventCollection, + McEventCollection_p6 + > +{ + + typedef T_AthenaPoolTPCnvBase<McEventCollection, + McEventCollection_p6> Base_t; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor: + */ + McEventCollectionCnv_p6(); + + /** Copy constructor + */ + McEventCollectionCnv_p6( const McEventCollectionCnv_p6& rhs ); + + /** Assignement operator + */ + McEventCollectionCnv_p6& operator=( const McEventCollectionCnv_p6& rhs ); + + /** Destructor + */ + virtual ~McEventCollectionCnv_p6(); + + void setPileup(); + + /** Method creating the transient representation of @c McEventCollection + * from its persistent representation @c McEventCollection_p6 + */ + virtual void persToTrans( const McEventCollection_p6* persObj, + McEventCollection* transObj, + MsgStream &log ) ; + + /** Method creating the persistent representation @c McEventCollection_p6 + * from its transient representation @c McEventCollection + */ + virtual void transToPers( const McEventCollection* transObj, + McEventCollection_p6* persObj, + MsgStream &log ) ; + + /////////////////////////////////////////////////////////////////// + // Protected method: + /////////////////////////////////////////////////////////////////// + protected: + + typedef std::unordered_map<HepMC::GenParticlePtr,int> ParticlesMap_t; + + /** @brief Create a transient @c GenVertex from a persistent one (version 1) + * It returns the new @c GenVertex. + * This method calls @c createGenParticle for each of the out-going + * particles and only for the in-going particle which are orphans (no + * production vertex): for optimisation purposes. + * Note that the map being passed as an argument is to hold the association + * of barcodes to particle so that we can reconnect all the (non-orphan) + * particles to their decay vertex (if any). + */ + HepMC::GenVertexPtr + createGenVertex( const McEventCollection_p6& persEvts, + const GenVertex_p6& vtx, + ParticlesMap_t& bcToPart, + HepMC::DataPool& datapools, HepMC::GenEvent* parent=nullptr ) const; + + /** @brief Create a transient @c GenParticle from a persistent one (vers.1) + * It returns the new @c GenParticle. Note that the map being passed as an + * argument is to hold the association of barcodes to particle so that + * we can reconnect all the particles to their decay vertex (if any). + */ + HepMC::GenParticlePtr + createGenParticle( const GenParticle_p6& p, + ParticlesMap_t& partToEndVtx, + HepMC::DataPool& datapools, HepMC::GenVertexPtr parent=nullptr, bool add_to_output = true ) const; + + /** @brief Method to write a persistent @c GenVertex object. The persistent + * vertex is added to the persistent is added to the persistent + * @c GenEvent. + */ +#ifdef HEPMC3 + void writeGenVertex( HepMC::ConstGenVertexPtr vtx, + McEventCollection_p6& persEvt ) const; +#else + void writeGenVertex( const HepMC::GenVertex& vtx, + McEventCollection_p6& persEvt ) const; + +#endif + /** @brief Method to write a persistent @c GenParticle object + * It returns the index of the persistent @c GenParticle into the + * collection of persistent of @c GenParticles from the + * persistent @c GenEvent + */ +#ifdef HEPMC3 + int writeGenParticle( HepMC::ConstGenParticlePtr p, + McEventCollection_p6& persEvt ) const; +#else + int writeGenParticle( const HepMC::GenParticle& p, + McEventCollection_p6& persEvt ) const; +#endif + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + bool m_isPileup; + ServiceHandle<IHepMCWeightSvc> m_hepMCWeightSvc; +}; +#endif //> GENERATOROBJECTSTPCNV_MCEVENTCOLLECTIONCNV_p6_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollection_p6.h b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollection_p6.h new file mode 100755 index 0000000000000000000000000000000000000000..f3353aca708ca6c02cb691dcebac14431e6a62e9 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/McEventCollection_p6.h @@ -0,0 +1,73 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// McEventCollection_p6.h +// Header file for class McEventCollection_p1 +// Author: S.Binet<binet@cern.ch> +// Date: October 2006 +/////////////////////////////////////////////////////////////////// +#ifndef GENERATOROBJECTSTPCNV_MCEVENTCOLLECTION_p6_H +#define GENERATOROBJECTSTPCNV_MCEVENTCOLLECTION_p6_H + +// STL includes +#include <vector> + +// GeneratorObjectsTPCnv includes +#include "GeneratorObjectsTPCnv/GenEvent_p6.h" +#include "GeneratorObjectsTPCnv/GenParticle_p6.h" +#include "GeneratorObjectsTPCnv/GenVertex_p6.h" + +// Forward declaration +class McEventCollectionCnv_p6; + +class McEventCollection_p6 +{ + /////////////////////////////////////////////////////////////////// + // Friend classes + /////////////////////////////////////////////////////////////////// + + // Make the AthenaPoolCnv class our friend + friend class McEventCollectionCnv_p6; + + /////////////////////////////////////////////////////////////////// + // Public methods: + /////////////////////////////////////////////////////////////////// + public: + + /** Default constructor: + */ + McEventCollection_p6(); + + /////////////////////////////////////////////////////////////////// + // Protected data: + /////////////////////////////////////////////////////////////////// + protected: + + /** The vector of persistent representation of GenEvents + */ + std::vector<GenEvent_p6> m_genEvents; + + /** The vector of persistent representation of GenVertices + */ + std::vector<GenVertex_p6> m_genVertices; + + /** The vector of persistent representation of GenParticles + */ + std::vector<GenParticle_p6> m_genParticles; + +}; + +/////////////////////////////////////////////////////////////////// +// Inline methods: +/////////////////////////////////////////////////////////////////// + +inline McEventCollection_p6::McEventCollection_p6() : + m_genEvents ( ), + m_genVertices ( ), + m_genParticles( ) +{} + +#endif //> GENERATOROBJECTSTPCNV_MCEVENTCOLLECTION_p6_H diff --git a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/selection.xml b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/selection.xml index 460e911a6cac54bd1d7754844abdf52c121b96a0..901c149495dbecceec82b59065d4bf6b45a3174e 100755 --- a/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/selection.xml +++ b/Generators/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv/selection.xml @@ -21,4 +21,13 @@ <class name="std::vector<GenParticle_p5>" /> <class name="GenParticle_p5" /> + + <class name="McEventCollection_p6" id="6B78A751-B31A-4597-BFB6-DDCE62646CF9" /> + <class name="std::vector<GenEvent_p6>" /> + <class name="GenEvent_p6" /> + <class name="std::vector<GenVertex_p6>" /> + <class name="GenVertex_p6" /> + <class name="std::vector<GenParticle_p6>" /> + <class name="GenParticle_p6" /> + </lcgdict> diff --git a/Generators/GeneratorObjectsTPCnv/share/McEventCollectionCnv_p6_test.ref b/Generators/GeneratorObjectsTPCnv/share/McEventCollectionCnv_p6_test.ref new file mode 100644 index 0000000000000000000000000000000000000000..659b228f7f8fcef8fb611be957decef771cd9f39 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/share/McEventCollectionCnv_p6_test.ref @@ -0,0 +1,24 @@ +GeneratorObjectsTPCnv/McEventCollectionCnv_p6_test + + +Initializing Gaudi ApplicationMgr using job opts /afs/cern.ch/user/s/ssnyder/atlas-work3h/build-x86_64-centos7-gcc8-opt/x86_64-centos7-gcc8-opt/jobOptions/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv_test.txt +JobOptionsSvc INFO # =======> /afs/cern.ch/user/s/ssnyder/atlas-work3h/build-x86_64-centos7-gcc8-opt/x86_64-centos7-gcc8-opt/jobOptions/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv_test.txt +JobOptionsSvc INFO # (1,1): ApplicationMgr.Dlls += ["StoreGate", "CLIDComps"] +JobOptionsSvc INFO # (2,1): ApplicationMgr.ExtSvc += ["StoreGateSvc", "StoreGateSvc/MetaDataStore"] +JobOptionsSvc INFO Job options successfully read in from /afs/cern.ch/user/s/ssnyder/atlas-work3h/build-x86_64-centos7-gcc8-opt/x86_64-centos7-gcc8-opt/jobOptions/GeneratorObjectsTPCnv/GeneratorObjectsTPCnv_test.txt +ApplicationMgr SUCCESS +==================================================================================================================================== + Welcome to ApplicationMgr (GaudiCoreSvc v35r1) + running on lxplus728.cern.ch on Fri Mar 12 00:34:20 2021 +==================================================================================================================================== +ApplicationMgr INFO Successfully loaded modules : StoreGate, CLIDComps +ApplicationMgr INFO Application Manager Configured successfully +ClassIDSvc INFO getRegistryEntries: read 866 CLIDRegistry entries for module ALL +EventLoopMgr WARNING Unable to locate service "EventSelector" +EventLoopMgr WARNING No events will be processed from external input. +ApplicationMgr INFO Application Manager Initialized successfully +ApplicationMgr Ready +test1 +HepMCWeightSvc INFO Storing /Generation/Parameters :: WeightNames = { 'weight1' : 0 } +test WARNING No run info! +test WARNING No run info! diff --git a/Generators/GeneratorObjectsTPCnv/src/GeneratorObjectsTPCnv.cxx b/Generators/GeneratorObjectsTPCnv/src/GeneratorObjectsTPCnv.cxx index 51f6d535ee08d3a62ff14908bd4bf5aea5fa5cad..a77659dd61afc912c91782dbc2206498f33f82ab 100644 --- a/Generators/GeneratorObjectsTPCnv/src/GeneratorObjectsTPCnv.cxx +++ b/Generators/GeneratorObjectsTPCnv/src/GeneratorObjectsTPCnv.cxx @@ -38,6 +38,13 @@ #include "GeneratorObjectsTPCnv/McEventCollection_p5.h" #include "GeneratorObjectsTPCnv/McEventCollectionCnv_p5.h" +#include "GeneratorObjectsTPCnv/GenParticle_p6.h" +#include "GeneratorObjectsTPCnv/GenVertex_p6.h" +#include "GeneratorObjectsTPCnv/GenEvent_p6.h" +#include "GeneratorObjectsTPCnv/McEventCollection_p6.h" +#include "GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h" + + DECLARE_TPCNV_FACTORY(McEventCollectionCnv_p1, McEventCollection, McEventCollection_p1, @@ -62,3 +69,8 @@ DECLARE_TPCNV_FACTORY(McEventCollectionCnv_p5, McEventCollection, McEventCollection_p5, Athena::TPCnvVers::Current) + +DECLARE_TPCNV_FACTORY(McEventCollectionCnv_p6, + McEventCollection, + McEventCollection_p6, + Athena::TPCnvVers::Old) diff --git a/Generators/GeneratorObjectsTPCnv/src/McEventCollectionCnv_p6.cxx b/Generators/GeneratorObjectsTPCnv/src/McEventCollectionCnv_p6.cxx new file mode 100755 index 0000000000000000000000000000000000000000..6c42a71a2e5afa5b833f506913ef9de794debd31 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/src/McEventCollectionCnv_p6.cxx @@ -0,0 +1,931 @@ +///////////////////////// -*- C++ -*- ///////////////////////////// + +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ + +// McEventCollectionCnv_p6.cxx +// Implementation file for class McEventCollectionCnv_p6 +// Author: S.Binet<binet@cern.ch> +/////////////////////////////////////////////////////////////////// + +// STL includes +#include <utility> +#include <cmath> +#include <cfloat> // for DBL_EPSILON + +// GeneratorObjectsTPCnv includes +#include "GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h" +#include "HepMcDataPool.h" +#include "GenInterfaces/IHepMCWeightSvc.h" +#include "McEventCollectionCnv_utils.h" + + +/////////////////////////////////////////////////////////////////// +// Constructors +/////////////////////////////////////////////////////////////////// + +McEventCollectionCnv_p6::McEventCollectionCnv_p6() : + Base_t( ), + m_isPileup(false),m_hepMCWeightSvc("HepMCWeightSvc","McEventCollectionCnv_p6") +{} + +McEventCollectionCnv_p6::McEventCollectionCnv_p6( const McEventCollectionCnv_p6& rhs ) : + Base_t( rhs ), + m_isPileup(false),m_hepMCWeightSvc("HepMCWeightSvc","McEventCollectionCnv_p6") +{} + +McEventCollectionCnv_p6& +McEventCollectionCnv_p6::operator=( const McEventCollectionCnv_p6& rhs ) +{ + if ( this != &rhs ) { + Base_t::operator=( rhs ); + m_isPileup=rhs.m_isPileup;m_hepMCWeightSvc = rhs.m_hepMCWeightSvc; + } + return *this; +} + +/////////////////////////////////////////////////////////////////// +// Destructor +/////////////////////////////////////////////////////////////////// + +McEventCollectionCnv_p6::~McEventCollectionCnv_p6() +{ +} + + +void McEventCollectionCnv_p6::persToTrans( const McEventCollection_p6* persObj, + McEventCollection* transObj, + MsgStream& msg ) +{ + msg << MSG::DEBUG << "Loading McEventCollection from persistent state..." + << endmsg; + + // elements are managed by DataPool + if (!m_isPileup) { + transObj->clear(SG::VIEW_ELEMENTS); + } + HepMC::DataPool datapools; + const unsigned int nVertices = persObj->m_genVertices.size(); + if ( datapools.vtx.capacity() - datapools.vtx.allocated() < nVertices ) { + datapools.vtx.reserve( datapools.vtx.allocated() + nVertices ); + } + const unsigned int nParts = persObj->m_genParticles.size(); + if ( datapools.part.capacity() - datapools.part.allocated() < nParts ) { + datapools.part.reserve( datapools.part.allocated() + nParts ); + } + const unsigned int nEvts = persObj->m_genEvents.size(); + if ( datapools.evt.capacity() - datapools.evt.allocated() < nEvts ) { + datapools.evt.reserve( datapools.evt.allocated() + nEvts ); + } + + transObj->reserve( nEvts ); + for ( std::vector<GenEvent_p6>::const_iterator + itr = persObj->m_genEvents.begin(), + itrEnd = persObj->m_genEvents.end(); + itr != itrEnd; + ++itr ) { + const GenEvent_p6& persEvt = *itr; + HepMC::GenEvent * genEvt(0); + if(m_isPileup) { + genEvt = new HepMC::GenEvent(); + } else { + genEvt = datapools.getGenEvent(); + } +#ifdef HEPMC3 + for (unsigned int i = 0; i < persEvt.m_e_attribute_id.size(); ++i) { + genEvt->add_attribute(persEvt.m_e_attribute_name[i], std::make_shared<HepMC3::StringAttribute>(persEvt.m_e_attribute_string[i]), persEvt.m_e_attribute_id[i]); + } + ///Note: the code above takes care about all the attributes: CS, HI, etc. ANd the code below is needed only for the compatibility + + genEvt->add_attribute("signal_process_id", std::make_shared<HepMC3::IntAttribute>(persEvt.m_signalProcessId)); + genEvt->set_event_number(persEvt.m_eventNbr); + genEvt->add_attribute("mpi", std::make_shared<HepMC3::IntAttribute>(persEvt.m_mpi)); + genEvt->add_attribute("event_scale", std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_eventScale)); + genEvt->add_attribute("alphaQCD", std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQCD)); + genEvt->add_attribute("alphaQED", std::make_shared<HepMC3::DoubleAttribute>(persEvt.m_alphaQED)); + genEvt->weights()= persEvt.m_weights; + genEvt->add_attribute("random_states", std::make_shared<HepMC3::VectorLongIntAttribute>(persEvt.m_randomStates)); + + genEvt->set_units(static_cast<HepMC3::Units::MomentumUnit>(persEvt.m_momentumUnit), + static_cast<HepMC3::Units::LengthUnit>(persEvt.m_lengthUnit)); + + //restore weight names from the dedicated svc (which was keeping them in metadata for efficiency) + if(!genEvt->run_info()) genEvt->set_run_info(std::make_shared<HepMC3::GenRunInfo>()); + genEvt->run_info()->set_weight_names(name_index_map_to_names(m_hepMCWeightSvc->weightNames())); + for (unsigned int i = 0; i < persEvt.m_r_attribute_name.size(); ++i) { + genEvt->run_info()->add_attribute(persEvt.m_r_attribute_name[i], std::make_shared<HepMC3::StringAttribute>(persEvt.m_r_attribute_string[i])); + } + // cross-section restore + + if (!persEvt.m_crossSection.empty()) { + auto cs = std::make_shared<HepMC3::GenCrossSection>(); + const std::vector<double>& xsection = persEvt.m_crossSection; + if( static_cast<bool>(xsection[0]) ) + cs->set_cross_section(xsection[2],xsection[1]); + else + cs->set_cross_section(-1.0, -1.0); + genEvt->set_cross_section(cs); + } + + // heavyIon restore + if (!persEvt.m_heavyIon.empty()) { + auto hi = std::make_shared<HepMC3::GenHeavyIon>(); + const std::vector<float>& hIon = persEvt.m_heavyIon; + //AV NOTE THE ORDER + hi->set( + static_cast<int>(hIon[12]), // Ncoll_hard + static_cast<int>(hIon[11]), // Npart_proj + static_cast<int>(hIon[10]), // Npart_targ + static_cast<int>(hIon[9]), // Ncoll + static_cast<int>(hIon[8]), // spectator_neutrons + static_cast<int>(hIon[7]), // spectator_protons + static_cast<int>(hIon[6]), // N_Nwounded_collisions + static_cast<int>(hIon[5]), // Nwounded_N_collisions + static_cast<int>(hIon[4]), // Nwounded_Nwounded_collisions + hIon[3], // impact_parameter + hIon[2], // event_plane_angle + hIon[1], // eccentricity + hIon[0] ); // sigma_inel_NN + genEvt->set_heavy_ion(hi); + } + + + + // pdfinfo restore + if (!persEvt.m_pdfinfo.empty()) + { + const std::vector<double>& pdf = persEvt.m_pdfinfo; + HepMC3::GenPdfInfoPtr pi = std::make_shared<HepMC3::GenPdfInfo>(); + pi->set( + static_cast<int>(pdf[6]), // id1 + static_cast<int>(pdf[5]), // id2 + pdf[4], // x1 + pdf[3], // x2 + pdf[2], // scalePDF + pdf[1], // pdf1 + pdf[0] ); // pdf2 + genEvt->set_pdf_info(pi); + } + transObj->push_back( genEvt ); + + // create a temporary map associating the barcode of an end-vtx to its + // particle. + // As not all particles are stable (d'oh!) we take 50% of the number of + // particles as an initial size of the hash-map (to prevent re-hash) + ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd - persEvt.m_particlesBegin)/2 ); + // This is faster than the HepMC::barcode_to_vertex + std::map<int, HepMC::GenVertexPtr> brc_to_vertex; + + // create the vertices + const unsigned int endVtx = persEvt.m_verticesEnd; + for ( unsigned int iVtx = persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx ) { + auto vtx = createGenVertex( *persObj, persObj->m_genVertices[iVtx], partToEndVtx, datapools, genEvt ); + brc_to_vertex[persObj->m_genVertices[iVtx].m_barcode] = vtx; + } //> end loop over vertices + + // set the signal process vertex + const int sigProcVtx = persEvt.m_signalProcessVtx; + if ( sigProcVtx != 0 && brc_to_vertex.count(sigProcVtx) ) { + HepMC::set_signal_process_vertex(genEvt, brc_to_vertex[sigProcVtx] ); + } + + // connect particles to their end vertices + for ( ParticlesMap_t::iterator p = partToEndVtx.begin(), endItr = partToEndVtx.end(); p != endItr; ++p ) { + if ( brc_to_vertex.count(p->second) ) { + auto decayVtx = brc_to_vertex[p->second]; + decayVtx->add_particle_in( p->first ); + } else { + msg << MSG::ERROR << "GenParticle points to null end vertex !!" << endmsg; + } + } + // set the beam particles + const int beamPart1 = persEvt.m_beamParticle1; + const int beamPart2 = persEvt.m_beamParticle2; + if ( beamPart1 != 0 && beamPart2 != 0 ) { + genEvt->set_beam_particles(HepMC::barcode_to_particle(genEvt, beamPart1), + HepMC::barcode_to_particle(genEvt, beamPart2)); + } + +#else + genEvt->m_signal_process_id = persEvt.m_signalProcessId; + genEvt->m_event_number = persEvt.m_eventNbr; + genEvt->m_mpi = persEvt.m_mpi; + genEvt->m_event_scale = persEvt.m_eventScale; + genEvt->m_alphaQCD = persEvt.m_alphaQCD; + genEvt->m_alphaQED = persEvt.m_alphaQED; + genEvt->m_signal_process_vertex = 0; + genEvt->m_beam_particle_1 = 0; + genEvt->m_beam_particle_2 = 0; + genEvt->m_weights = persEvt.m_weights; + genEvt->m_random_states = persEvt.m_randomStates; + genEvt->m_vertex_barcodes.clear(); + genEvt->m_particle_barcodes.clear(); + genEvt->m_momentum_unit = static_cast<HepMC::Units::MomentumUnit>(persEvt.m_momentumUnit); + genEvt->m_position_unit = static_cast<HepMC::Units::LengthUnit>(persEvt.m_lengthUnit); + + //restore weight names from the dedicated svc (which was keeping them in metadata for efficiency) + genEvt->m_weights.m_names = m_hepMCWeightSvc->weightNames(); + + // cross-section restore + if( genEvt->m_cross_section ) + delete genEvt->m_cross_section; + genEvt->m_cross_section = 0; + + if (!persEvt.m_crossSection.empty()) { + genEvt->m_cross_section = new HepMC::GenCrossSection(); + const std::vector<double>& xsection = persEvt.m_crossSection; + if( static_cast<bool>(xsection[0]) ) + genEvt->m_cross_section->set_cross_section(xsection[2],xsection[1]); + } + + // heavyIon restore + if(genEvt->m_heavy_ion ) + delete genEvt->m_heavy_ion; + genEvt->m_heavy_ion = 0; + if (!persEvt.m_heavyIon.empty()) { + const std::vector<float>& hIon = persEvt.m_heavyIon; + genEvt->m_heavy_ion = new HepMC::HeavyIon + ( + static_cast<int>(hIon[12]), // Ncoll_hard + static_cast<int>(hIon[11]), // Npart_proj + static_cast<int>(hIon[10]), // Npart_targ + static_cast<int>(hIon[9]), // Ncoll + static_cast<int>(hIon[8]), // spectator_neutrons + static_cast<int>(hIon[7]), // spectator_protons + static_cast<int>(hIon[6]), // N_Nwounded_collisions + static_cast<int>(hIon[5]), // Nwounded_N_collisions + static_cast<int>(hIon[4]), // Nwounded_Nwounded_collisions + hIon[3], // impact_parameter + hIon[2], // event_plane_angle + hIon[1], // eccentricity + hIon[0] ); // sigma_inel_NN + } + + + + // pdfinfo restore + if(genEvt->m_pdf_info) + delete genEvt->m_pdf_info; + genEvt->m_pdf_info = 0; + if (!persEvt.m_pdfinfo.empty()) { + const std::vector<double>& pdf = persEvt.m_pdfinfo; + genEvt->m_pdf_info = new HepMC::PdfInfo + ( + static_cast<int>(pdf[8]), // id1 + static_cast<int>(pdf[7]), // id2 + pdf[4], // x1 + pdf[3], // x2 + pdf[2], // scalePDF + pdf[1], // pdf1 + pdf[0], // pdf2 + static_cast<int>(pdf[6]), // pdf_id1 + static_cast<int>(pdf[5]) // pdf_id2 + ); + } + + transObj->push_back( genEvt ); + + // create a temporary map associating the barcode of an end-vtx to its + // particle. + // As not all particles are stable (d'oh!) we take 50% of the number of + // particles as an initial size of the hash-map (to prevent re-hash) + ParticlesMap_t partToEndVtx( (persEvt.m_particlesEnd- + persEvt.m_particlesBegin)/2 ); + + // create the vertices + const unsigned int endVtx = persEvt.m_verticesEnd; + for ( unsigned int iVtx= persEvt.m_verticesBegin; iVtx != endVtx; ++iVtx ) { + genEvt->add_vertex( createGenVertex( *persObj, + persObj->m_genVertices[iVtx], + partToEndVtx, + datapools ) ); + } //> end loop over vertices + + // set the signal process vertex + const int sigProcVtx = persEvt.m_signalProcessVtx; + if ( sigProcVtx != 0 ) { + genEvt->set_signal_process_vertex( genEvt->barcode_to_vertex( sigProcVtx ) ); + } + + // connect particles to their end vertices + for ( ParticlesMap_t::iterator + p = partToEndVtx.begin(), + endItr = partToEndVtx.end(); + p != endItr; + ++p ) { + auto decayVtx = HepMC::barcode_to_vertex(genEvt, p->second ); + if ( decayVtx ) { + decayVtx->add_particle_in( p->first ); + } else { + msg << MSG::ERROR + << "GenParticle points to null end vertex !!" + << endmsg; + } + } + + // set the beam particles + const int beamPart1 = persEvt.m_beamParticle1; + const int beamPart2 = persEvt.m_beamParticle2; + if ( beamPart1 != 0 && beamPart2 !=0 ) { + genEvt->set_beam_particles(genEvt->barcode_to_particle(beamPart1), + genEvt->barcode_to_particle(beamPart2)); + } + +#endif + + + } //> end loop over m_genEvents + + msg << MSG::DEBUG << "Loaded McEventCollection from persistent state [OK]" + << endmsg; + + return; +} + +void McEventCollectionCnv_p6::transToPers( const McEventCollection* transObj, + McEventCollection_p6* persObj, + MsgStream& msg ) +{ + msg << MSG::DEBUG << "Creating persistent state of McEventCollection..." + << endmsg; + persObj->m_genEvents.reserve( transObj->size() ); + + const std::pair<unsigned int,unsigned int> stats = nbrParticlesAndVertices( transObj ); + persObj->m_genParticles.reserve( stats.first ); + persObj->m_genVertices.reserve ( stats.second ); + + const McEventCollection::const_iterator itrEnd = transObj->end(); + for ( McEventCollection::const_iterator itr = transObj->begin(); + itr != itrEnd; + ++itr ) { + const unsigned int nPersVtx = persObj->m_genVertices.size(); + const unsigned int nPersParts = persObj->m_genParticles.size(); + const HepMC::GenEvent* genEvt = *itr; +#ifdef HEPMC3 + //save the weight names to metadata via the HepMCWeightSvc + if (genEvt->run_info()) { + if (!genEvt->run_info()->weight_names().empty()) { + m_hepMCWeightSvc->setWeightNames( names_to_name_index_map(genEvt->weight_names()) ).ignore(); + } else { + //AV : This to be decided if one would like to have default names. + //std::vector<std::string> names{"0"}; + //m_hepMCWeightSvc->setWeightNames( names_to_name_index_map(names) ); + } + } + + auto A_mpi=genEvt->attribute<HepMC3::IntAttribute>("mpi"); + auto A_signal_process_id=genEvt->attribute<HepMC3::IntAttribute>("signal_process_id"); + auto A_event_scale=genEvt->attribute<HepMC3::DoubleAttribute>("event_scale"); + auto A_alphaQCD=genEvt->attribute<HepMC3::DoubleAttribute>("alphaQCD"); + auto A_alphaQED=genEvt->attribute<HepMC3::DoubleAttribute>("alphaQED"); + auto signal_process_vertex = HepMC::signal_process_vertex(genEvt); + auto A_random_states=genEvt->attribute<HepMC3::VectorLongIntAttribute>("random_states"); + auto beams=genEvt->beams(); + persObj->m_genEvents. + push_back( GenEvent_p6(A_signal_process_id?(A_signal_process_id->value()):-1, + genEvt->event_number(), + A_mpi?(A_mpi->value()):-1, + A_event_scale?(A_event_scale->value()):0.0, + A_alphaQCD?(A_alphaQCD->value()):0.0, + A_alphaQED?(A_alphaQED->value()):0.0, + signal_process_vertex?HepMC::barcode(signal_process_vertex):0, + beams.size()>0?HepMC::barcode(beams[0]):0, + beams.size()>1?HepMC::barcode(beams[1]):0, + genEvt->weights(), + A_random_states?(A_random_states->value()):std::vector<long>(), + std::vector<double>(), // cross section + std::vector<float>(), // heavyion + std::vector<double>(), // pdf info + genEvt->momentum_unit(), + genEvt->length_unit(), + nPersVtx, + nPersVtx + genEvt->vertices().size(), + nPersParts, + nPersParts + genEvt->particles().size() ) ); + { + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::map< std::string, std::map<int, std::shared_ptr<HepMC3::Attribute> > > e_atts = genEvt->attributes(); + for (auto& attmap: e_atts) { + for (auto& att: attmap.second) { + persEvt.m_e_attribute_name.push_back(attmap.first); + persEvt.m_e_attribute_id.push_back(att.first); + std::string st; + bool status = att.second->to_string(st); + /// One can add here checks for the status + persEvt.m_e_attribute_string.push_back(st); + } + } + auto ri = genEvt->run_info(); + if (ri) { + std::map< std::string, std::shared_ptr<HepMC3::Attribute> > r_atts = ri->attributes(); + for (auto& att: r_atts) { + persEvt.m_r_attribute_name.push_back(att.first); + std::string st; + bool status = att.second->to_string(st); + /// One can add here checks for the status + persEvt.m_r_attribute_string.push_back(st); + } + } + //Actually, with this piece there is no need to treat the CS and HI separately. + } + //HepMC::GenCrossSection encoding + if (genEvt->cross_section()) { + auto cs=genEvt->cross_section(); + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<double>& crossSection = persEvt.m_crossSection; + crossSection.resize(3); + crossSection[2] = cs->xsec(); + crossSection[1] = cs->xsec_err(); + crossSection[0] = static_cast<double>(cs->is_valid()); + /// HepMC3 uses different defaults for "wrong" cross-section + /// Here we try to mimic HepMC2 + if (crossSection[2] < 0) { + crossSection[2] = 0.0; + if (crossSection[1] < 0) { + crossSection[1] = 0.0; + } + crossSection[0] = 0.0; + } + + } + + //HepMC::HeavyIon encoding + if (genEvt->heavy_ion()) { + auto hi=genEvt->heavy_ion(); + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<float>& heavyIon = persEvt.m_heavyIon; + heavyIon.resize(13); + heavyIon[12] = static_cast<float>(hi->Ncoll_hard); + heavyIon[11] = static_cast<float>(hi->Npart_proj); + heavyIon[10] = static_cast<float>(hi->Npart_targ); + heavyIon[9] = static_cast<float>(hi->Ncoll); + heavyIon[8] = static_cast<float>(hi->spectator_neutrons); + heavyIon[7] = static_cast<float>(hi->spectator_protons); + heavyIon[6] = static_cast<float>(hi->N_Nwounded_collisions); + heavyIon[5] = static_cast<float>(hi->Nwounded_N_collisions); + heavyIon[4] = static_cast<float>(hi->Nwounded_Nwounded_collisions); + heavyIon[3] = hi->impact_parameter; + heavyIon[2] = hi->event_plane_angle; + heavyIon[1] = hi->eccentricity; + heavyIon[0] = hi->sigma_inel_NN; + } + + //PdfInfo encoding + if (genEvt->pdf_info()) { + auto pi=genEvt->pdf_info(); + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<double>& pdfinfo = persEvt.m_pdfinfo; + pdfinfo.resize(9); + pdfinfo[8] = static_cast<double>(pi->parton_id[0]); + pdfinfo[7] = static_cast<double>(pi->parton_id[1]); + pdfinfo[6] = static_cast<double>(pi->pdf_id[0]); + pdfinfo[5] = static_cast<double>(pi->pdf_id[1]); + pdfinfo[4] = pi->x[0]; + pdfinfo[3] = pi->x[1]; + pdfinfo[2] = pi->scale; + pdfinfo[1] = pi->xf[0]; + pdfinfo[0] = pi->xf[1]; + } + + // create vertices + for (auto v: genEvt->vertices()) { + writeGenVertex( v, *persObj ); + } +#else + const int signalProcessVtx = genEvt->m_signal_process_vertex + ? genEvt->m_signal_process_vertex->barcode() + : 0; + const int beamParticle1Barcode = genEvt->m_beam_particle_1 + ? genEvt->m_beam_particle_1->barcode() + : 0; + const int beamParticle2Barcode = genEvt->m_beam_particle_2 + ? genEvt->m_beam_particle_2->barcode() + : 0; + + //save the weight names to metadata via the HepMCWeightSvc + m_hepMCWeightSvc->setWeightNames( genEvt->m_weights.m_names ).ignore(); + + + persObj->m_genEvents. + push_back( GenEvent_p6( genEvt->m_signal_process_id, + genEvt->m_event_number, + genEvt->mpi(), // number of multi particle interactions + genEvt->m_event_scale, + genEvt->m_alphaQCD, + genEvt->m_alphaQED, + signalProcessVtx, + beamParticle1Barcode, // barcodes of beam particles + beamParticle2Barcode, + genEvt->m_weights.m_weights, + genEvt->m_random_states, + std::vector<double>(), // cross section + std::vector<float>(), // heavyion + std::vector<double>(), // pdf info + genEvt->m_momentum_unit, + genEvt->m_position_unit, + nPersVtx, + nPersVtx + genEvt->vertices_size(), + nPersParts, + nPersParts + genEvt->particles_size() ) ); + //HepMC::GenCrossSection encoding + if (genEvt->m_cross_section) { + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<double>& crossSection = persEvt.m_crossSection; + crossSection.resize(3); + crossSection[2] = genEvt->m_cross_section->m_cross_section; + crossSection[1] = genEvt->m_cross_section->m_cross_section_error; + crossSection[0] = static_cast<double>(genEvt->m_cross_section->m_is_set); + } + + //HepMC::HeavyIon encoding + if (genEvt->m_heavy_ion) { + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<float>& heavyIon = persEvt.m_heavyIon; + heavyIon.resize(13); + heavyIon[12] = static_cast<float>(genEvt->m_heavy_ion->m_Ncoll_hard); + heavyIon[11] = static_cast<float>(genEvt->m_heavy_ion->m_Npart_proj); + heavyIon[10] = static_cast<float>(genEvt->m_heavy_ion->m_Npart_targ); + heavyIon[9] = static_cast<float>(genEvt->m_heavy_ion->m_Ncoll); + heavyIon[8] = static_cast<float>(genEvt->m_heavy_ion->m_spectator_neutrons); + heavyIon[7] = static_cast<float>(genEvt->m_heavy_ion->m_spectator_protons); + heavyIon[6] = static_cast<float>(genEvt->m_heavy_ion->m_N_Nwounded_collisions); + heavyIon[5] = static_cast<float>(genEvt->m_heavy_ion->m_Nwounded_N_collisions); + heavyIon[4] = static_cast<float>(genEvt->m_heavy_ion->m_Nwounded_Nwounded_collisions); + heavyIon[3] = genEvt->m_heavy_ion->m_impact_parameter; + heavyIon[2] = genEvt->m_heavy_ion->m_event_plane_angle; + heavyIon[1] = genEvt->m_heavy_ion->m_eccentricity; + heavyIon[0] = genEvt->m_heavy_ion->m_sigma_inel_NN; + } + + //PdfInfo encoding + if (genEvt->m_pdf_info) { + GenEvent_p6& persEvt = persObj->m_genEvents.back(); + std::vector<double>& pdfinfo = persEvt.m_pdfinfo; + pdfinfo.resize(9); + pdfinfo[8] = static_cast<double>(genEvt->m_pdf_info->m_id1); + pdfinfo[7] = static_cast<double>(genEvt->m_pdf_info->m_id2); + pdfinfo[6] = static_cast<double>(genEvt->m_pdf_info->m_pdf_id1); + pdfinfo[5] = static_cast<double>(genEvt->m_pdf_info->m_pdf_id2); + pdfinfo[4] = genEvt->m_pdf_info->m_x1; + pdfinfo[3] = genEvt->m_pdf_info->m_x2; + pdfinfo[2] = genEvt->m_pdf_info->m_scalePDF; + pdfinfo[1] = genEvt->m_pdf_info->m_pdf1; + pdfinfo[0] = genEvt->m_pdf_info->m_pdf2; + } + + // create vertices + const HepMC::GenEvent::vertex_const_iterator endVtx=genEvt->vertices_end(); + for ( HepMC::GenEvent::vertex_const_iterator i = genEvt->vertices_begin(); + i != endVtx; + ++i ) { + writeGenVertex( **i, *persObj ); + } +#endif + + } //> end loop over GenEvents + + msg << MSG::DEBUG << "Created persistent state of HepMC::GenEvent [OK]" << endmsg; + return; +} + + +HepMC::GenVertexPtr +McEventCollectionCnv_p6::createGenVertex( const McEventCollection_p6& persEvt, + const GenVertex_p6& persVtx, + ParticlesMap_t& partToEndVtx, HepMC::DataPool& datapools + ,HepMC::GenEvent* parent + ) const +{ + HepMC::GenVertexPtr vtx(nullptr); + if(m_isPileup) { + vtx=HepMC::newGenVertexPtr(); + } else { + vtx = datapools.getGenVertex(); + } + if (parent ) parent->add_vertex(vtx); +#ifdef HEPMC3 + vtx->set_position(HepMC::FourVector( persVtx.m_x , persVtx.m_y , persVtx.m_z ,persVtx.m_t )); + //AV ID cannot be assigned in HepMC3. And its meaning in HepMC2 is not clear. + vtx->set_status(persVtx.m_id); + vtx->add_attribute("weights",std::make_shared<HepMC3::VectorFloatAttribute>(persVtx.m_weights)); + vtx->add_attribute("barcode",std::make_shared<HepMC3::IntAttribute>(persVtx.m_barcode)); + // handle the in-going (orphans) particles + const unsigned int nPartsIn = persVtx.m_particlesIn.size(); + for ( unsigned int i = 0; i != nPartsIn; ++i ) { + createGenParticle( persEvt.m_genParticles[persVtx.m_particlesIn[i]], partToEndVtx, datapools, vtx, false ); + } + + HepMC::suggest_barcode(vtx,persVtx.m_barcode); + // now handle the out-going particles + const unsigned int nPartsOut = persVtx.m_particlesOut.size(); + for ( unsigned int i = 0; i != nPartsOut; ++i ) { + createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]], partToEndVtx, datapools, vtx ); + } +#else + vtx->m_position.setX( persVtx.m_x ); + vtx->m_position.setY( persVtx.m_y ); + vtx->m_position.setZ( persVtx.m_z ); + vtx->m_position.setT( persVtx.m_t ); + vtx->m_particles_in.clear(); + vtx->m_particles_out.clear(); + vtx->m_id = persVtx.m_id; + vtx->m_weights.m_weights.reserve( persVtx.m_weights.size() ); + vtx->m_weights.m_weights.assign ( persVtx.m_weights.begin(), + persVtx.m_weights.end() ); + vtx->m_event = 0; + vtx->m_barcode = persVtx.m_barcode; + + // handle the in-going (orphans) particles + const unsigned int nPartsIn = persVtx.m_particlesIn.size(); + for ( unsigned int i = 0; i != nPartsIn; ++i ) { + createGenParticle( persEvt.m_genParticles[persVtx.m_particlesIn[i]], + partToEndVtx, + datapools ); + } + + // now handle the out-going particles + const unsigned int nPartsOut = persVtx.m_particlesOut.size(); + for ( unsigned int i = 0; i != nPartsOut; ++i ) { + vtx->add_particle_out( createGenParticle( persEvt.m_genParticles[persVtx.m_particlesOut[i]], + partToEndVtx, + datapools ) ); + } +#endif + + return vtx; +} + +HepMC::GenParticlePtr +McEventCollectionCnv_p6::createGenParticle( const GenParticle_p6& persPart, + ParticlesMap_t& partToEndVtx, HepMC::DataPool& datapools ,HepMC::GenVertexPtr parent, bool add_to_output ) const +{ + HepMC::GenParticlePtr p(nullptr); + if (m_isPileup) { + p = HepMC::newGenParticlePtr(); + } else { + p = datapools.getGenParticle(); + } + if (parent) add_to_output?parent->add_particle_out(p):parent->add_particle_in(p); +#ifdef HEPMC3 + p->set_pdg_id( persPart.m_pdgId); + p->set_status( persPart.m_status); + p->add_attribute("phi",std::make_shared<HepMC3::DoubleAttribute>(persPart.m_phiPolarization)); + p->add_attribute("theta",std::make_shared<HepMC3::DoubleAttribute>(persPart.m_thetaPolarization)); + p->add_attribute("barcode",std::make_shared<HepMC3::IntAttribute>(persPart.m_barcode)); + p->set_generated_mass(persPart.m_generated_mass); + + // Note: do the E calculation in extended (long double) precision. + // That happens implicitly on x86 with optimization on; saying it + // explicitly ensures that we get the same results with and without + // optimization. (If this is a performance issue for platforms + // other than x86, one could change to double for those platforms.) + if ( 0 == persPart.m_recoMethod ) { + double temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px + + (long double)(persPart.m_py)*persPart.m_py + + (long double)(persPart.m_pz)*persPart.m_pz + + (long double)(persPart.m_m) *persPart.m_m ); + p->set_momentum( HepMC::FourVector(persPart.m_px,persPart.m_py,persPart.m_pz,temp_e)); + } else { + const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 ); + const double persPart_ene = + std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px + + (long double)(persPart.m_py)*persPart.m_py + + (long double)(persPart.m_pz)*persPart.m_pz + + signM2* (long double)(persPart.m_m)* persPart.m_m)); + const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 ); + p->set_momentum(HepMC::FourVector( persPart.m_px, + persPart.m_py, + persPart.m_pz, + signEne * persPart_ene )); + } + + // setup flow + std::vector<int> flows; + const unsigned int nFlow = persPart.m_flow.size(); + for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow ) { + flows.push_back(persPart.m_flow[iFlow].second ); + } + //We construct it here as vector w/o gaps. + p->add_attribute("flows", std::make_shared<HepMC3::VectorIntAttribute>(flows)); +#else + p->m_pdg_id = persPart.m_pdgId; + p->m_status = persPart.m_status; + p->m_polarization.m_theta= static_cast<double>(persPart.m_thetaPolarization); + p->m_polarization.m_phi = static_cast<double>(persPart.m_phiPolarization ); + p->m_production_vertex = 0; + p->m_end_vertex = 0; + p->m_barcode = persPart.m_barcode; + p->m_generated_mass = static_cast<double>(persPart.m_generated_mass); + + // Note: do the E calculation in extended (long double) precision. + // That happens implicitly on x86 with optimization on; saying it + // explicitly ensures that we get the same results with and without + // optimization. (If this is a performance issue for platforms + // other than x86, one could change to double for those platforms.) + if ( 0 == persPart.m_recoMethod ) { + + p->m_momentum.setPx( persPart.m_px); + p->m_momentum.setPy( persPart.m_py); + p->m_momentum.setPz( persPart.m_pz); + double temp_e = std::sqrt( (long double)(persPart.m_px)*persPart.m_px + + (long double)(persPart.m_py)*persPart.m_py + + (long double)(persPart.m_pz)*persPart.m_pz + + (long double)(persPart.m_m) *persPart.m_m ); + p->m_momentum.setE( temp_e); + } else { + const int signM2 = ( persPart.m_m >= 0. ? 1 : -1 ); + const double persPart_ene = + std::sqrt( std::abs((long double)(persPart.m_px)*persPart.m_px + + (long double)(persPart.m_py)*persPart.m_py + + (long double)(persPart.m_pz)*persPart.m_pz + + signM2* (long double)(persPart.m_m)* persPart.m_m)); + const int signEne = ( persPart.m_recoMethod == 1 ? 1 : -1 ); + p->m_momentum.set( persPart.m_px, + persPart.m_py, + persPart.m_pz, + signEne * persPart_ene ); + } + + // setup flow + const unsigned int nFlow = persPart.m_flow.size(); + p->m_flow.clear(); + for ( unsigned int iFlow= 0; iFlow != nFlow; ++iFlow ) { + p->m_flow.set_icode( persPart.m_flow[iFlow].first, + persPart.m_flow[iFlow].second ); + } +#endif + + if ( persPart.m_endVtx != 0 ) { + partToEndVtx[p] = persPart.m_endVtx; + } + + return p; +} + +#ifdef HEPMC3 +void McEventCollectionCnv_p6::writeGenVertex( HepMC::ConstGenVertexPtr vtx, + McEventCollection_p6& persEvt ) const +{ + const HepMC::FourVector& position = vtx->position(); + auto A_weights=vtx->attribute<HepMC3::VectorDoubleAttribute>("weights"); + auto A_barcode=vtx->attribute<HepMC3::IntAttribute>("barcode"); + std::vector<double> weights=A_weights?(A_weights->value()):std::vector<double>(); + persEvt.m_genVertices.push_back( + GenVertex_p6( position.x(), + position.y(), + position.z(), + position.t(), + vtx->status(), + weights.begin(), + weights.end(), + A_barcode?(A_barcode->value()):vtx->id()) ); + GenVertex_p6& persVtx = persEvt.m_genVertices.back(); + + // we write only the orphans in-coming particles and beams + persVtx.m_particlesIn.reserve(vtx->particles_in().size()); + for (auto p: vtx->particles_in()) { + if ( !p->production_vertex() || p->production_vertex()->id() == 0 ) { + persVtx.m_particlesIn.push_back( writeGenParticle( p, persEvt ) ); + } + } + + persVtx.m_particlesOut.reserve(vtx->particles_out().size()); + for (auto p: vtx->particles_out()) { + persVtx.m_particlesOut.push_back( writeGenParticle( p, persEvt ) ); + } + + return; +} +#else +void McEventCollectionCnv_p6::writeGenVertex( const HepMC::GenVertex& vtx, + McEventCollection_p6& persEvt ) const +{ + const HepMC::FourVector& position = vtx.m_position; + persEvt.m_genVertices.push_back( + GenVertex_p6( position.x(), + position.y(), + position.z(), + position.t(), + vtx.m_id, + vtx.m_weights.m_weights.begin(), + vtx.m_weights.m_weights.end(), + vtx.m_barcode ) ); + GenVertex_p6& persVtx = persEvt.m_genVertices.back(); + + // we write only the orphans in-coming particles + const std::vector<HepMC::GenParticlePtr>::const_iterator endInVtx = vtx.m_particles_in.end(); + persVtx.m_particlesIn.reserve(vtx.m_particles_in.size()); + for ( std::vector<HepMC::GenParticlePtr>::const_iterator p = vtx.m_particles_in.begin(); + p != endInVtx; + ++p ) { + if ( 0 == (*p)->production_vertex() ) { + persVtx.m_particlesIn.push_back( writeGenParticle( **p, persEvt ) ); + } + } + + const std::vector<HepMC::GenParticlePtr>::const_iterator endOutVtx = vtx.m_particles_out.end(); + persVtx.m_particlesOut.reserve(vtx.m_particles_out.size()); + for ( std::vector<HepMC::GenParticlePtr>::const_iterator p = vtx.m_particles_out.begin(); + p != endOutVtx; + ++p ) { + persVtx.m_particlesOut.push_back( writeGenParticle( **p, persEvt ) ); + } + + return; +} +#endif + +#ifdef HEPMC3 +int McEventCollectionCnv_p6::writeGenParticle( HepMC::ConstGenParticlePtr p, + McEventCollection_p6& persEvt ) const +{ + const HepMC::FourVector mom = p->momentum(); + const double ene = mom.e(); + const double m2 = mom.m2(); + + // Definitions of Bool isTimeLilike, isSpacelike and isLightlike according to HepLorentzVector definition + const bool useP2M2 = !(m2 > 0) && // !isTimelike + (m2 < 0) && // isSpacelike + !(std::abs(m2) < 2.0*DBL_EPSILON*ene*ene); // !isLightlike + auto A_flows=p->attribute<HepMC3::VectorIntAttribute>("flows"); + auto A_phi=p->attribute<HepMC3::DoubleAttribute>("phi"); + auto A_theta=p->attribute<HepMC3::DoubleAttribute>("theta"); + + const short recoMethod = ( !useP2M2 ? 0: ( ene >= 0.? 1: 2 ) ); + persEvt.m_genParticles. + push_back( GenParticle_p6( mom.px(), + mom.py(), + mom.pz(), + mom.m(), + p->pdg_id(), + p->status(), + A_flows?(A_flows->value().size()):0, + A_theta?(A_theta->value()):0.0, + A_phi?(A_phi->value()):0.0, + p->production_vertex()? HepMC::barcode(p->production_vertex()):0, + p->end_vertex()? HepMC::barcode(p->end_vertex()):0, + HepMC::barcode(p), + p->generated_mass(), + recoMethod ) ); + + std::vector< std::pair<int,int> > flow_hepmc2; + if(A_flows) flow_hepmc2=vector_to_vector_int_int(A_flows->value()); + persEvt.m_genParticles.back().m_flow.assign( flow_hepmc2.begin(),flow_hepmc2.end() ); + + // we return the index of the particle in the big vector of particles + // (contained by the persistent GenEvent) + return (persEvt.m_genParticles.size() - 1); + +} +#else +int McEventCollectionCnv_p6::writeGenParticle( const HepMC::GenParticle& p, + McEventCollection_p6& persEvt ) const +{ + const HepMC::FourVector& mom = p.m_momentum; + const double ene = mom.e(); + const double m2 = mom.m2(); + + // Definitions of Bool isTimeLilike, isSpacelike and isLightlike according to HepLorentzVector definition + const bool useP2M2 = !(m2 > 0) && // !isTimelike + (m2 < 0) && // isSpacelike + !(std::abs(m2) < 2.0*DBL_EPSILON*ene*ene); // !isLightlike + + const short recoMethod = ( !useP2M2 + ? 0 + : ( ene >= 0. //*GeV + ? 1 + : 2 ) ); + + + persEvt.m_genParticles. + push_back( GenParticle_p6( mom.px(), + mom.py(), + mom.pz(), + mom.m(), + p.m_pdg_id, + p.m_status, + p.m_flow.size(), + p.m_polarization.theta(), + p.m_polarization.phi(), + p.m_production_vertex + ? p.m_production_vertex->barcode() + : 0, + p.m_end_vertex + ? p.m_end_vertex->barcode() + : 0, + p.m_barcode, + p.m_generated_mass, + recoMethod ) ); + persEvt.m_genParticles.back().m_flow.assign( p.m_flow.begin(), + p.m_flow.end() ); + + // we return the index of the particle in the big vector of particles + // (contained by the persistent GenEvent) + return (persEvt.m_genParticles.size() - 1); +} +#endif + +void McEventCollectionCnv_p6::setPileup() { + m_isPileup = true; +} diff --git a/Generators/GeneratorObjectsTPCnv/test/McEventCollectionCnv_p6_test.cxx b/Generators/GeneratorObjectsTPCnv/test/McEventCollectionCnv_p6_test.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9f1e82ee23d4def6cd2847de6a25875eabf77942 --- /dev/null +++ b/Generators/GeneratorObjectsTPCnv/test/McEventCollectionCnv_p6_test.cxx @@ -0,0 +1,288 @@ +/* + Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +*/ +/** + * @file GeneratorObjectsTPCnv/test/McEventCollectionCnv_p6_test.cxx + * @brief Tests for McEventCollectionCnv_p6. + */ + + +#undef NDEBUG +#include <cassert> +#include <iostream> +// HepMC includes +#include "AtlasHepMC/GenEvent.h" +#include "AtlasHepMC/GenVertex.h" +#include "AtlasHepMC/GenParticle.h" +#include "TestTools/initGaudi.h" + +// CLHEP includes +#include "CLHEP/Units/SystemOfUnits.h" + +#include "GeneratorObjectsTPCnv/McEventCollectionCnv_p6.h" + +void compareGenParticle(HepMC::ConstGenParticlePtr p1, + HepMC::ConstGenParticlePtr p2) +{ + assert (HepMC::barcode(p1) == HepMC::barcode(p2)); + assert (p1->status() == p2->status()); + assert (p1->pdg_id() == p2->pdg_id()); + assert ((p1->momentum().px()) == (p2->momentum().px())); + assert ((p1->momentum().py()) == (p2->momentum().py())); + assert ((p1->momentum().pz()) == (p2->momentum().pz())); + assert (float(p1->momentum().m()) == float(p2->momentum().m())); // only persistified with float precision + + return; +} + + +void compareGenVertex(HepMC::ConstGenVertexPtr v1, + HepMC::ConstGenVertexPtr v2) +{ + assert (HepMC::barcode(v1) == HepMC::barcode(v2)); + assert (float(v1->position().x()) == float(v2->position().x())); // only persistified with float precision + assert (float(v1->position().y()) == float(v2->position().y())); // only persistified with float precision + assert (float(v1->position().z()) == float(v2->position().z())); // only persistified with float precision + assert (float(v1->position().t()) == float(v2->position().t())); // only persistified with float precision + assert (HepMC::particles_in_size(v1) == HepMC::particles_in_size(v2)); + assert (HepMC::particles_out_size(v1) == HepMC::particles_out_size(v2)); + +#ifdef HEPMC3 + std::vector<HepMC::ConstGenParticlePtr>::const_iterator originalPartInIter(v1->particles_in().begin()); + const std::vector<HepMC::ConstGenParticlePtr>::const_iterator endOfOriginalListOfParticlesIn(v1->particles_in().end()); + std::vector<HepMC::ConstGenParticlePtr>::const_iterator resetPartInIter(v2->particles_in().begin()); + const std::vector<HepMC::ConstGenParticlePtr>::const_iterator endOfResetListOfParticlesIn(v2->particles_in().end()); +#else + HepMC::GenVertex::particles_in_const_iterator originalPartInIter(v1->particles_in_const_begin()); + const HepMC::GenVertex::particles_in_const_iterator endOfOriginalListOfParticlesIn(v1->particles_in_const_end()); + HepMC::GenVertex::particles_in_const_iterator resetPartInIter(v2->particles_in_const_begin()); + const HepMC::GenVertex::particles_in_const_iterator endOfResetListOfParticlesIn(v2->particles_in_const_end()); +#endif + while( originalPartInIter!=endOfOriginalListOfParticlesIn && + resetPartInIter!=endOfResetListOfParticlesIn ) { + compareGenParticle(*originalPartInIter,*resetPartInIter); + ++resetPartInIter; + ++originalPartInIter; + } + +#ifdef HEPMC3 +std::vector<HepMC::ConstGenParticlePtr>::const_iterator originalPartOutIter(v1->particles_out().begin()); +const std::vector<HepMC::ConstGenParticlePtr>::const_iterator endOfOriginalListOfParticlesOut(v1->particles_out().end()); +std::vector<HepMC::ConstGenParticlePtr>::const_iterator resetPartOutIter(v2->particles_out().begin()); +const std::vector<HepMC::ConstGenParticlePtr>::const_iterator endOfResetListOfParticlesOut(v2->particles_out().end()); +#else +HepMC::GenVertex::particles_out_const_iterator originalPartOutIter(v1->particles_out_const_begin()); +const HepMC::GenVertex::particles_out_const_iterator endOfOriginalListOfParticlesOut(v1->particles_out_const_end()); +HepMC::GenVertex::particles_out_const_iterator resetPartOutIter(v2->particles_out_const_begin()); +const HepMC::GenVertex::particles_out_const_iterator endOfResetListOfParticlesOut(v2->particles_out_const_end()); +#endif + while( originalPartOutIter!=endOfOriginalListOfParticlesOut && + resetPartOutIter!=endOfResetListOfParticlesOut ) { + compareGenParticle(*originalPartOutIter,*resetPartOutIter); + ++resetPartOutIter; + ++originalPartOutIter; + } + + return; +} + + +void compare (const HepMC::GenEvent& e1, + const HepMC::GenEvent& e2) +{ + assert (HepMC::signal_process_id(e1) == HepMC::signal_process_id(e2) ); + assert (e1.event_number() == e2.event_number() ); + + assert (HepMC::valid_beam_particles(&e1) == HepMC::valid_beam_particles(&e2)); + if ( HepMC::valid_beam_particles(&e1) && HepMC::valid_beam_particles(&e2) ) { +#if HEPMC3 + const std::vector<HepMC::ConstGenParticlePtr> & originalBPs = e1.beams(); + const std::vector<HepMC::ConstGenParticlePtr> & resetBPs = e2.beams(); + compareGenParticle(originalBPs.at(0), resetBPs.at(0)); + compareGenParticle(originalBPs.at(1), resetBPs.at(1)); +#else + std::pair<HepMC::GenParticle*,HepMC::GenParticle*> originalBP = e1.beam_particles(); + std::pair<HepMC::GenParticle*,HepMC::GenParticle*> resetBP = e2.beam_particles(); + compareGenParticle(originalBP.first, resetBP.first); + compareGenParticle(originalBP.second, resetBP.second); +#endif + } + +#if HEPMC3 + assert (e1.particles().size() == e2.particles().size()); + assert (e1.vertices().size() == e2.vertices().size()); + + std::vector<HepMC3::ConstGenParticlePtr>::const_iterator origParticleIter(begin(e1)); + const std::vector<HepMC3::ConstGenParticlePtr>::const_iterator endOfOriginalListOfParticles(end(e1)); + std::vector<HepMC3::ConstGenParticlePtr>::const_iterator resetParticleIter(begin(e2)); + const std::vector<HepMC3::ConstGenParticlePtr>::const_iterator endOfResetListOfParticles(end(e2)); + + while( origParticleIter!=endOfOriginalListOfParticles && + resetParticleIter!=endOfResetListOfParticles ) { + compareGenParticle(*origParticleIter,*resetParticleIter); + ++origParticleIter; + ++resetParticleIter; + } + + std::vector<HepMC::ConstGenVertexPtr>::const_iterator origVertexIter(e1.vertices().begin()); + const std::vector<HepMC::ConstGenVertexPtr>::const_iterator endOfOriginalListOfVertices(e1.vertices().end()); + std::vector<HepMC::ConstGenVertexPtr>::const_iterator resetVertexIter(e2.vertices().begin()); + const std::vector<HepMC::ConstGenVertexPtr>::const_iterator endOfResetListOfVertices(e2.vertices().end()); + while( origVertexIter!=endOfOriginalListOfVertices && + resetVertexIter!=endOfResetListOfVertices ) { + compareGenVertex(*origVertexIter,*resetVertexIter); + ++origVertexIter; + ++resetVertexIter; + } +#else + assert (e1.particles_size() == e2.particles_size()); + assert (e1.vertices_size() == e2.vertices_size()); + + HepMC::GenEvent::particle_const_iterator origParticleIter(begin(e1)); + const HepMC::GenEvent::particle_const_iterator endOfOriginalListOfParticles(end(e1)); + HepMC::GenEvent::particle_const_iterator resetParticleIter(begin(e2)); + const HepMC::GenEvent::particle_const_iterator endOfResetListOfParticles(end(e2)); + + while( origParticleIter!=endOfOriginalListOfParticles && + resetParticleIter!=endOfResetListOfParticles ) { + compareGenParticle(*origParticleIter,*resetParticleIter); + ++origParticleIter; + ++resetParticleIter; + } + + HepMC::GenEvent::vertex_const_iterator origVertexIter(e1.vertices_begin()); + const HepMC::GenEvent::vertex_const_iterator endOfOriginalListOfVertices(e1.vertices_end()); + HepMC::GenEvent::vertex_const_iterator resetVertexIter(e2.vertices_begin()); + const HepMC::GenEvent::vertex_const_iterator endOfResetListOfVertices(e2.vertices_end()); + while( origVertexIter!=endOfOriginalListOfVertices && + resetVertexIter!=endOfResetListOfVertices ) { + compareGenVertex(*origVertexIter,*resetVertexIter); + ++origVertexIter; + ++resetVertexIter; + } + return; +#endif +} + +void compare (const McEventCollection& p1, + const McEventCollection& p2) +{ + assert (p1.size() == p2.size()); + for (size_t i = 0; i < p1.size(); i++) { + compare (*(p1.at(i)), *(p2.at(i))); + } +} + +void populateGenEvent(HepMC::GenEvent & ge) +{ + HepMC::FourVector myPos( 0.0345682751, 0.00872347682, 0.23671987, 0.0 ); + HepMC::GenVertexPtr myVertex = HepMC::newGenVertexPtr( myPos, -1 ); + HepMC::FourVector fourMomentum1( 0.0, 0.0, 1.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle1 = HepMC::newGenParticlePtr(fourMomentum1, 2, 10); + myVertex->add_particle_in(inParticle1); + HepMC::FourVector fourMomentum2( 0.0, 0.0, -1.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle2 = HepMC::newGenParticlePtr(fourMomentum2, -2, 10); + myVertex->add_particle_in(inParticle2); + HepMC::FourVector fourMomentum3( 0.0, 1.0, 0.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle3 = HepMC::newGenParticlePtr(fourMomentum3, 2, 10); + myVertex->add_particle_out(inParticle3); + HepMC::FourVector fourMomentum4( 0.0, -1.0, 0.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle4 = HepMC::newGenParticlePtr(fourMomentum4, -2, 10); + myVertex->add_particle_out(inParticle4); + ge.add_vertex( myVertex ); + HepMC::set_signal_process_vertex(&ge, myVertex ); + ge.set_beam_particles(inParticle1,inParticle2); +} + +void populateGenEvent2(HepMC::GenEvent & ge) +{ + HepMC::FourVector myPos(0.0054625871, 0.08027374862, 0.32769178, 0.0); + HepMC::GenVertexPtr myVertex = HepMC::newGenVertexPtr( myPos, -1 ); + HepMC::FourVector fourMomentum1( 0.0, 0.0, 1.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle1 = HepMC::newGenParticlePtr(fourMomentum1, 2, 10); + myVertex->add_particle_in(inParticle1); + HepMC::FourVector fourMomentum2( 0.0, 0.0, -1.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle2 = HepMC::newGenParticlePtr(fourMomentum2, -2, 10); + myVertex->add_particle_in(inParticle2); + HepMC::FourVector fourMomentum3( 0.0, 1.0, 0.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle3 = HepMC::newGenParticlePtr(fourMomentum3, 2, 10); + myVertex->add_particle_out(inParticle3); + HepMC::FourVector fourMomentum4( 0.0, -1.0, 0.0, 1.0*CLHEP::TeV); + HepMC::GenParticlePtr inParticle4 = HepMC::newGenParticlePtr(fourMomentum4, -2, 10); + myVertex->add_particle_out(inParticle4); + ge.add_vertex( myVertex ); + HepMC::set_signal_process_vertex(&ge, myVertex ); + ge.set_beam_particles(inParticle1,inParticle2); +} + +void testit (const McEventCollection& trans1) +{ + MsgStream log (0, "test"); + McEventCollectionCnv_p6 cnv; + McEventCollection_p6 pers; + cnv.transToPers (&trans1, &pers, log); + McEventCollection trans2; + cnv.persToTrans (&pers, &trans2, log); +#if HEPMC3 + compare (trans1, trans2); +#else + // TP conversion of HepMC2::GenEvents has a feature where the order + // of GenParticles associated with each GenVertex is flipped, so + // agreement is only restored after running TP conversion twice... + McEventCollection_p6 pers2; + cnv.transToPers (&trans2, &pers2, log); + McEventCollection trans3; + cnv.persToTrans (&pers2, &trans3, log); + + compare (trans1, trans3); +#endif +} + +void test1() +{ + std::cout << "test1\n"; + +#ifdef HEPMC3 + auto runInfo = std::make_shared<HepMC3::GenRunInfo>(); + runInfo->set_weight_names ({"weight1"}); +#endif + + McEventCollection trans1; + // Add a dummy GenEvent + const int process_id1(20); + const int event_number1(17); + trans1.push_back(HepMC::newGenEvent(process_id1, event_number1)); +#ifdef HEPMC3 + trans1.back()->set_run_info (runInfo); +#endif + HepMC::GenEvent& ge1 = *(trans1.at(0)); + populateGenEvent(ge1); + // Add a second dummy GenEvent + const int process_id2(20); + const int event_number2(25); + trans1.push_back(HepMC::newGenEvent(process_id2, event_number2)); +#ifdef HEPMC3 + trans1.back()->set_run_info (runInfo); +#endif + HepMC::GenEvent& ge2 = *(trans1.at(1)); + populateGenEvent2(ge2); + + testit (trans1); +} + + +int main() +{ + setlinebuf(stdout); + setlinebuf(stderr); + + std::cout << "GeneratorObjectsTPCnv/McEventCollectionCnv_p6_test\n"; + ISvcLocator* pSvcLoc; + if (!Athena_test::initGaudi("GeneratorObjectsTPCnv/GeneratorObjectsTPCnv_test.txt", pSvcLoc)) { + std::cerr << "This test can not be run" << std::endl; + return 0; + } + + test1(); + return 0; +}