|
ATLAS Offline Software
|
Go to the documentation of this file.
34 #include "CLHEP/Random/Randomize.h"
35 #include "CLHEP/Random/RandomEngine.h"
39 using CLHEP::RandFlat;
40 using CLHEP::RandGaussQ;
41 using CLHEP::RandPoissonT;
42 using CLHEP::RandGeneral;
45 const std::string&
name,
75 ATH_MSG_INFO(
"No photostatistics effect will be simulated");
92 ATH_MSG_INFO(
" In case of pileup, the trigger time subtraction is done in PileUpSvc");
93 ATH_MSG_INFO(
" => TileHitVecToCnt will not apply Trigger Time ");
162 <<
"'; therefore set HitTimeFlag to 2");
166 ATH_MSG_ERROR(
"Take average time from all hits in event as trigger time");
181 ATH_MSG_INFO(
"Minimal hit time will be used as trigger time"
182 <<
" with random additional shift between 0 and " << -
m_triggerTime <<
" ns");
185 ATH_MSG_INFO(
"Average time will be calculated in every event");
193 ATH_MSG_INFO(
"Time of all hits will be preserved during copy");
231 ATH_MSG_DEBUG(
"TileHitVecToCntTool initialization completed");
234 return StatusCode::RECOVERABLE;
236 return StatusCode::SUCCESS;
247 for (; iHit != lastHit; ++iHit) {
256 for (; iHit != lastHit; ++iHit) {
258 if(pHit ==
nullptr)
continue;
271 return StatusCode::SUCCESS;
277 ATH_MSG_DEBUG(
"TileHitVecToCntTool prepareEvent initialization started");
286 return StatusCode::SUCCESS;
294 for (; inpItr !=
end; ++inpItr) {
296 const TileHit * cinp = &(*inpItr);
298 eHitTot += cinp->
energy();
305 int hitsize = cinp->
size();
308 for (
int i = 0;
i < hitsize; ++
i) {
317 eHitTot += eHit - cinp->
energy();
323 <<
" Copy hit: ener=";
324 for (
int i = 0;
i < hitsize; ++
i)
327 for (
int i = 0;
i < hitsize; ++
i)
336 double& eHitTot,
bool isSignal) {
342 const bool inTimeEvent(fabs(SubEvtTimOffset) <
m_deltaT);
347 for (; inpItr !=
end; ++inpItr) {
349 const TileHit * cinp = &(*inpItr);
369 double ener = cinp->
energy();
370 double time = cinp->
time() + SubEvtTimOffset;
376 TileHit * pHit_DigiHSTruth(
nullptr);
389 pHit =
new TileHit(hit_id, 0.0, 0.0);
392 pHit_DigiHSTruth =
new TileHit(hit_id, 0.0, 0.0);
406 <<
" offs=" << SubEvtTimOffset
424 if (pHit->
size() > 1 || pHit->
energy() != 0.0)
429 <<
" offs=" << SubEvtTimOffset
430 <<
" double hit" <<
endmsg;
437 <<
" offs=" << SubEvtTimOffset
442 int hitsize = cinp->
size();
443 for (
int ind = 1;
ind < hitsize; ++
ind) {
465 <<
" double hit from single hit" <<
endmsg;
484 for (; inpItr !=
end; ++inpItr) {
485 const TileHit * cinp = &(*inpItr);
486 eHitTot += cinp->
energy();
493 int hitsize = cinp->
size();
496 for (
int i = 0;
i < hitsize; ++
i) {
505 eHitTot += eHit - cinp->
energy();
511 <<
" Copy hit: ener=";
512 for (
int i = 0;
i < hitsize; ++
i)
515 for (
int i = 0;
i < hitsize; ++
i)
525 for (; inpItr !=
end; ++inpItr) {
526 const TileHit * cinp = &(*inpItr);
529 for (
int i = 0;
i <
size; ++
i) {
542 int hitsize = cinp->
size();
547 <<
" Input hit: ener=";
548 for (
int i = 0;
i < hitsize; ++
i)
551 for (
int i = 0;
i < hitsize; ++
i)
580 for (; inpItr !=
end; ++inpItr) {
581 const TileHit * cinp = &(*inpItr);
583 for (
int i = 0;
i <
size; ++
i) {
584 if (cinp->
time(
i) < avtime) avtime = cinp->
time(
i);
597 for (; inpItr !=
end; ++inpItr) {
598 const TileHit * cinp = &(*inpItr);
600 for (
int i = 0;
i <
size; ++
i) {
614 inpItr = inputHits->
begin();
617 for (; inpItr !=
end; ++inpItr) {
618 const TileHit * cinp = &(*inpItr);
622 for (
int i = 0;
i <
size; ++
i) {
631 int hitsize = pHit->
size();
634 for (
int i = 0;
i < hitsize; ++
i) {
647 <<
" Output hit: ener=";
648 for (
int i = 0;
i < hitsize; ++
i)
651 for (
int i = 0;
i < hitsize; ++
i)
672 ATH_MSG_DEBUG(
"Inside TileHitVecToCntTool processBunchXing" << bunchXing);
676 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(Gaudi::Hive::currentContext());
681 while (iEvt != eSubEvents) {
686 std::vector<std::string>::const_iterator hitVecNamesItr =
m_hitVectorNames.begin();
687 std::vector<std::string>::const_iterator hitVecNamesEnd =
m_hitVectorNames.end();
688 for (; hitVecNamesItr != hitVecNamesEnd; ++hitVecNamesItr) {
690 const std::string hitVectorName(*hitVecNamesItr);
695 if (!(
m_mergeSvc->retrieveSingleSubEvtData(hitVectorName, inputHits, bunchXing, iEvt))){
696 ATH_MSG_ERROR(
" Tile Hit container not found for event key " << hitVectorName);
699 const double SubEvtTimOffset(iEvt->time());
702 if (fabs(SubEvtTimOffset) > 0.1) {
703 ATH_MSG_ERROR(
"Wrong time for in-time event: " << SubEvtTimOffset <<
" Ignoring all hits ");
705 ATH_MSG_DEBUG(
" New HitCont. TimeOffset=" << SubEvtTimOffset <<
", size =" << inputHits->
size());
710 bool isSignal =
false;
711 if(iEvt == bSubEvents) isSignal =
true;
719 if (!(
m_mergeSvc->retrieveSingleSubEvtData(hitVectorName, inputHits, bunchXing, iEvt))){
720 ATH_MSG_ERROR(
" Tile Hit container not found for event key " << hitVectorName);
733 ATH_MSG_DEBUG(
"Exiting processBunchXing in TileHitVecToCntTool");
735 return StatusCode::SUCCESS;
740 ATH_MSG_DEBUG(
"TileHitVecToCntTool processAllSubEvents started");
751 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(ctx);
755 for (
auto & inputHits : hitVectorHandles) {
756 if (!inputHits.isValid()) {
758 return StatusCode::FAILURE;
760 const double SubEvtTimeOffset(0.0);
762 ATH_MSG_DEBUG(
" New HitCont. TimeOffset=" << SubEvtTimeOffset <<
", size =" << inputHits->size());
767 return StatusCode::SUCCESS;
773 TimedHitContList hitContList;
775 if (!(
m_mergeSvc->retrieveSubEvtsData(hitVectorName, hitContList).isSuccess()) || hitContList.size() == 0) {
776 ATH_MSG_WARNING(
"Could not fill TimedHitContList for hit vector " << hitVectorName);
785 if (iCont != iEndCont) {
787 const double SubEvtTimeOffset(iCont->first.time());
788 if (fabs(SubEvtTimeOffset) > 0.1) {
789 ATH_MSG_ERROR(
"Wrong time for in-time event: " << SubEvtTimeOffset <<
" Ignoring all hits ");
793 ATH_MSG_DEBUG(
" New HitCont. TimeOffset=" << SubEvtTimeOffset <<
", size =" << inputHits->
size());
800 for (; iCont != iEndCont; ++iCont) {
802 const double SubEvtTimeOffset(iCont->first.time());
805 ATH_MSG_VERBOSE(
" New HitCont. TimeOffset=" << SubEvtTimeOffset <<
", size =" << inputHits->
size());
806 bool isSignal =
false;
807 if(iCont == hitContList.begin() ) isSignal =
true;
818 ATH_MSG_WARNING(
"Hit Vector "<< hitVectorName <<
" not found in StoreGate");
829 return StatusCode::SUCCESS;
843 double eHitInTime = 0.0;
847 for (; iHit != lastHit; ++iHit) {
849 std::unique_ptr<TileHit> pHit_DigiHSTruth;
850 if(
m_doDigiTruth) pHit_DigiHSTruth = std::make_unique<TileHit>(**iHit_DigiHSTruth);
851 if (pHit->
size() > 1 || pHit->
energy() != 0.0) {
857 eHitInTime += pHit->
energy();
863 ATH_MSG_DEBUG(
" nHitUni=" << nHitUni <<
" eHitInTime="<< eHitInTime);
876 for (std::unique_ptr<TileHitCollection>& coll : *
m_hits ) {
877 int frag_id = coll->identify();
887 for (; collIt != endcollIt; ++collIt) {
888 int frag_id = (*collIt)->identify();
901 CLHEP::HepRandomEngine * engine = rngWrapper->
getEngine(ctx);
913 for (std::unique_ptr<TileHitCollection>& coll : *
m_hits ) {
918 coll_DigiHSTruth = (*collIt_DigiHSTruth).
get();
919 hitItr_DigiHSTruth = coll_DigiHSTruth->
begin();
920 hitEnd_DigiHSTruth = coll_DigiHSTruth->
end();
930 int hitsize = pHit->size();
931 for (
int i = 0;
i < hitsize; ++
i) {
932 double thit = pHit->time(
i);
944 double scaleFactor = 1.0;
947 pHit->scale(scaleFactor);
951 TileHit *pHit_DigiHSTruth = (*hitItr_DigiHSTruth);
952 pHit_DigiHSTruth->
scale(scaleFactor);
954 ++hitItr_DigiHSTruth;
964 auto hits = std::make_unique<TileHitContainer>
967 for (std::unique_ptr<TileHitCollection>& coll : *
m_hits ) {
968 CHECK(
hits->addCollection (coll.release(), hashId++));
982 auto hits_DigiHSTruth = std::make_unique<TileHitContainer>
984 size_t hashId_DigiHSTruth = 0;
986 ATH_CHECK(hits_DigiHSTruth->addCollection (coll.release(), hashId_DigiHSTruth++));
990 ATH_CHECK( hitContainer_DigiHSTruth.
record(std::move(hits_DigiHSTruth)) );
994 return StatusCode::SUCCESS;
1004 for (; iHit != lastHit; ++iHit) {
1010 for (; iHit != lastHit; ++iHit) {
1018 return StatusCode::SUCCESS;
1032 nPhotoElectrons =
std::round(nPhotoElectrons * 1000) / 1000;
1034 double pe =
energy * nPhotoElectrons;
1035 double pe_scale = 1., RndmPois = 1.;
1040 RndmPois =
std::max(0.0, RandGaussQ::shoot(engine,
pe, sqrt(
pe)));
1041 pe_scale = RndmPois /
pe;
1045 double singleMEAN = 1.0;
1046 double singleSIGMA = 1.0;
1047 RndmPois = RandPoissonT::shoot(engine,
pe);
1051 for (
int i = 0;
i < RndmPois;
i++)
1052 pe_scale += 1 / (1.08332) *
std::max(0., RandGaussQ::shoot(engine, singleMEAN, singleSIGMA));
1054 pe_scale /= RndmPois;
1063 RndmPois = RandPoissonT::shoot(engine,
pe);
1064 pe_scale = RndmPois /
pe;
1071 RndmPois =
std::max(0.0, RandGaussQ::shoot(engine,
pe, sqrt(
pe)));
1074 double * ProbFunc =
new double[nn];
1075 ProbFunc[0] =
exp(-
pe);
1076 for (
int i = 1;
i < nn; ++
i) {
1077 ProbFunc[
i] = ProbFunc[
i - 1] *
pe /
i;
1079 RandGeneral* RandG =
new RandGeneral(ProbFunc, nn, 0);
1080 RndmPois = RandG->shoot(engine) * nn;
1086 pe_scale = RndmPois /
pe;
1093 <<
", numPhElec=" << nPhotoElectrons
1095 <<
", rndmPoisson=" << RndmPois
1096 <<
", pe_scale=" << pe_scale);
1103 int module = frag_id & 0x3F;
1111 for (; hitIt != endHitIt; ++hitIt) {
1122 if (fromHitIt != coll->
end()) {
1124 <<
"] in module: " <<
module);
1125 bool isToHitNew =
false;
1129 toHit =
new TileHit(to_pmt_id);
1144 toHit->
add(*fromHitIt, 0.1);
1151 coll->
erase(fromHitIt);
1161 int module = frag_id & 0x3F;
1169 for (; hitIt != endHitIt; ++hitIt) {
1180 if (fromHitIt != coll->
end()) {
1182 <<
"] in module: " <<
module);
1183 bool isToHitNew =
false;
1188 toHit =
new TileHit(to_pmt_id);
1203 toHit->
add(*fromHitIt, 0.1);
1211 coll->
erase(fromHitIt);
1220 for (std::unique_ptr<TileHitCollection>& coll : *hitCont) {
1222 int frag_id = coll->identify();
1223 int module = frag_id & 0x3F;
1225 std::vector<TileHit*>
hits(48,
nullptr);
1226 std::vector<std::unique_ptr<TileHit>> otherModuleHits;
1227 coll->erase(std::remove_if(coll->begin(), coll->end(),
1229 Identifier pmt_id = hit->pmt_ID();
1230 int channel = m_tileHWID->channel(hit->pmt_HWID());
1231 TileHit* channelHit = hits[channel];
1233 mergeExtraHitToChannelHit(hit, channelHit);
1239 otherModuleHits.push_back(std::make_unique<TileHit>(*hit));
1242 hits[channel] = hit;
1247 for (std::unique_ptr<TileHit>& hit : otherModuleHits) {
1254 coll->push_back(std::move(hit));
1268 channelHit->
add(extraHit, 0.1);
def retrieve(aClass, aKey=None)
JetConstituentVector::iterator iterator
void scale(float coeff)
Scale energy of all sub-hits in a hit
Identifier identify(void) const
Return logical ID of the pmt.
float getSamplingFraction(unsigned int drawerIdx, unsigned int channel) const
Return Tile Calorimeter sampling fraction.
void setSeed(const std::string &algName, const EventContext &ctx)
Set the random seed using a string (e.g.
Identifier channel_id(int type, int module, int channel) const
identifer for one channel of a Tile testbeam detector
std::string to_string(const Identifier &id, int level=0) const
extract all fields from TileTB identifier Identifier get_all_fields ( const Identifier & id,...
Scalar phi() const
phi method
bool is_tiletb(const Identifier &id) const
Test ID if it is TileTBID.
const_pointer_type cptr()
Dereference the pointer.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
AtlasHitsVector< TileHit >::const_iterator TileHitVecConstIterator
Scalar eta() const
pseudorapidity method
float round(const float toRound, const unsigned int decimals)
int side(const Identifier &id) const
int sample(const Identifier &id) const
const T * get(size_type n) const
Access an element, as an rvalue.
int frag(const HWIdentifier &id) const
extract frag field from HW identifier
size_type drawer_hash_max(void) const
drawer hash table max size
int tower(const Identifier &id) const
#define ATH_MSG_VERBOSE(x)
const std::string & key() const
Return the StoreGate ID for the referenced object.
int type(const Identifier &id) const
extract type field from TileTB identifier
const_iterator begin() const
int size(void) const
Return length of energy/time vectors
int module(const Identifier &id) const
extract module field from TileTB identifier
int channel(const HWIdentifier &id) const
extract channel field from HW identifier
int ros(const HWIdentifier &id) const
extract ros field from HW identifier
std::list< value_t > type
type of the collection of timed data object
float getNumberOfPhotoElectrons(unsigned int drawerIdx, unsigned int channel) const
Return number of photoelectrons per 1 GeV in Tile Calorimeter scintilator.
Handle class for recording to StoreGate.
bool isRun2PlusCabling() const
virtual int get_id(const IdentifierHash &hash_id, Identifier &id, const IdContext *context=0) const
create compact id from hash id (return == 0 for OK)
std::vector< std::unique_ptr< TileHitCollection > >::iterator iterator
int module(const Identifier &id) const
Condition object to keep and provide Tile Calorimeter sampling fraction and number of photoelectrons.
void reserve(int len)
Reserve length of energy and time vectors in a hit
(Non-const) Iterator class for DataVector/DataList.
@ OWN_ELEMENTS
this data object owns its elements
IdContext channel_context(void) const
idContext for channels
::StatusCode StatusCode
StatusCode definition for legacy code.
int add(float energy, float time)
Add sub-hit to a given hit.
#define CHECK(...)
Evaluate an expression and check for errors.
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
bool isRun2Cabling() const
void initialize(const TileHWID *tileHWID, TYPE type=Default)
int channel(const Identifier &id) const
extract channel field from TileTB identifier
virtual bool isValid() override final
Can the handle be successfully dereferenced?
virtual int get_hash(const Identifier &id, IdentifierHash &hash_id, const IdContext *context=0) const
create hash id from compact id (return == 0 for OK)
void push_back(element_t *rc)
HWIdentifier drawer_id(int frag) const
ROS HWIdentifer.
bool is_MBTS_merged_run2plus(int module) const
A wrapper class for event-slot-local random engines.
Helpers for checking error return status codes and reporting errors.
StatusCode initialize(bool used=true)
CLHEP::HepRandomEngine * getEngine(const EventContext &ctx) const
Retrieve the random engine corresponding to the provided EventContext.
size_type pmt_hash_max(void) const
const_iterator end() const noexcept
Return a const_iterator pointing past the end of the collection.
This is a minimal version of a TileHitContainer in which the saved collections remain non-const.
int drawer(const HWIdentifier &id) const
extract drawer field from HW identifier
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
def time(flags, cells_name, *args, **kw)
HWIdentifier pmt_HWID(void) const
Return pmt hardware ID (== channel ID)
std::string to_string(const Identifier &id, int level=0) const
#define ATH_MSG_WARNING(x)
float energy(int ind=0) const
Return energy of ind-th sub-hit
Identifier pmt_id(const Identifier &any_id) const
const_iterator end() const
void setTime(float t, int ind=0)
Set time of ind-th sub-hit in a hit
IdContext pmt_context(void) const
id for PMTs
int phi(const Identifier &id) const
extract phi field from MBTS identifier
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
iterator erase(iterator position)
Remove element at a given position.
Identifier cell_id(const Identifier &any_id) const
float time(int ind=0) const
Return time of ind-th sub-hit
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
void setZero()
Resize energy/time vectors in a hit to one and set energy/time to zero
int E1_merged_with_run2plus(int ros, int module) const
interface to a tool that returns the time offset of the current trigger. Used by PileUpMergeSvc
Identifier pmt_ID(void) const
Return logical ID of the pmt.
const_iterator begin() const noexcept
Return a const_iterator pointing at the beginning of the collection.
int side(const Identifier &id) const
define synonyms for minimum bias scintillators
HWIdentifier s2h_channel_id(const Identifier &id) const