|
ATLAS Offline Software
|
Go to the documentation of this file.
59 #include <CLHEP/Random/Randomize.h>
60 #include <CLHEP/Units/SystemOfUnits.h>
62 using CLHEP::RandGaussQ;
63 using CLHEP::RandFlat;
75 , m_cablingService(nullptr)
113 ATH_MSG_INFO(
"TilePulseForTileMuonReceiver should not be used for RUN1 simulations");
114 return StatusCode::SUCCESS;
116 ATH_MSG_INFO(
"Initializing TilePulseForTileMuonReceiver");
133 <<
" Triggering tile slice: " <<
m_iTrig
134 <<
" ADC saturation value: " <<
m_adcMax
149 <<
" Triggering tile sample " <<
m_iTrig);
177 ATH_MSG_INFO(
"Pileup and/or noise added by overlaying digits of random events");
181 ATH_MSG_INFO(
"PileUpMergeSvc successfully initialized");
185 ATH_MSG_VERBOSE(
"TilePulseForTileMuonReceiver initialization completed");
186 return StatusCode::SUCCESS;
194 ATH_MSG_VERBOSE(
"ATT: RUN1 settings TilePulseForTileMuonReceiver will end now" );
195 return StatusCode::SUCCESS;
200 const EventContext& ctx = Gaudi::Hive::currentContext();
209 int EBchan[
nEBchan]={17,16,37,38,3,2};
211 int LBchan[
nLBchan]={0,13,14,25,24,41,44,39,40};
213 #if (nEBchan > nLBchan)
214 double pDigitSamplesArray[
nEBchan][7];
215 double pDigitSamplesRndmArray[
nEBchan][7];
217 double pDigitSamplesArray[
nLBchan][7];
218 double pDigitSamplesRndmArray[
nLBchan][7];
231 double sigma_Hfn1 = 0.;
232 double sigma_Hfn2 = 0.;
233 double sigma_Norm = 0.;
234 double sigmaSim(0.0);
238 double muRcv_NoiseSigma;
250 badChannels = *badChannelsHandle;
264 sampleNoise = sampleNoiseHandle.
retrieve();
279 auto muRcvDigitsContainer = std::make_unique<TileMutableDigitsContainer>(
true,
282 ATH_CHECK( muRcvDigitsContainer->status() );
286 auto muRcvRawChannelContainer = std::make_unique<TileMutableRawChannelContainer>(
true,
290 ATH_CHECK( muRcvRawChannelContainer->status() );
296 std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
300 ATH_MSG_DEBUG(
"Prepare background container for MC Overlay procedure");
302 backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(
true,
305 ATH_CHECK( backgroundDigitContainer->status() );
309 TimedDigitContList digitContList;
313 if (digitContList.size() == 0) {
315 return StatusCode::SUCCESS;
319 for (
const auto* digitCollection : *(iTzeroDigitCont->second)) {
320 for (
const auto*
digit : *digitCollection) {
321 auto pDigits = std::make_unique<TileDigits>(*
digit);
322 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
327 if (tileDigitsContainerHandle.
isValid()) {
328 for (
const auto* digitCollection : *tileDigitsContainerHandle) {
329 for (
const auto*
digit : *digitCollection) {
330 auto pDigits = std::make_unique<TileDigits>(*
digit);
331 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
335 ATH_MSG_ERROR(
"ReadHandle to Background Digits is invalid.");
336 return StatusCode::FAILURE;
340 collItrRndm = backgroundDigitContainer->begin();
341 lastCollRndm = backgroundDigitContainer->end();
350 std::vector<float> digitsBuffer_rndm(
m_nSamples);
351 std::vector<bool> good_bkg( 9 ,
false );
375 ATH_MSG_VERBOSE(
"(A.00) Looping over all collections for TMDB in the HIT container");
376 memset(pDigitSamplesArray, 0,
sizeof(pDigitSamplesArray));
397 memset(pDigitSamplesRndmArray, 0,
sizeof(pDigitSamplesRndmArray));
403 if (hitCollection->identify() != bkgDigitCollection->
identify()) {
404 ATH_MSG_ERROR (
"Frag IDs for hit collection and digits overlay collection do not match "
405 << MSG::hex << hitCollection->identify() <<
" != " << bkgDigitCollection->
identify()
407 return StatusCode::FAILURE;
410 ATH_MSG_DEBUG(
"Prepare buffer (digitsBuffer_rndm) for MC Overlay procdure: pileup digits");
412 for (
const auto* bkgDigit : *bkgDigitCollection) {
413 bool good_channel =
true;
419 digitsBuffer_rndm = (*bkgDigit).samples();
421 int nsamp_rndm = digitsBuffer_rndm.size();
425 for (
int js=nsamp_rndm; js<
m_nSamples; ++js) {
426 digitsBuffer_rndm[js] = digitsBuffer_rndm[js-1];
432 pDigitSamplesRndmArray[
channel][j] = digitsBuffer_rndm[j];
435 if (pDigitSamplesRndmArray[
channel][j]==0) good_channel =
false;
437 good_bkg[
channel] = good_channel;
441 for (
int j=0; j< (
int) digitsBuffer_rndm.size(); j++)
msg(
MSG::VERBOSE) << digitsBuffer_rndm[j] <<
" | ";
454 if ( hitCollection->empty() )
ATH_MSG_DEBUG(
"-- No hits in this drawer! Filling channels with either noise and pedestal or MC pileup overlay. --");
456 for (
const TileHit* tile_hit : *hitCollection) {
468 ATH_MSG_VERBOSE(
"(B.00) ++ Iterate over all the D layer channels with hits");
478 TMDBchan = 1 -
m_tileID->
pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
480 TMDBchan =
m_tileID->
pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
482 TILEchan=EBchan[TMDBchan];
490 TMDBchan = 1 -
m_tileID->
pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
492 TMDBchan =
m_tileID->
pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
495 TILEchan=LBchan[TMDBchan];
498 double* pDigitSamples = pDigitSamplesArray[TMDBchan];
503 ATH_MSG_VERBOSE(
"(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<
" "<<TILEchan<<
"=?"
515 hit_calib =
std::round(hit_calib * 1000) / 1000;
524 int n_hits = tile_hit->size();
528 for (
int ihit = 0; ihit < n_hits; ++ihit) {
530 ATH_MSG_VERBOSE(
"(C.00) ++ Iterating over the hits of channel " << TILEchan <<
": hit " << ihit <<
"/"<< n_hits);
532 double e_hit = tile_hit->energy(ihit);
533 double e_pmt = e_hit * hit_calib;
535 ATH_MSG_VERBOSE(
"(C.01) Energy in scintillator [MeV]: " << e_hit <<
" true cell energy [MeV]: " << e_pmt);
537 double t_hit = tile_hit->time(ihit);
567 pDigitSamples[js] += e_pmt * shape;
571 <<
" Shape wt. = " << shape
572 <<
" Amp = " << pDigitSamples[js] <<
" [MeV]");
587 <<
" Amp = " << pDigitSamples[js]
588 <<
"[MeV] Energy: " << e_pmt <<
" LOGAIN from TileInfo");
594 ATH_MSG_DEBUG(
"(C.04) Went over " << n_hits <<
" hits for channel"
596 <<
" digits [MeV] "<< pDigitSamples[0]
597 <<
"/" << pDigitSamples[1]
598 <<
"/" << pDigitSamples[2]
599 <<
"/" << pDigitSamples[3]
600 <<
"/" << pDigitSamples[4]
601 <<
"/" << pDigitSamples[5]
602 <<
"/" << pDigitSamples[6]);
603 ATH_MSG_VERBOSE(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
619 ATH_MSG_VERBOSE(
"++ START filling of channels with background either noise+pedestal or overlay");
621 for (
int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) {
623 double* pDigitSamples=pDigitSamplesArray[TMDBchan];
624 int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
628 ATH_MSG_DEBUG(
"(D.) Going now to channel " <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan);
630 <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan
633 <<
" drawer idx: " << drawerIdx
644 <<
" adc/pCb: "<< muRcv_Calib
651 <<
" final calibration factor adc/MeV: "<< mev2ADC_factor);
654 <<
" " << pDigitSamples[0]
655 <<
" " << pDigitSamples[1]
656 <<
" " << pDigitSamples[2]
657 <<
" " << pDigitSamples[3]
658 <<
" " << pDigitSamples[4]
659 <<
" " << pDigitSamples[5]
660 <<
" " << pDigitSamples[6]
661 <<
" [All ZERO if there is no hit in channel.] ");
663 if ( good_bkg[TMDBchan] ) {
673 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{Signal} [adc]: "<< pDigitSamples[js] * mev2ADC_factor <<
" -- Overlay");
674 digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
677 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{PileUp} [adc]: "<< pDigitSamplesRndmArray[TMDBchan][js] <<
" -- Overlay");
678 digitsBuffer[js] += pDigitSamplesRndmArray[TMDBchan][js];
681 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
685 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E_{Signal+PileUp} [adc]: "<< digitsBuffer[js] <<
" -- Overlay");
688 if (
m_rndmEvtOverlay)
ATH_MSG_INFO(
"At least one digit is zero in background file using the stadart path to fill pedestal and noise in digits");
695 <<
" noi " << muRcv_NoiseSigma
696 <<
" ped " << muRcv_Ped
697 <<
" cal " << muRcv_Calib
698 <<
" max " << muRcv_Max);
710 if (pedSim == 0.0) pedSim = 30.;
719 RandGaussQ::shootArray(*rngWrapper,
m_nSamples, Rndm, 0.0, 1.0);
720 RandFlat::shootArray(*rngWrapper, 1, Rndm_dG, 0.0, 1.0);
723 if (sigma_Hfn1 > 0 || sigma_Hfn2) {
729 if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
730 else sigmaSim = sigma_Hfn2;
732 sigmaSim = muRcv_NoiseSigma;
739 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E [MeV]: "<< pDigitSamples[js]);
740 digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
741 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E [adc]: "<< digitsBuffer[js]);
744 digitsBuffer[js] += pedSim;
745 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding pedestal "<< pedSim <<
"-> E [adc]: "<< digitsBuffer[js]);
749 digitsBuffer[js] += sigmaSim * Rndm[js];
750 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding noise "<< sigmaSim * Rndm[js] <<
"-> E [adc]: "<< digitsBuffer[js]);
754 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
763 bool chanIsBad =
false;
767 chanIsBad =
status.isBad();
772 digitsBuffer[js] = 255;
774 ATH_MSG_VERBOSE(
"(D.03) Masking Channel: "<<
ros <<
'/' <<
drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
776 ATH_MSG_VERBOSE(
"(D.03) Good Channel : "<<
ros <<
'/' <<
drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
780 std::unique_ptr<TileDigits> muonReceiverDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
781 ATH_MSG_VERBOSE(
"++ Create a TileRawChannelObject object and set it into a container " );
783 ATH_CHECK( muRcvDigitsContainer->push_back(std::move(muonReceiverDigits)) );
784 ATH_CHECK( muRcvRawChannelContainer->push_back(muRcvRawChannel) );
787 <<
" Digitized pulse [ADC] "<< digitsBuffer[0]
788 <<
"/" << digitsBuffer[1]
789 <<
"/" << digitsBuffer[2]
790 <<
"/" << digitsBuffer[3]
791 <<
"/" << digitsBuffer[4]
792 <<
"/" << digitsBuffer[5]
793 <<
"/" << digitsBuffer[6] );
795 <<
" E [ADC]: "<< muRcvRawChannel->
amplitude()
796 <<
" Time [ns]: "<< muRcvRawChannel->
time()
797 <<
" Qf: "<< muRcvRawChannel->
quality() );
807 ATH_MSG_VERBOSE (
"(A.05) Send to event store all collected objects " );
813 ATH_CHECK( muRcvRawChannelCnt.
record(std::move(muRcvRawChannelContainer)) );
817 return StatusCode::SUCCESS;
825 ATH_MSG_INFO(
"TilePulseForTileMuonReceiver finalized successfully");
826 return StatusCode::SUCCESS;
def retrieve(aClass, aKey=None)
JetConstituentVector::iterator iterator
SG::ReadCondHandleKey< TileBadChannels > m_badChannelsKey
Name of TileBadChannels in condition store.
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.
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
ServiceHandle< PileUpMergeSvc > m_mergeSvc
float getHfn2(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
Gaudi::Property< bool > m_maskBadChannels
int NdigitSamples() const
Returns the number of sammples (digits) per event.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts
Condition object to keep and provide Tile sample noise.
SG::WriteHandleKey< TileRawChannelContainer > m_muRcvRawChannelContainerKey
int pmt(const Identifier &id) const
const std::vector< double > & MuRcvFullShape() const
Return full Muon Receiver shape vector.
float round(const float toRound, const unsigned int decimals)
Class holding bad channel problems.
int side(const Identifier &id) const
int sample(const Identifier &id) const
int m_adcMax
ADC saturation value.
bool msgLvl(const MSG::Level lvl) const
SG::WriteHandleKey< TileDigitsContainer > m_muRcvDigitsContainerKey
float getHfn(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
int tower(const Identifier &id) const
IdContext drawer_context(void) const
idContext for drawers
#define ATH_MSG_VERBOSE(x)
const std::string & key() const
Return the StoreGate ID for the referenced object.
int m_binTime0
Index of time=0 bin for pulse shape.
SG::ReadCondHandleKey< TileSamplingFraction > m_samplingFractionKey
Name of TileSamplingFraction in condition store.
double MuRcvCalib(const Identifier &) const
Returns the factor which converts amplitude in pCb to ADC counts in Muon Receiver.
float time(int ind=0) const
int m_iTrig
Index of the triggering time slice.
int m_nSamples
Number of time slices for each channel.
int channel(const HWIdentifier &id) const
extract channel field from HW identifier
const ServiceHandle< StoreGateSvc > & detStore() const
The standard StoreGateSvc/DetectorStore Returns (kind of) a pointer to the StoreGateSvc.
virtual StatusCode initialize() override
initialize method
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
std::string m_inputDigitContainerName
float quality(int ind=0) const
float calibrateChannel(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float amplitude, TileRawChannelUnit::UNIT rawDataUnitIn, TileRawChannelUnit::UNIT rawDataUnitOut) const
Calibrate a Tile channel.
Handle class for recording to StoreGate.
SG::ReadCondHandleKey< TilePulse > m_pulseShapeKey
Name of TilePulseShape in condition store.
int ItrigSample() const
The sample at which the pulse should ideally peak.
virtual ~TilePulseForTileMuonReceiver()
SG::ReadCondHandleKey< TileSampleNoise > m_sampleNoiseKey
Name of TileSampleNoise in condition store.
Gaudi::Property< std::string > m_randomStreamName
Random Stream Name.
int MuRcvTime0Bin() const
Return index of in-time bin in Muon Receiver shape.
float amplitude(int ind=0) const
SG::ReadHandleKey< TileHitContainer > m_hitContainerKey
const_pointer_type retrieve()
TilePulseForTileMuonReceiver(const std::string &name, ISvcLocator *pSvcLocator)
float getHfn1(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
virtual IdentifierHash get_hash(const HWIdentifier &id) const
create hash id from compact ADC id without error checking
::StatusCode StatusCode
StatusCode definition for legacy code.
double MuRcvMax(const Identifier &) const
Returns max possible value (in ADC counts) for Muon Receiver adcs.
int MuRcvBinsPerX() const
Return number of Muon Receiver bins per bunch-crossing.
Helper for holding non-const raw data prior to recording in SG.
double MuRcvNoiseSigma(const Identifier &) const
Returns the sigma (in ADC counts) of Noise in Muon Receiver adcs.
float getHfnNorm(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
virtual bool isValid() override final
Can the handle be successfully dereferenced?
ToolHandle< TileRawChannelBuilderMF > m_MuRcvBuildTool
double m_timeStep
Time step in pulse shape: 25.0 / nBinsPerX.
HWIdentifier drawer_id(int frag) const
ROS HWIdentifer.
A wrapper class for event-slot-local random engines.
Condition object to keep Tile channel and ADC status.
virtual StatusCode execute() override
execute method
virtual StatusCode finalize() override
finalize method
Helpers for checking error return status codes and reporting errors.
StatusCode initialize(bool used=true)
double MuRcvPed(const Identifier &) const
Returns the pedestal (in ADC counts) for Muon Receiver adcs.
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
int m_nShape
Number of bins in pulse shape.
const TileBchStatus & getAdcStatus(const HWIdentifier adc_id) const
Return Tile ADC status.
int MuRcvNBins() const
Return number of bins in Muon Receiver shape.
SG::ReadHandleKey< TileDigitsContainer > m_inputDigitContainerKey
HWIdentifier adc_id(int ros, int drawer, int channel, int adc) const
adc HWIdentifer
Gaudi::Property< bool > m_tileNoise
double ThresholdDigits(int) const
Return the threshold value for good TileDigits (cut applied to in-time digit only)
Helper for holding non-const raw data prior to recording in SG.
const TileInfo * m_tileInfo
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.
Gaudi::Property< bool > m_tilePedestal
std::string to_string(const Identifier &id, int level=0) const
#define ATH_MSG_WARNING(x)
bool connected(int ros, int drawer) const
std::vector< double > m_shapeMuonReceiver
Muon receiver pulse shape.
int m_nBinsPerX
Number of bins per bunch crossing in pulse shape.
ServiceHandle< IAthRNGSvc > m_rndmSvc
Random number service to use.
Gaudi::Property< bool > m_onlyUseContainerName
bool getPulseShapeYDY(unsigned int drawerIdx, unsigned int channel, unsigned int adc, float time, float &y, float &dy) const
Condition object to keep and provide Tile pulse shape.
const TileHWID * m_tileHWID
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
std::string to_string(const HWIdentifier &id, int level=0) const
extract all fields from HW identifier HWIdentifier get_all_fields ( const HWIdentifier & id,...
Handle class for reading from StoreGate.
double m_tileThresh
Actual threshold value.
Gaudi::Property< bool > m_integerDigits
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Gaudi::Property< std::string > m_infoName
float getPed(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
This class saves the "context" of an expanded identifier (ExpandedIdentifier) for compact or hash ver...
int ADCmax() const
Returns the maximum ADC output (10 bits --> 1023)
Gaudi::Property< bool > m_rndmEvtOverlay
HWIdentifier s2h_channel_id(const Identifier &id) const
Gaudi::Property< bool > m_useCoolPulseShapes
const TileCablingService * m_cablingService
TileCabling instance.