Skip to content
Snippets Groups Projects
Commit 440431b8 authored by Marcin Nowak's avatar Marcin Nowak :radioactive:
Browse files

Remove unused PileUp Bkg stream types

parent 8068fe7d
No related branches found
No related tags found
9 merge requests!58791DataQualityConfigurations: Modify L1Calo config for web display,!46784MuonCondInterface: Enable thread-safety checking.,!46776Updated LArMonitoring config file for WD to match new files produced using MT,!45405updated ART test cron job,!42417Draft: DIRE and VINCIA Base Fragments for Pythia 8.3,!28528Revert 63f845ae,!27054Atr20369 210,!26342Monopole: Handle fractionally charged particles,!20008migrate PileUpEventInfo to xAOD::EvenInfo
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
/*#define DEBUG_PILEUP 1*/
#include <cassert>
#include <cmath> /*ceil,sqrt*/
#include <functional> /* mem_fun_ref*/
#include <stdexcept> /*runtime_error*/
#include <string>
#include <vector>
#include <boost/bind.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>
#include "AthenaKernel/IAtRndmGenSvc.h"
#include "GaudiKernel/GaudiException.h"
#include "StoreGate/ActiveStoreSvc.h"
#include "StoreGate/StoreGateSvc.h" /*to print name() */
#include "GaudiKernel/IEvtSelector.h"
#include "CLHEP/Random/RandFlat.h"
#include "CLHEP/Random/RandPoisson.h"
#include "EventInfo/PileUpTimeEventIndex.h"
#include "xAODEventInfo/EventInfoContainer.h"
#include "AthenaBaseComps/AthMsgStreamMacros.h"
#include "BkgStreamsConcentricCache.h"
using namespace std;
BkgStreamsConcentricCache::BkgStreamsConcentricCache( const std::string& type,
const std::string& name,
const IInterface* parent) :
base_class( type, name, parent ),
p_activeStore(0),
m_cursor(),
m_streams(),
m_nXings(0),
m_nStores(0),
m_rings(),
m_collXing(23.0),
m_occupationFraction(1.0),
m_collDistrName("Poisson"),
m_selecName("FakeEventSelector", name),
m_readDownscale(150),
m_atRndmSvc("AtRndmGenSvc", name),
m_randomStreamName("PileUpCollXingStream"),
m_pileUpEventTypeProp(0),
m_pileUpEventType(xAOD::EventInfo::PileUpType::Signal),
m_ringsProp(),
m_allowRingMigProp(false),
m_readEventRand(0),
m_chooseEventRand(0),
m_collXingPoisson(0),
m_f_collDistr(0),
m_collXingSF(1.0),
m_ignoreSF(false)
{
declareProperty("CollPerXing", m_collXing, "(average) number of collisions per beam crossing");
declareProperty("OccupationFraction", m_occupationFraction, "The maximum fraction of bunch-crossings which will be occupied.");
declareProperty("CollDistribution", m_collDistrName, "nEvts/Xings can be either Fixed at CollPerXing or Poisson with average CollPerXing");
declareProperty("EventSelector", m_selecName);
declareProperty("ReadDownscaleFactor", m_readDownscale, "read one event every downscaleFactor accesses (asymptotically -> number of times an event in the cache will be reused)");
declareProperty("RndmGenSvc", m_atRndmSvc, "IAtRndmGenSvc controlling the distribution of bkg events/xing");
declareProperty("RndmStreamName", m_randomStreamName, "IAtRndmGenSvc stream used as engine for our various random distributions, including the CollPerXing one ");
declareProperty("PileUpEventType", m_pileUpEventTypeProp, "Type of the pileup events in this cache: 0:Signal, 1:MinimumBias, 2:Cavern, 3:HaloGas, 4:ZeroBias");
m_pileUpEventTypeProp.verifier().setUpper((xAOD::EventInfo::PileUpType)PileUpTimeEventIndex::NTYPES-2);
m_pileUpEventTypeProp.declareUpdateHandler(&BkgStreamsConcentricCache::PileUpEventTypeHandler, this);
declareProperty("NonIntersectingRings", m_ringsProp,
"Array of rings specified in the form lowXing:hiXing. Rings must not intersect (e.g. -7:7, -3:0, -1:0) or an exception will be thrown");
m_ringsProp.declareUpdateHandler(&BkgStreamsConcentricCache::RingsPropHandler, this);
//add default (huge) ring to make cache work if NonIntersectingRings never set
m_rings.push_back(Ring());
declareProperty("AllowRingMigration", m_allowRingMigProp, "Allow events in inner rings to be used in outer rings. When false every ring is effectively a separate cache");
declareProperty("IgnoreBeamLumi", m_ignoreSF, "Default=False, set to True to ignore the PileUpEventLoopMgr beam luminosity tool in setting the number of events per xing.");
}
BkgStreamsConcentricCache::~BkgStreamsConcentricCache() {
delete m_collXingPoisson;
delete m_chooseEventRand;
delete m_readEventRand;
}
void
BkgStreamsConcentricCache::PileUpEventTypeHandler(Property&) {
m_pileUpEventType=(xAOD::EventInfo::PileUpType)PileUpTimeEventIndex::ushortToType(m_pileUpEventTypeProp.value());
}
void
BkgStreamsConcentricCache::RingsPropHandler(Property&) {
const vector<string>& rRings = m_ringsProp.value();
if (!rRings.empty()) {
vector<string>::const_iterator iSR(rRings.begin()), eSR(rRings.end());
while (iSR!=eSR) m_rings.push_back(Ring(*iSR++));
//this will throw an exception if the rings are intersecting
sort(m_rings.begin(), m_rings.end());
}
}
StatusCode
BkgStreamsConcentricCache::setup(int firstXing,
unsigned int nXings,
unsigned int firstStore,
IBeamIntensity*)
{
assert (0 < nXings);
m_nXings = nXings;
//readjust all rings so that they count from 0 as the code expects
vector<Ring>::iterator iR(m_rings.begin()), eR(m_rings.end());
while (iR!=eR) (iR++)->adjust(-firstXing);
//ceil (cmath) rounds up to the nearest integer ceil(1.5)= 2
float occupiedCrossings = ceil(static_cast<float>(m_nXings) * m_occupationFraction);
m_nStores = static_cast<unsigned int>(ceil( m_collXing * occupiedCrossings ));
if (m_collDistrName.value() == "Poisson") {
//allow for fluctuations in # of overlaid events
//allow for one sided migration among rings
//FIXME just a guess this needs to be optimized
m_nStores += ( m_allowRingMigProp.value() ?
static_cast<unsigned int>(6.0 * m_rings.size() * sqrt(static_cast<float>(m_nStores))) :
static_cast<unsigned int>(6.0 * sqrt(static_cast<float>(m_nStores))));
}
if (m_allowRingMigProp.value() && m_collDistrName.value() == "Fixed") {
//allow for one sided migration among rings
//FIXME just a guess this needs to be optimized
m_nStores += static_cast<unsigned int>(m_rings.size() * sqrt(static_cast<float>(m_nStores)));
}
//get bkg selectors, stores and iterators
m_nEvtsXing.reserve(m_nStores);
m_streams.reserve(m_nStores);
const std::string& selecName(m_selecName.name());
for (unsigned int i=0; i < m_nStores; ++i) {
std::stringstream bufName;
bufName << "BkgEvent_" << i + firstStore;
const std::string& streamName(bufName.str());
try {
m_streams.push_back(PileUpStream(streamName,serviceLocator(),selecName));
} catch (const std::runtime_error& e) {
ATH_MSG_ERROR ( "Exception thrown while creating PileUpStream "
<< streamName << " : " << e.what() );
return StatusCode::FAILURE;
}
if(!(m_streams.back().setupStore())) {
ATH_MSG_ERROR ( "Can not setup bkg evt store for stream "
<< streamName );
return StatusCode::FAILURE;
}
}
m_cursor = m_streams.begin();
CLHEP::HepRandomEngine* collEng(m_atRndmSvc->GetEngine(m_randomStreamName.value()));
if(0 == collEng ) {
ATH_MSG_ERROR ( "can not get random stream " << m_randomStreamName.value() );
return StatusCode::FAILURE;
}
//setup generator to pickup an event store at random from the cache
//notice how we pass collEng by reference. If ! CLHEP will take ownership...
m_chooseEventRand = new CLHEP::RandFlat(*(collEng),
0.0, double(m_nStores));
return StatusCode::SUCCESS;
}
void BkgStreamsConcentricCache::resetEvtsPerXingScaleFactor(float sf) {
if (!m_ignoreSF) m_collXingSF = sf;
}
long BkgStreamsConcentricCache::collXingPoisson(){
if (!m_collXingPoisson) return collXing();
return m_collXingPoisson->fire(m_collXing * m_collXingSF);
}
void BkgStreamsConcentricCache::newEvent() {
ATH_MSG_DEBUG ( "newEvent called resetting used event set" );
unsigned int totEvts(0);
do {
totEvts = 0;
for (unsigned int iXing=0; iXing<m_nXings; ++iXing) {
totEvts += setNEvtsXing(iXing);
if (totEvts > m_nStores) {
ATH_MSG_WARNING ( "newEvent: number of required evts exceeds number of available stores "
<< m_nStores << ". Regenerating bkg sequence for this event \n"
<< " the total number of bkg events may not exceed average by more than 6 sigmas"
);
break;
}
}
} while(totEvts > m_nStores);
for_each(m_streams.begin(), m_streams.end(),
mem_fun_ref(&PileUpStream::resetUsed));
}
const xAOD::EventInfo* BkgStreamsConcentricCache::nextEvent(unsigned int iXing) {
const xAOD::EventInfo* pNextEvt(0);
//find the first ring containing iXing
unsigned int iRing(0);
while (iRing<m_rings.size() && (!m_rings[iRing++].contains(iXing))) { }
--iRing;
#ifdef DEBUG_PILEUP
cout <<"nextEvent " << iXing << ' ' << iRing << ' ' << m_rings.size() << endl;
#endif
if (iRing<m_rings.size()) {
StreamVector::size_type iS(0);
unsigned int attempts(100*m_nStores);
do {
iS = (StreamVector::size_type)m_chooseEventRand->fire();
} while ((--attempts != 0) && !this->canUse(iS,iRing));
if (0 == attempts)
throw GaudiException("BkgStreamsConcentricCache::nextEvent: can not find a suitable stream",
name(),
StatusCode::FAILURE);
//set current store to iS
m_cursor = m_streams.begin();
std::advance(m_cursor, iS);
ATH_MSG_DEBUG ( "using stream/store " << iS );
PileUpStream* pCurrStream(current());
if (0 != pCurrStream) {
p_activeStore->setStore(&(pCurrStream->store()));
//read a new event every downscaleFactor accesses
bool readEvent(m_readEventRand->fire()<1.0);
pNextEvt=pCurrStream->nextEventPre(readEvent);
}
} //ring found
return pNextEvt;
}
StatusCode BkgStreamsConcentricCache::nextEvent_passive(unsigned int iXing) {
//find the first ring containing iXing
unsigned int iRing(0);
while (iRing<m_rings.size() && (!m_rings[iRing++].contains(iXing))) { }
--iRing;
#ifdef DEBUG_PILEUP
cout <<"nextEvent " << iXing << ' ' << iRing << ' ' << m_rings.size() << endl;
#endif
if (iRing<m_rings.size()) {
StreamVector::size_type iS(0);
unsigned int attempts(100*m_nStores);
do {
iS = (StreamVector::size_type)m_chooseEventRand->fire();
} while ((--attempts != 0) && !this->canUse(iS,iRing));
if (0 == attempts)
throw GaudiException("BkgStreamsConcentricCache::nextEvent: can not find a suitable stream",
name(),
StatusCode::FAILURE);
//set current store to iS
m_cursor = m_streams.begin();
std::advance(m_cursor, iS);
ATH_MSG_DEBUG ( "using stream/store " << iS );
PileUpStream* pCurrStream(current());
if (0 != pCurrStream) {
p_activeStore->setStore(&(pCurrStream->store()));
//read a new event every downscaleFactor accesses
bool readEvent(m_readEventRand->fire()<1.0);
if(pCurrStream->nextEventPre_Passive(readEvent)) return StatusCode::SUCCESS;
}
} //ring found
return StatusCode::FAILURE;
}
bool BkgStreamsConcentricCache::canUse(StreamVector::size_type iS, unsigned currentRing) {
assert(currentRing<m_rings.size());
//can use a stream if belongs to a ring inside the current one
//if the stream has no ring assigned yet we can of course use it
PileUpStream& stream(m_streams[iS]);
bool canUse(!stream.used() &&
( !stream.hasRing() ||
(m_allowRingMigProp.value() ?
currentRing>=stream.originalIRing() :
currentRing==stream.originalIRing()) ) );
#ifndef NDEBUG
ATH_MSG_VERBOSE ( "canUse: stream " << iS
<< (canUse ? " can" : " can not") << " be used in ring " << currentRing
<< "\n Stream " <<(stream.used() ? "already" : "not yet")
<< " used in this event. Stream originally used for ring "
<< stream.originalIRing()
);
#endif
if (canUse) {
stream.setUsed();
stream.setOriginalIRing(currentRing);
#ifdef DEBUG_PILEUP
cout << "canUse: new stream status : used " << stream.used() << " original ring " << stream.originalIRing() << endl;
#endif
}
return canUse;
}
PileUpStream* BkgStreamsConcentricCache::current() {
if (m_cursor != m_streams.end()) return &*m_cursor;
// m_cursor->isNotEmpty()) return &*m_cursor;
else return 0; //FIXME should reomve empty stream and keep going
}
StatusCode BkgStreamsConcentricCache::initialize() {
StatusCode sc(StatusCode::SUCCESS);
ATH_MSG_INFO ( "Initializing " << name()
<< " - cache for events of type "
<< PileUpTimeEventIndex::typeName((PileUpTimeEventIndex::PileUpType)m_pileUpEventType)
<< " - package version " << PACKAGE_VERSION ) ;
PileUpEventTypeHandler(m_pileUpEventTypeProp);
//locate the ActiveStoreSvc and initialize our local ptr
if (!(sc = service("ActiveStoreSvc", p_activeStore)).isSuccess() )
{
ATH_MSG_ERROR ( "Error retrieving ActiveStoreSvc." );
return sc;
}
//create random number generators
if (!(m_atRndmSvc.retrieve()).isSuccess()) {
ATH_MSG_ERROR ( "can not get IAtRndmGenSvc " << m_atRndmSvc );
return StatusCode::FAILURE;
}
CLHEP::HepRandomEngine* collEng(m_atRndmSvc->GetEngine(m_randomStreamName.value()));
if(0 == collEng ) {
ATH_MSG_ERROR ( "can not get random stream " << m_randomStreamName.value() );
return StatusCode::FAILURE;
}
//setup distribution to read a new event every downscaleFactor accesses
//notice how we pass collEng by reference. If ! CLHEP will take ownership...
m_readEventRand = new CLHEP::RandFlat(*(collEng),
0.0, double(m_readDownscale));
// select collision distribution function
if (m_collDistrName.value() == "Fixed")
m_f_collDistr = boost::bind(&BkgStreamsConcentricCache::collXing, this);
else if (m_collDistrName.value() == "Poisson") {
//pass collEng by reference. If Not CLHEP will take ownership...
m_collXingPoisson = new CLHEP::RandPoisson(*(collEng), m_collXing);
// m_f_collDistr will call m_collXingPoisson->fire(m_collXing) USED TO BE boost::bind(&CLHEP::RandPoisson::fire, m_collXingPoisson);
m_f_collDistr = boost::bind(&BkgStreamsConcentricCache::collXingPoisson, this);
} else {
ATH_MSG_ERROR ( m_collDistrName
<< " is not a know collision distribution function" );
sc = StatusCode::FAILURE;
}
return sc;
}
unsigned int BkgStreamsConcentricCache::nEvtsXing(unsigned int iXing) const {
return (iXing + 1 > m_nEvtsXing.size()) ? 0 : m_nEvtsXing[iXing];
}
unsigned int BkgStreamsConcentricCache::setNEvtsXing(unsigned int iXing) {
if (iXing + 1 > m_nEvtsXing.size()) m_nEvtsXing.resize(2 * iXing + 1);
m_nEvtsXing[iXing] = m_f_collDistr();
return m_nEvtsXing[iXing];
}
StatusCode BkgStreamsConcentricCache::addSubEvts(unsigned int iXing,
xAOD::EventInfo* overEvent,
int t0BinCenter) {
return this->addSubEvts(iXing, overEvent, t0BinCenter, true, 0);
}
StatusCode BkgStreamsConcentricCache::addSubEvts(unsigned int iXing,
xAOD::EventInfo* overEvent,
int t0BinCenter, bool loadEventProxies, unsigned int /*BCID*/) {
for (unsigned int iEvt=0; iEvt<nEvtsXing(iXing); ++iEvt) {
StoreGateSvc* pBkgStore(0);
// increment event iterators
if(!loadEventProxies)
{
return this->nextEvent_passive(iXing);
}
const xAOD::EventInfo* pBkgEvent(nextEvent(iXing));
//check input selector is not empty
PileUpStream* currStream(current());
if (0 == pBkgEvent || 0 == currStream) {
// This is the end of the loop. No more events in the selection
ATH_MSG_INFO ( "end of loop: background cache has no more events" );
return StatusCode::FAILURE;
} else {
pBkgStore = &(currStream->store());
ATH_MSG_DEBUG ( "added event " << pBkgEvent->eventNumber()
<< " run " << pBkgEvent->runNumber()
<< " from store "
<< pBkgStore->name()
<< " @ Xing " << iXing );
}
// register as sub event of the overlaid
// ask if sufficient/needed
ATH_MSG_ERROR("NOT IMPLEMENTED!");
// overEvent.addSubEvt(t0BinCenter, m_pileUpEventType, pBkgEvent, pBkgStore);//,BCID); FIXME:Changes needed to PileUpEventInfo to do this.
#ifdef DEBUG_PILEUP
const EventInfo* pStoreInfo(0);
if (pBkgStore->retrieve(pStoreInfo).isSuccess() && pStoreInfo &&
pBkgEvent->event_ID()->event_number() != pStoreInfo->event_ID()->event_number()) {
ATH_MSG_ERROR ( "added event " << pBkgEvent->event_ID()->event_number()
<< " run " << pBkgEvent->event_ID()->run_number()
<< " differ from current store "
<< pBkgStore->name()
<< " event " << pStoreInfo->event_ID()->event_number()
<< " run " << pStoreInfo->event_ID()->run_number()
);
assert(1);
}
#endif
} //loop over evts in xing
return StatusCode::SUCCESS;
}
StatusCode BkgStreamsConcentricCache::finalize() {
StatusCode sc(StatusCode::SUCCESS);
ATH_MSG_INFO ( "Finalizing " << name()
<< " - cache for events of type "
<< PileUpTimeEventIndex::typeName((PileUpTimeEventIndex::PileUpType)m_pileUpEventType)
<< " - package version " << PACKAGE_VERSION ) ;
while (sc.isSuccess() && m_streams.size()>0) {
sc=m_streams.back().finalize();
m_streams.pop_back();
}
return sc;
}
bool
BkgStreamsConcentricCache::Ring::operator <(const BkgStreamsConcentricCache::Ring& rhs) const {
//this is not a typo: we want the rings with higher m_lowXing to be
//less than (inside of) the others
bool lessLHS(this->m_lowXing > rhs.m_lowXing);
//throw if the rings are not concentric
if ((lessLHS && (this->m_hiXing > rhs.m_hiXing)) ||
((m_lowXing < rhs.m_lowXing) && (this->m_hiXing < rhs.m_hiXing))){
cerr << "rings not concentric:\n"
<< "this " << this->m_lowXing << ':' << this->m_hiXing << '\n'
<< "rhs " << rhs.m_lowXing << ':' << rhs.m_hiXing
<< endl;
throw runtime_error("rings not concentric");
}
return lessLHS;
}
BkgStreamsConcentricCache::Ring::Ring(const string& prop) :
m_lowXing(-9999),
m_hiXing(9999)
{
typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
boost::char_separator<char> sep(":");
tokenizer tokens(prop, sep);
bool OK = (distance(tokens.begin(), tokens.end()) == 2);
if (OK) {
tokenizer::iterator token(tokens.begin());
try {
m_lowXing = boost::lexical_cast<long>(*token++);
m_hiXing = boost::lexical_cast<long>(*token);
} catch (const boost::bad_lexical_cast& e) {
OK = false;
}
}
OK = OK && (m_lowXing <= m_hiXing);
if (!OK) {
cerr << "Badly formatted ring property string: " << prop
<< " please use format lowXing:hiXing " << endl;
throw runtime_error("Badly formatted ring property string");
}
}
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef PILEUPTOOLS_BKGSTREAMSCONCENTRICCACHE_H
# define PILEUPTOOLS_BKGSTREAMSCONCENTRICCACHE_H
/** @file BkgStreamsConcentricCache.h
* @brief Optimized in memory cache for pileup events
* This implementation controls how events are reused in the cache
* events that have been used in the "inner rings" of the cache
* can be used in the outer rings, but not viceversa
* The idea is that events in the inner rings will have all data
* objects in them read from disk, while events in the outer rings
* will only need to read hits from one or two detectors (LAr and MDT)
*
* $Id: BkgStreamsConcentricCache.h,v 1.10 2008-08-28 01:11:06 calaf Exp $
* @author Paolo Calafiura - ATLAS Collaboration
*/
#include <string>
#include <vector>
#include <boost/function.hpp>
#include "AthenaBaseComps/AthAlgTool.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/Property.h"
#include "GaudiKernel/VectorMap.h"
#include "PileUpTools/PileUpStream.h"
#include "PileUpTools/IBkgStreamsCache.h"
#include "EventInfo/PileUpTimeEventIndex.h" /* needed for PileUpType */
#include "AthenaKernel/MsgStreamMember.h"
class ActiveStoreSvc;
class IEvtSelector;
class IAtRndmGenSvc;
class IBeamIntensity;
namespace CLHEP {
class RandFlat;
class RandPoisson;
}
/** @class BkgStreamsConcentricCache
* @brief Optimized in-memory cache for pileup events
*/
class BkgStreamsConcentricCache :
public extends<AthAlgTool, IBkgStreamsCache>
{
public:
BkgStreamsConcentricCache( const std::string&, const std::string&, const IInterface*);
virtual ~BkgStreamsConcentricCache();
virtual StatusCode initialize();
virtual StatusCode finalize();
/**
@param nXings bunch Xings to be processed
@param firstStore id of first store in cache
*/
virtual StatusCode setup(int firstXing,
unsigned int nXings,
unsigned int firstStore,
IBeamIntensity*);
/// inform cache that we start overlaying a new event
virtual void newEvent();
/// reset scale factor at new run/lumiblk
virtual void resetEvtsPerXingScaleFactor(float sf);
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overlaidEvent,
int t0BinCenter);
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
@param BCID bunch-crossing ID of signal bunch crossing
@param loadEventProxies should we load the event proxies or not.
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overEvent,
int t0BinCenter, bool loadEventProxies, unsigned int /*BCID*/);
/// how many stores in cache
virtual unsigned int nStores() const { return m_nStores; }
/// meant to be used (mainly) via m_f_collDistr
long collXing() { return m_collXing * m_collXingSF; }
long collXingPoisson();
/** @class BkgStreamsConcentricCache::Ring
* @brief A closed range in beam xings. Events initially used for a Ring
* can be reused for an outer Ring but not for an inner Ring.
*/
class Ring {
public:
///takes a string of the form "lowXing:hiXing". @throws if bad format
Ring(const std::string&);
/// args are xing indices, not times in ns, 0 being the index of the t0
Ring(int lowXing=-9999, int hiXing=9999) :
m_lowXing(lowXing), m_hiXing(hiXing) {}
Ring(const Ring& rhs) :
m_lowXing(rhs.m_lowXing), m_hiXing(rhs.m_hiXing) {}
/// does this ring contain iXing
bool contains(int iXing) {
#ifdef DEBUG_PILEUP
std::cout << "contains: " << m_lowXing << ' ' << iXing << ' ' << m_hiXing << std::endl;
#endif
return (m_lowXing <= iXing) && (iXing <= m_hiXing) ;
}
///@throws if rings are not concentric
bool operator <(const Ring& rhs) const;
Ring& operator =(const Ring& rhs)
{
if (this == &rhs) {return *this;} // Handle self assignment
m_lowXing = rhs.m_lowXing;
m_hiXing = rhs.m_hiXing;
return *this;
}
int lowXing() const { return m_lowXing; }
int hiXing() const { return m_hiXing; }
void adjust(int offset) {
m_lowXing += offset;
m_hiXing += offset;
}
private:
int m_lowXing;
int m_hiXing;
};
private:
/// get next bkg event for xing iXing from cache
const xAOD::EventInfo* nextEvent(unsigned int iXing);
/// as nextEvent except don't actually load anything
StatusCode nextEvent_passive(unsigned int iXing);
/// get current (last selected) stream
PileUpStream* current();
unsigned int setNEvtsXing(unsigned int iXing);
unsigned int nEvtsXing(unsigned int iXing) const;
typedef std::vector<PileUpStream> StreamVector;
bool canUse(StreamVector::size_type iS, unsigned currentRing);
ActiveStoreSvc* p_activeStore;
StreamVector::iterator m_cursor;
StreamVector m_streams;
unsigned int m_nXings;
unsigned int m_nStores;
std::vector<unsigned int> m_nEvtsXing;
/// these rings will be sorted in the property callback
std::vector<Ring> m_rings;
/// @name Properties
//@{
/// # of collisions/xings (~beam intensity)
Gaudi::Property<float> m_collXing;
/// The maximum fraction of bunch-crossings which will be occupied.
Gaudi::Property<float> m_occupationFraction;
/// select collision distribution
Gaudi::Property<std::string> m_collDistrName;
ServiceHandle<IEvtSelector> m_selecName;
/// read downscale factor (average number of times a min bias is reused)
Gaudi::Property<float> m_readDownscale;
/// IAtRndmGenSvc controlling the distribution of bkg events/xing
ServiceHandle<IAtRndmGenSvc> m_atRndmSvc;
/// the IAtRndmGenSvc stream to generate number of collisions/xing
Gaudi::Property<std::string> m_randomStreamName;
/// the type of events in this cache
Gaudi::CheckedProperty<unsigned short> m_pileUpEventTypeProp;
void PileUpEventTypeHandler(Property&);
/// the type of events in this cache
xAOD::EventInfo::PileUpType m_pileUpEventType;
void RingsPropHandler(Property&);
/// the list of rings to be used in the form "lowXing:hiXing"
Gaudi::Property<std::vector<std::string>> m_ringsProp;
/// Allow events in inner rings to be used in outer rings.
/// When false every ring is effectively a separate cache
Gaudi::Property<bool> m_allowRingMigProp;
//@}
/// read a new event every downscaleFactor accesses
CLHEP::RandFlat* m_readEventRand;
/// pickup an event store at random from the cache
CLHEP::RandFlat* m_chooseEventRand;
/// set number of collisions/xing (if Poisson distribution chosen)
CLHEP::RandPoisson* m_collXingPoisson;
/// function returning number of collisions/xing
boost::function0< long > m_f_collDistr;
/// float scaling number of collisions/xing
float m_collXingSF;
/// bool apply scaling number of collisions/xing ?
Gaudi::Property<bool> m_ignoreSF;
};
#endif // PILEUPTOOLS_BKGSTREAMSCACHE_H
This diff is collapsed.
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef PILEUPTOOLS_BKGSTREAMSSTEPCACHE_H
# define PILEUPTOOLS_BKGSTREAMSSTEPCACHE_H
/** @file BkgStreamsStepCache.h
* @brief In memory cache for pileup events - stepping through the bunch crossings
*
* $Id: BkgStreamsStepCache.h,v 1.10 2008-08-28 01:11:06 calaf Exp $
* @author Will Buttinger - ATLAS Collaboration
*/
#include <string>
#include <vector>
#include <deque>
#include <boost/function.hpp>
#include "AthenaBaseComps/AthAlgTool.h"
#include "AthenaKernel/MsgStreamMember.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/Property.h"
#include "PileUpTools/PileUpStream.h"
#include "PileUpTools/IBkgStreamsCache.h"
#include "EventInfo/PileUpTimeEventIndex.h" /* needed for PileUpType */
class ActiveStoreSvc;
class IEvtSelector;
class IAtRndmGenSvc;
class IBeamIntensity;
namespace CLHEP {
class RandFlat;
class RandPoisson;
}
/** @class BkgStreamsStepCache
* @brief In-memory cache for pileup events
*/
class BkgStreamsStepCache :
public extends<AthAlgTool, IBkgStreamsCache>
{
public:
BkgStreamsStepCache( const std::string&, const std::string&, const IInterface*);
virtual ~BkgStreamsStepCache();
virtual StatusCode initialize() override final;
virtual StatusCode finalize() override final;
/**
@param nXings bunch Xings to be processed
@param firstStore id of first store in cache
*/
virtual StatusCode setup(int firstXing,
unsigned int nXings,
unsigned int firstStore,
IBeamIntensity*) override final;
/// inform cache that we start overlaying a new event
virtual void newEvent() override final;
/// reset scale factor at new run/lumiblk
virtual void resetEvtsPerXingScaleFactor(float sf) override final;
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overlaidEvent,
int t0BinCenter) override final;
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
@param BCID bunch-crossing ID of signal bunch crossing
@param loadEventProxies should we load the event proxies or not.
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overEvent,
int t0BinCenter, bool loadEventProxies, unsigned int /*BCID*/) override final;
/// how many stores in cache
virtual unsigned int nStores() const override final { return m_nStores; }
/// meant to be used (mainly) via f_collDistr
long collXing() { return m_collXing; }
long collXingPoisson();
/// meant to be used via f_numberOfBackgroundForBunchCrossing
unsigned int numberOfBkgForBunchCrossingIgnoringBeamIntensity(unsigned int iXing) const;
unsigned int numberOfBkgForBunchCrossingDefaultImpl(unsigned int iXing) const;
unsigned int numberOfCavernBkgForBunchCrossing(unsigned int iXing) const;
private:
/// get next bkg event from cache
const xAOD::EventInfo* nextEvent();
/// as nextEvent except don't actually load anything
StatusCode nextEvent_passive();
/// get current (last asked) stream
PileUpStream* current();
/// apply m_beamInt normalization to random number of events
//unsigned int normEventsXing(unsigned int iXing) const;
unsigned int setNEvtsXing(unsigned int iXing);
unsigned int nEvtsXing(unsigned int iXing) const;
typedef std::vector<PileUpStream> StreamVector;
bool alreadyInUse(StreamVector::size_type iStream);
ActiveStoreSvc* p_activeStore;
StreamVector::iterator m_cursor;
StreamVector m_streams;
std::vector<bool> m_usedStreams;
std::deque<StreamVector::size_type> m_streamUseOrder; //holds order in which events should be loaded
//we use a deque to easily pop early events off the front, pushing new events on to the back
std::deque<StreamVector::size_type>::iterator m_useCursor; //will use to know which event to load next
bool m_firstEvent; //For very first event of job we need to setup a full set of event counts
unsigned int m_currentXing; //the xing of the current event being simulated
unsigned int m_nXings;
unsigned int m_nStores;
std::vector<unsigned int> m_nEvtsXing;
/// @name Properties
//@{
/// # of collisions/xings (~beam intensity)
Gaudi::Property<float> m_collXing;
/// The maximum fraction of bunch-crossings which will be occupied.
Gaudi::Property<float> m_occupationFraction;
/// select collision distribution
Gaudi::Property<std::string> m_collDistrName;
ServiceHandle<IEvtSelector> m_selecName;
/// read downscale factor (average number of times a min bias is reused)
Gaudi::Property<int> m_readDownscale;
/// IAtRndmGenSvc controlling the distribution of bkg events/xing
ServiceHandle<IAtRndmGenSvc> m_atRndmSvc;
/// the IAtRndmGenSvc stream to generate number of collisions/xing
Gaudi::Property<std::string> m_randomStreamName;
/// the type of events in this cache
Gaudi::CheckedProperty<unsigned short> m_pileUpEventTypeProp;
void PileUpEventTypeHandler(Property&);
/// the type of events in this cache
xAOD::EventInfo::PileUpType m_pileUpEventType;
/// subtract from number of events at bunch xing = 0
Gaudi::Property<unsigned short> m_subtractBC0;
/// ignore the PileUpEventLoopMgr beam intensity tool
Gaudi::Property<bool> m_ignoreBM;
//@}
/// read a new event every downscaleFactor accesses
CLHEP::RandFlat* m_readEventRand;
/// pickup an event store at random from the cache
CLHEP::RandFlat* m_chooseEventRand;
/// set number of collisions/xing (if Poisson distribution chosen)
CLHEP::RandPoisson* m_collXingPoisson;
/// function returning the number of collisions per bunch crossing
/// before bunch structure modulation
boost::function0< long > m_f_collDistr;
/// function returning the number of bkg events per bunch crossing
/// after bunch structure modulation
boost::function1< unsigned int, unsigned int > m_f_numberOfBackgroundForBunchCrossing;
/// float scaling number of collisions/xing
float m_collXingSF;
/// bool apply scaling number of collisions/xing ?
Gaudi::Property<bool> m_ignoreSF;
/// offset of BC=0 xing
int m_zeroXing;
/// pointer to the IBeamIntensity distribution tool
IBeamIntensity* m_beamInt;
};
#endif // PILEUPTOOLS_BKGSTREAMSCACHE_H
This diff is collapsed.
/*
Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
*/
#ifndef PILEUPTOOLS_SPLITBKGSTREAMSCACHE_H
# define PILEUPTOOLS_SPLITBKGSTREAMSCACHE_H
/** @file SplitBkgStreamsCache.h
* @brief In memory cache for pileup events
*
* $Id: SplitBkgStreamsCache.h,v 1.10 2008-08-28 01:11:06 calaf Exp $
* @author Paolo Calafiura - ATLAS Collaboration
*/
#include <string>
#include <vector>
#include <boost/function.hpp>
#include "AthenaBaseComps/AthAlgTool.h"
#include "AthenaKernel/MsgStreamMember.h"
#include "GaudiKernel/ServiceHandle.h"
#include "GaudiKernel/Property.h"
#include "PileUpTools/PileUpStream.h"
#include "PileUpTools/IBkgStreamsCache.h"
#include "EventInfo/PileUpTimeEventIndex.h" /* needed for PileUpType */
class ActiveStoreSvc;
class IAtRndmGenSvc;
class IEvtSelector;
class IBeamIntensity;
namespace CLHEP {
class RandFlat;
class RandPoisson;
}
/** @class SplitBkgStreamsCache
* @brief In-memory cache for pileup events
*/
class SplitBkgStreamsCache :
public extends<AthAlgTool, IBkgStreamsCache>
{
public:
SplitBkgStreamsCache( const std::string&, const std::string&, const IInterface*);
virtual ~SplitBkgStreamsCache();
virtual StatusCode initialize();
virtual StatusCode finalize();
/**
@param nXings bunch Xings to be processed
@param firstStore id of first store in cache
*/
virtual StatusCode setup(int firstXing,
unsigned int nXings,
unsigned int firstStore,
IBeamIntensity*);
/// inform cache that we start overlaying a new event
virtual void newEvent();
/// reset scale factor at new run/lumiblk
virtual void resetEvtsPerXingScaleFactor(float sf);
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overlaidEvent,
int t0BinCenter) override final;
/**
@brief Read input events in bkg stores and link them to overlay store
@param iXing offset to first xing number (=0 first Xing, =nXings for last xing)
@param overlaidEvent reference to resulting overlaid event
@param t0BinCenter time wrto t0 of current bin center in ns
@param loadEventProxies should we load the event proxies or not.
@param BCID bunch-crossing ID of signal bunch crossing
*/
virtual StatusCode addSubEvts(unsigned int iXing,
xAOD::EventInfo* overEvent,
int t0BinCenter, bool loadEventProxies, unsigned int /*BCID*/) override final;
/// how many stores in this cache
virtual unsigned int nStores() const { return (m_nStores1 + m_nStores2); }
/// meant to be used (mainly) via f_collDistr
long collXing() { return m_meanCollisionsPerBunchCrossing; }
long collXingPoisson();
/// meant to be used via m_f_numberOfBackgroundForBunchCrossing
unsigned int numberOfBkgForBunchCrossingIgnoringBeamIntensity(unsigned int iXing) const;
unsigned int numberOfBkgForBunchCrossingDefaultImpl(unsigned int iXing) const;
unsigned int numberOfCavernBkgForBunchCrossing(unsigned int iXing) const;
private:
/// get next bkg event from cache
const xAOD::EventInfo* nextEvent(bool isCentralBunchCrossing);
/// as nextEvent except don't actually load anything
StatusCode nextEvent_passive(bool isCentralBunchCrossing);
/// get current (last asked) stream
PileUpStream* current();
unsigned int pickNumberOfBkgForBunchCrossing(unsigned int iXing);
unsigned int getNumberOfBkgForBunchCrossing(unsigned int iXing) const;
void calculateCacheSizes();
typedef std::vector<PileUpStream> StreamVector;
bool alreadyInUse(StreamVector::size_type iStream, unsigned int cacheForThisEvent);
ActiveStoreSvc* p_activeStore;
StreamVector::iterator m_cursor;
unsigned int m_nXings;
//Properties for Cache1
StreamVector m_streams1;
std::vector<bool> m_usedStreams1;
unsigned int m_nStores1;
//Properties for Cache2
StreamVector m_streams2;
std::vector<bool> m_usedStreams2;
unsigned int m_nStores2;
std::vector<unsigned int> m_numberOfBkgForBunchCrossing;
/// @name Properties
//@{
/// # of collisions per bunch crossing (~beam intensity)
Gaudi::Property<float> m_meanCollisionsPerBunchCrossing;
/// Fraction of cache1 collisions
Gaudi::Property<float> m_fractionOfCache1Collisions;
/// The maximum fraction of bunch-crossings which will be occupied.
Gaudi::Property<float> m_occupationFraction;
/// select collision distribution
Gaudi::Property<std::string> m_collDistrName;
ServiceHandle<IEvtSelector> m_selecName1;
ServiceHandle<IEvtSelector> m_selecName2;
/// read downscale factor for cache1 (average number of times a min bias is reused)
Gaudi::Property<float> m_readDownscale1;
/// read downscale factor for cache2 (average number of times a min bias is reused)
Gaudi::Property<float> m_readDownscale2;
/// IAtRndmGenSvc controlling the distribution of bkg events per bunch crossing
ServiceHandle<IAtRndmGenSvc> m_atRndmSvc;
/// the IAtRndmGenSvc stream to generate number of bkg events per bunch crossing
Gaudi::Property<std::string> m_randomStreamName;
/// the type of events in this cache
Gaudi::CheckedProperty<unsigned short> m_pileUpEventTypeProp;
void PileUpEventTypeHandler(Property&);
/// the type of events in this cache
xAOD::EventInfo::PileUpType m_pileUpEventType;
/// subtract from number of events at bunch xing = 0
Gaudi::Property<unsigned short> m_subtractBC0;
/// ignore the PileUpEventLoopMgr beam intensity tool
Gaudi::Property<bool> m_ignoreBM;
/// bool apply scaling number of collisions per bunch crossing ?
Gaudi::Property<bool> m_ignoreSF;
/// Force events used in the central bunch crossing to be refreshed
Gaudi::Property<bool> m_forceReadForBC0;
//@}
/// read a new event every downscaleFactor accesses from cache1
CLHEP::RandFlat* m_readEventRand1;
/// read a new event every downscaleFactor accesses from cache2
CLHEP::RandFlat* m_readEventRand2;
/// pickup an event store at random from cache1
CLHEP::RandFlat* m_chooseEventRand1;
/// pickup an event store at random from cache2
CLHEP::RandFlat* m_chooseEventRand2;
/// pick whether event will come from cache 1 or cache2
CLHEP::RandFlat* m_chooseCacheRand;
/// set number of collisions per bunch crossing (if Poisson distribution chosen)
CLHEP::RandPoisson* m_collXingPoisson;
/// function returning the number of collisions per bunch crossing
/// before bunch structure modulation
boost::function0< long > m_f_collDistr;
/// function returning the number of bkg events per bunch crossing
/// after bunch structure modulation
boost::function1< unsigned int, unsigned int > m_f_numberOfBackgroundForBunchCrossing;
/// float scaling number of collisions per bunch crossing
float m_collXingSF;
/// offset of BC=0 xing
int m_zeroXing;
/// pointer to the IBeamIntensity distribution tool
IBeamIntensity* m_beamInt;
};
#endif // PILEUPTOOLS_SPLITBKGSTREAMSCACHE_H
#include "../BkgStreamsCache.h"
#include "../BkgStreamsConcentricCache.h"
#include "../BkgStreamsStepCache.h"
#include "../SplitBkgStreamsCache.h"
#include "../PileUpEventLoopMgr.h"
#include "../PileUpXingFolder.h"
#include "../PileUpToolsAlg.h"
......@@ -22,9 +19,6 @@ DECLARE_COMPONENT( StepArrayBM )
DECLARE_COMPONENT( LumiProfileSvc )
DECLARE_COMPONENT( NoProfileSvc )
DECLARE_COMPONENT( BkgStreamsCache )
DECLARE_COMPONENT( BkgStreamsConcentricCache )
DECLARE_COMPONENT( BkgStreamsStepCache )
DECLARE_COMPONENT( SplitBkgStreamsCache )
DECLARE_COMPONENT( PileUpXingFolder )
DECLARE_COMPONENT( TestPileUpTool )
DECLARE_COMPONENT( PileUpToolsAlg )
......
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