13#include "CLHEP/Random/RandomEngine.h"
14#include "CLHEP/Random/RandGaussZiggurat.h"
29 declareProperty(
"ModNoise",
m_modNoise,
"RMS noise averaged over modules");
30 declareProperty(
"ModSignal",
m_modSignal,
"Average MIP signal in modules");
31 declareProperty(
"NinoThr",
m_ninoThr,
"NINO threshold voltage");
51 return StatusCode::FAILURE;
65 return StatusCode::SUCCESS;
75 ATH_CHECK(outputContainer.
record(std::make_unique<BCM_RDO_Container>()));
76 if (!outputContainer.
isValid()) {
77 ATH_MSG_ERROR(
"Could not record output BCM RDO container " << outputContainer.
name() <<
" to store " << outputContainer.
store());
78 return StatusCode::FAILURE;
81 ATH_MSG_DEBUG(
"Recorded output BCM RDO container " << outputContainer.
name() <<
" in store " << outputContainer.
store());
86 ATH_CHECK(outputSDOContainer.
record(std::make_unique<InDetSimDataCollection>()));
87 if (!outputSDOContainer.
isValid()) {
88 ATH_MSG_ERROR(
"Could not record output BCM SDO container " << outputSDOContainer.
name() <<
" to store " << outputSDOContainer.
store());
89 return StatusCode::FAILURE;
92 ATH_MSG_DEBUG(
"Recorded output BCM SDO container " << outputSDOContainer.
name() <<
" in store " << outputSDOContainer.
store());
97 for (
unsigned int iMod=0; iMod<8; ++iMod) {
103 return StatusCode::SUCCESS;
130 rngWrapper->
setSeed( name(), ctx );
133 for (
int iMod=0; iMod<8; ++iMod) {
137 for (
int iGain=0; iGain<2; ++iGain) {
142 fillRDO(iGain*8+iMod,p1x,p1w,p2x,p2w);
152 ATH_MSG_DEBUG (
"prepareEvent() called for " << nInputEvents <<
" input events" );
156 return StatusCode::SUCCESS;
171 if (!hitCollection.
isValid()) {
172 ATH_MSG_ERROR(
"Could not get BCM SiHitCollection container " << hitCollection.
name() <<
173 " from store " << hitCollection.
store());
174 return StatusCode::FAILURE;
176 const unsigned int evtIndex = 0;
177 const double time = 0.0;
178 ATH_MSG_DEBUG (
"SiHitCollection found with " << hitCollection->size() <<
" hits" );
180 for (
const auto& siHit : *hitCollection) {
187 TimedHitCollList hitCollList;
190 return StatusCode::FAILURE;
196 TimedHitCollList::iterator iColl(hitCollList.begin());
197 TimedHitCollList::iterator endColl(hitCollList.end());
198 for (; iColl != endColl; ++iColl) {
200 const unsigned int evtIndex = (iColl->first).
index();
201 const double time = (iColl->first).time();
204 for (
const auto& siHit : *tmpColl) {
212 return StatusCode::SUCCESS;
222 const EventContext &ctx = Gaudi::Hive::currentContext();
227 for (; iEvt!=eSubEvents; ++iEvt) {
230 <<
" bunch crossing : " << bunchXing
231 <<
" time offset : " << iEvt->time()
232 <<
" event number : " << iEvt->ptr()->eventNumber()
233 <<
" run number : " << iEvt->ptr()->runNumber()
246 return StatusCode::SUCCESS;
258 return StatusCode::SUCCESS;
270 float xStep, yStep, rStep, r0Step, effStep;
271 for (
int iStep=0; iStep<10; ++iStep) {
272 xStep = startPos.x()+iStep*(endPos.x()-startPos.x())/9;
273 yStep = startPos.y()+iStep*(endPos.y()-startPos.y())/9;
274 if (xStep==0 && yStep==0) effStep = 1.;
276 rStep = sqrt(
pow(xStep,2)+
pow(yStep,2));
280 calcEner+= 0.1*simEner*effStep;
290 std::vector<float> analog(64,0);
291 for (
unsigned int iHit=0; iHit<enerVect.size(); ++iHit) {
292 float enerDep = enerVect.at(iHit);
293 float hitTime = timeVect.at(iHit);
294 int startBin = (int)(
hitTime*64/25);
296 float slopeup = signalMax/5;
297 float slopedown = signalMax/10;
298 int iBin = startBin-1;
300 if (iBin>=0 && startBin<64) {
301 while (signal>=0 && iBin<64) {
302 analog[iBin] += signal;
304 if (iBin > startBin+4) signal -= slopeup+slopedown;
317 for (
float & iBin : analog) iBin+=CLHEP::RandGaussZiggurat::shoot(randomEngine,0.,
m_modNoise[iMod]);
325 std::bitset<64> digital;
327 float factor = iChan<8 ? 1./13 : 12./13;
328 for (
int iBin=0; iBin<64; ++iBin)
329 if (analog[iBin]*factor>
m_ninoThr[iChan%8]) digital.set(iBin);
339 for (
int iSamp=2; iSamp<63; iSamp++) {
340 if (digital[iSamp-2] && digital[iSamp-1] && !digital[iSamp] && digital[iSamp+1]) digital[iSamp] = 1;
341 if (digital[iSamp-2] && !digital[iSamp-1] && digital[iSamp] && digital[iSamp+1]) digital[iSamp-1] = 1;
344 if (digital[0] && !digital[1]) digital[0] = 0;
345 for (
int iSamp=1; iSamp<63; iSamp++) {
346 if (!digital[iSamp-1] && digital[iSamp] && !digital[iSamp+1]) digital[iSamp] = 0;
348 if (!digital[62] && digital[63]) digital[63] = 0;
356 p1x = 0; p1w = 0; p2x = 0; p2w = 0;
358 if (!digital.count())
return;
360 bool p1done =
false, p2done =
false;
bool ignorepulse =
false;
361 if (digital[0] && digital[1]) ignorepulse =
true;
362 else if (!digital[0] && digital[1] && digital[2]) p1x = 1;
363 for (
int iBin=2; iBin<63; iBin++) {
364 if (!digital[iBin-2] && !digital[iBin-1] && digital[iBin] && digital[iBin+1]) {
365 if (!p1done && !p2done) p1x = iBin;
366 else if (p1done && !p2done) p2x = iBin;
368 else if (digital[iBin-2] && digital[iBin-1] && !digital[iBin] && !digital[iBin+1]) {
370 if (!p1done && !p2done) {
380 else if (p1done && !p2done) {
383 if (p2w >= 32) p2w = 31;
386 else ignorepulse =
false;
389 if (digital[61] && digital[62] && !digital[63]) {
391 if (!p1done && !p2done) {
401 else if (p1done && !p2done) {
404 if (p2w >= 32) p2w = 31;
407 else ignorepulse =
false;
409 else if (digital[62] && digital[63]) {
411 if (!p1done && !p2done) {
414 if (64 - p1x >= 32) {
421 else if (p1done && !p2done) {
424 if (64 - p2x >= 32) p2w = 31;
427 else ignorepulse =
false;
438 bool collExists =
false;
441 for (; it_coll!=it_collE; ++it_coll) {
442 if ((*it_coll)->getChannel()==chan) {
float hitTime(const AFP_SIDSimHit &hit)
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
Helpers for checking error return status codes and reporting errors.
#define CHECK(...)
Evaluate an expression and check for errors.
ATLAS-specific HepMC functions.
AtlasHitsVector< SiHit > SiHitCollection
static const Attributes_t empty
constexpr int pow(int base, int exp) noexcept
A wrapper class for event-slot-local random engines.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
CONT::const_iterator const_iterator
const_iterator begin() const
const_iterator end() const
value_type push_back(value_type pElem)
Add an element to the end of the collection.
DataModel_detail::iterator< DataVector > iterator
a link optimized in size for a GenParticle in a McEventCollection
static HepMcParticleLink getRedirectedLink(const HepMcParticleLink &particleLink, uint32_t eventIndex, const EventContext &ctx)
Return a HepMcParticleLink pointing at the same particle, but in a different GenEvent.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
std::string store() const
Return the name of the store holding the object we are proxying.
const std::string & name() const
Return the StoreGate ID for the referenced object.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
pointer_type ptr()
Dereference the pointer.
double energyLoss() const
HepGeom::Point3D< double > localStartPosition() const
const HepMcParticleLink & particleLink() const
HepGeom::Point3D< double > localEndPosition() const
The Athena Transient Store API.
StatusCode retrieve(const T *&ptr) const
Retrieve the default object into a const T*.
bool no_truth_link(const T &p)
Method to establish if a if the object is linked to something which was never saved to the HepMC Trut...
std::list< value_t > type
type of the collection of timed data object