Skip to content
Snippets Groups Projects
Commit 28408b4b authored by John Kenneth Anders's avatar John Kenneth Anders
Browse files

Merge branch 'pileup-hash' into '21.0'

Create pile-up events hash and store it in xAOD::EventInfo (ATLASSIM-3795)

See merge request atlas/athena!20788
parents f06c1485 d9d019e5
No related branches found
No related tags found
No related merge requests found
......@@ -19,6 +19,7 @@ atlas_depends_on_subdirs( PRIVATE
# External dependencies:
find_package( Boost COMPONENTS filesystem thread system )
find_package( CLHEP )
find_package( GTest )
# Component(s) in the package:
atlas_add_component( PileUpComps
......@@ -27,3 +28,7 @@ atlas_add_component( PileUpComps
INCLUDE_DIRS ${Boost_INCLUDE_DIRS} ${CLHEP_INCLUDE_DIRS}
LINK_LIBRARIES ${Boost_LIBRARIES} ${CLHEP_LIBRARIES} AthenaBaseComps AthenaKernel PileUpToolsLib StoreGateLib SGtests EventInfo xAODCnvInterfaces xAODEventInfo GaudiKernel )
atlas_add_test( PileUpHashHelper_test
SOURCES src/PileUpHashHelper.cxx test/PileUpHashHelper_test.cxx
INCLUDE_DIRS src ${GTEST_INCLUDE_DIRS}
LINK_LIBRARIES xAODEventInfo ${GTEST_LIBRARIES} )
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
// Class header
#include "PileUpEventLoopMgr.h"
// Helper header
#include "PileUpHashHelper.h"
// Athena includes
#include "AthenaBaseComps/AthMsgStreamMacros.h"
......@@ -584,6 +586,39 @@ StatusCode PileUpEventLoopMgr::nextEvent(int maxevt)
CHECK( m_evtStore->record( std::move( puei ), "PileUpEventInfo" ) );
//ATH_MSG_INFO("Dumping xAOD::EventInfo after adding SubEvents");
//xAOD::dump( *pLocalXAODEventInfo );
// Calculate/copy pile-up hash
xAOD::EventInfo::PileUpMixtureID pileUpMixtureID;
if (m_isEventOverlayJob && m_isEventOverlayJobMC) {
// Just copy over the background PileUpMixtureID
const xAOD::EventInfo *bkgEventInfo = nullptr;
if (!m_origStream.store().retrieve(bkgEventInfo).isSuccess()) {
ATH_MSG_WARNING ("Can not retrieve background xAOD::EventInfo from StoreGate " << m_origStream.store().name() );
} else {
pileUpMixtureID = bkgEventInfo->pileUpMixtureID();
if ( pileUpMixtureID.lowBits != 0 || pileUpMixtureID.highBits != 0 ) {
pLocalXAODEventInfo->setPileUpMixtureID( bkgEventInfo->pileUpMixtureID() );
}
}
} else {
PileUpHashHelper pileUpHashHelper;
if (m_isEventOverlayJob) {
pileUpHashHelper.addToHashSource(std::to_string(pEvent->event_ID()->event_number()));
} else {
pileUpHashHelper.addToHashSource(pLocalXAODEventInfo);
}
ATH_MSG_VERBOSE("Pile-up hash source:" << pileUpHashHelper.hashSource());
// Calculate and set hash
uuid_t pileUpHash;
pileUpHashHelper.calculateHash(pileUpHash);
pLocalXAODEventInfo->setPileUpMixtureID( PileUpHashHelper::uuidToPileUpMixtureId(pileUpHash) );
}
ATH_MSG_DEBUG("PileUpMixtureID = " << pLocalXAODEventInfo->pileUpMixtureID());
//////////// END OF TEMPORARY HACK /////////////////////
......
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
/// @author Tadej Novak
#include <CxxUtils/MD5.h>
#include "PileUpHashHelper.h"
void PileUpHashHelper::addToHashSource(const std::string &string)
{
m_stream << string;
}
void PileUpHashHelper::addToHashSource(const xAOD::EventInfo *eventInfo)
{
const std::vector<xAOD::EventInfo::SubEvent> &subEventsSource = eventInfo->subEvents();
std::vector<std::reference_wrapper<const xAOD::EventInfo::SubEvent>> subEvents(subEventsSource.begin(), subEventsSource.end());
std::stable_sort(subEvents.begin(), subEvents.end(), [](const xAOD::EventInfo::SubEvent &a, const xAOD::EventInfo::SubEvent &b) {
return (a.ptr()->bcid() < b.ptr()->bcid()) ||
((a.ptr()->bcid() == b.ptr()->bcid()) && (a.type() < b.type())) ||
((a.ptr()->bcid() == b.ptr()->bcid()) && (a.type() == b.type()) && (a.ptr()->eventNumber() < b.ptr()->eventNumber()));
});
// Generate subevents info string
bool first = true;
for (const xAOD::EventInfo::SubEvent &subevent : subEvents) {
if (subevent.type() == xAOD::EventInfo::Signal) {
continue;
}
if (first) {
first = false;
} else {
m_stream << ";";
}
m_stream << (static_cast<int32_t>(subevent.ptr()->bcid()) - static_cast<int32_t>(eventInfo->bcid())) << "_" << subevent.type() << "_" << subevent.ptr()->eventNumber();
}
}
void PileUpHashHelper::clearHashSource()
{
m_stream.str(std::string());
}
void PileUpHashHelper::calculateHash(uuid_t &hash) const
{
std::string sourceStr = m_stream.str();
std::vector<unsigned char> source(sourceStr.data(), sourceStr.data() + sourceStr.length() + 1);
MD5 md5Hash(&source[0], source.size());
md5Hash.raw_digest(hash);
}
xAOD::EventInfo::PileUpMixtureID PileUpHashHelper::uuidToPileUpMixtureId(const uuid_t &hash)
{
xAOD::EventInfo::PileUpMixtureID mixture{};
for (uint16_t i = 0; i < PILEUP_SIZE_BYTES; i++) {
mixture.lowBits |= (static_cast<unsigned long long>(hash[i]) << (i * sizeof(unsigned char) * CHAR_BIT));
mixture.highBits |= (static_cast<unsigned long long>(hash[i + PILEUP_SIZE_BYTES]) << (i * sizeof(unsigned char) * CHAR_BIT));
}
return mixture;
}
void PileUpHashHelper::pileUpMixtureIdToUuid(const xAOD::EventInfo::PileUpMixtureID &mixture,
uuid_t &hash)
{
for (uint16_t i = 0; i < PILEUP_SIZE_BYTES; i++) {
hash[i] |= (mixture.lowBits >> (i * sizeof(unsigned char) * CHAR_BIT));
hash[i + PILEUP_SIZE_BYTES] |= (mixture.highBits >> (i * sizeof(unsigned char) * CHAR_BIT));
}
}
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
#ifndef PILEUPCOMPS_PILEUPHASHHELPER_H
#define PILEUPCOMPS_PILEUPHASHHELPER_H
/**
@file PileUpHashHelper.h
@brief A helper class to compute a hash of pile-up events
@author Tadej Novak
*/
#include <sstream>
#include <uuid/uuid.h>
#include <xAODEventInfo/EventInfo.h>
class PileUpHashHelper
{
public:
PileUpHashHelper() {}
/// Add a plain string to the stream
void addToHashSource(const std::string &string);
/// Add subevents to the stream
void addToHashSource(const xAOD::EventInfo *eventInfo);
/// Clear the stream
void clearHashSource();
/// Get the current hash base
std::string hashSource() const { return m_stream.str(); }
/// Calculate the hash
void calculateHash(uuid_t &hash) const;
/// Convert uuid_t to xAOD::EventInfo::PileUpMixtureID
static xAOD::EventInfo::PileUpMixtureID uuidToPileUpMixtureId(const uuid_t &hash);
/// xAOD::EventInfo::PileUpMixtureID to uuid_t
static void pileUpMixtureIdToUuid(const xAOD::EventInfo::PileUpMixtureID &mixture,
uuid_t &hash);
/// Size of individual low/high bits in bytes
static const uint16_t PILEUP_SIZE_BYTES = 8;
private:
std::stringstream m_stream;
};
#endif // PILEUPCOMPS_PILEUPHASHHELPER_H
/*
Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
*/
/// @author Tadej Novak
// Google Test
#include <gtest/gtest.h>
// The class to test
#include "PileUpHashHelper.h"
namespace PileUpTesting
{
class PileUpHashHelper_test : public ::testing::Test {};
TEST_F(PileUpHashHelper_test, empty_mixture) {
unsigned long long reference = 0;
xAOD::EventInfo::PileUpMixtureID test{};
ASSERT_EQ(reference, test.lowBits);
ASSERT_EQ(reference, test.highBits);
}
TEST_F(PileUpHashHelper_test, uuid_to_long) {
uuid_t source{'a','a','a','a','a','a','a','b','1','0','0','0','0','0','0','0'};
xAOD::EventInfo::PileUpMixtureID reference;
reference.lowBits = 7089054359331365217;
reference.highBits = 3472328296227680305;
xAOD::EventInfo::PileUpMixtureID test = PileUpHashHelper::uuidToPileUpMixtureId(source);
ASSERT_EQ(reference, test);
ASSERT_EQ(reference.lowBits, test.lowBits);
ASSERT_EQ(reference.highBits, test.highBits);
}
TEST_F(PileUpHashHelper_test, long_to_uuid) {
uuid_t reference{'a','a','a','a','a','a','a','b','1','0','0','0','0','0','0','0'};
uuid_t test{};
xAOD::EventInfo::PileUpMixtureID source;
source.lowBits = 7089054359331365217;
source.highBits = 3472328296227680305;
PileUpHashHelper::pileUpMixtureIdToUuid(source, test);
ASSERT_EQ(uuid_compare(reference, test), 0);
}
} // namespace PileUpTesting
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
......@@ -44,6 +44,10 @@ namespace xAOD {
AUX_VARIABLE( mcChannelNumber );
AUX_VARIABLE( mcEventNumber );
AUX_VARIABLE( mcEventWeights );
// Pileup information:
AUX_VARIABLE( pileUpMixtureIDLowBits );
AUX_VARIABLE( pileUpMixtureIDHighBits );
}
} // namespace xAOD
......@@ -346,6 +346,37 @@ namespace xAOD {
AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( EventInfo_v1, float,
averageInteractionsPerCrossing,
setAverageInteractionsPerCrossing )
AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( EventInfo_v1, unsigned long long,
pileUpMixtureIDLowBits,
setPileUpMixtureIDLowBits )
AUXSTORE_PRIMITIVE_SETTER_AND_GETTER( EventInfo_v1, unsigned long long,
pileUpMixtureIDHighBits,
setPileUpMixtureIDHighBits )
EventInfo_v1::PileUpMixtureID EventInfo_v1::pileUpMixtureID() const {
static Accessor< unsigned long long > accLow( "pileUpMixtureIDLowBits" );
static Accessor< unsigned long long > accHigh( "pileUpMixtureIDHighBits" );
PileUpMixtureID id{};
// We need to check if the values are actually stored
if ( accLow.isAvailable( *this ) && accHigh.isAvailable( *this ) ) {
id.lowBits = pileUpMixtureIDLowBits();
id.highBits = pileUpMixtureIDHighBits();
}
return id;
}
void EventInfo_v1::setPileUpMixtureID( const PileUpMixtureID& value ) {
setPileUpMixtureIDLowBits( value.lowBits );
setPileUpMixtureIDHighBits( value.highBits );
}
EventInfo_v1::SubEvent::
SubEvent( int16_t time, uint16_t index, PileUpType type,
......@@ -832,4 +863,48 @@ namespace xAOD {
return out;
}
/// This operator is provided to make it convenient to print debug messages
/// including information about the PileUpMixtureID in hex.
///
/// @param out The output stream to write PileUpMixtureID information to
/// @param id The PileUpMixtureID object to print information about
/// @returns The same output stream that the operator received
///
std::ostream& operator<<( std::ostream &out,
const xAOD::EventInfo_v1::PileUpMixtureID& id ) {
// Get the current state of the stream:
const char fillChar = out.fill();
const std::ios_base::fmtflags flags = out.flags();
const std::streamsize width = out.width();
// Do the printout:
out << std::hex << std::setw( 16 ) << std::setfill( '0' );
out << id.lowBits;
out << id.highBits;
// Restore the original state of the stream:
out.fill( fillChar );
out.flags( flags );
out.width( width );
// Return the stream:
return out;
}
/// This operator is provided to make it convenient to compare two
/// instances of PileUpMixtureID directly.
///
/// @param a The PileUpMixtureID object to compare
/// @param b The PileUpMixtureID object to compare
/// @returns Comparison result
///
bool operator== ( const xAOD::EventInfo_v1::PileUpMixtureID& a,
const xAOD::EventInfo_v1::PileUpMixtureID& b ) {
return a.lowBits == b.lowBits && a.highBits == b.highBits;
}
} // namespace xAOD
......@@ -79,6 +79,12 @@ namespace xAOD {
std::vector< std::vector< float > > mcEventWeights;
/// @}
/// @name Pileup information
/// @{
std::vector< unsigned long long > pileUpMixtureIDLowBits;
std::vector< unsigned long long > pileUpMixtureIDHighBits;
/// @}
}; // class EventInfoAuxContainer_v1
} // namespace xAOD
......
......@@ -243,6 +243,27 @@ namespace xAOD {
/// Set average interactions per crossing for all BCIDs
void setAverageInteractionsPerCrossing( float value );
/// Unique pile-up mixture identifier definition
struct PileUpMixtureID {
unsigned long long lowBits{};
unsigned long long highBits{};
};
/// Unique pile-up mixture identifier
PileUpMixtureID pileUpMixtureID() const;
/// Set unique pile-up mixture identifier
void setPileUpMixtureID( const PileUpMixtureID &value );
/// Unique pile-up mixture identifier low bits
unsigned long long pileUpMixtureIDLowBits() const;
/// Set unique pile-up mixture identifier low bits
void setPileUpMixtureIDLowBits( unsigned long long value );
/// Unique pile-up mixture identifier high bits
unsigned long long pileUpMixtureIDHighBits() const;
/// Set unique pile-up mixture identifier high bits
void setPileUpMixtureIDHighBits( unsigned long long value );
/// Enumerator describing the types of pileup events
enum PileUpType {
Unknown = 99, ///< Type not known/specified
......@@ -458,8 +479,11 @@ namespace xAOD {
}; // class EventInfo_v1
/// A helper operator to be able to print debug messages easily
/// A helper operators to be able to print debug messages easily
std::ostream& operator<< ( std::ostream& out, const xAOD::EventInfo_v1& ei );
std::ostream& operator<< ( std::ostream& out, const xAOD::EventInfo_v1::PileUpMixtureID& id );
/// PileUpMixtureID comparison helper operator
bool operator== ( const xAOD::EventInfo_v1::PileUpMixtureID& a, const xAOD::EventInfo_v1::PileUpMixtureID& b );
} // namespace xAOD
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment