|
ATLAS Offline Software
|
Go to the documentation of this file.
59 #include <CLHEP/Random/Randomize.h>
60 #include <CLHEP/Units/SystemOfUnits.h>
67 using CLHEP::RandGaussQ;
68 using CLHEP::RandFlat;
80 , m_cablingService(nullptr)
119 ATH_MSG_INFO(
"TilePulseForTileMuonReceiver should not be used for RUN1 simulations");
120 return StatusCode::SUCCESS;
122 ATH_MSG_INFO(
"Initializing TilePulseForTileMuonReceiver");
139 <<
" Triggering tile slice: " <<
m_iTrig
140 <<
" ADC saturation value: " <<
m_adcMax
155 <<
" Triggering tile sample " <<
m_iTrig);
183 ATH_MSG_INFO(
"Pileup and/or noise added by overlaying digits of random events");
187 ATH_MSG_INFO(
"PileUpMergeSvc successfully initialized");
191 ATH_MSG_VERBOSE(
"TilePulseForTileMuonReceiver initialization completed");
192 return StatusCode::SUCCESS;
200 ATH_MSG_VERBOSE(
"ATT: RUN1 settings TilePulseForTileMuonReceiver will end now" );
201 return StatusCode::SUCCESS;
206 const EventContext& ctx = Gaudi::Hive::currentContext();
215 int EBchan[
nEBchan]={17,16,37,38,3,2};
217 int LBchan[
nLBchan]={0,13,14,25,24,41,44,39,40};
219 #if (nEBchan > nLBchan)
220 double pDigitSamplesArray[
nEBchan][7];
221 double pDigitSamplesRndmArray[
nEBchan][7];
223 double pDigitSamplesArray[
nLBchan][7];
224 double pDigitSamplesRndmArray[
nLBchan][7];
237 double sigma_Hfn1 = 0.;
238 double sigma_Hfn2 = 0.;
239 double sigma_Norm = 0.;
240 double sigmaSim(0.0);
244 double muRcv_NoiseSigma;
256 badChannels = *badChannelsHandle;
270 sampleNoise = sampleNoiseHandle.
retrieve();
285 auto muRcvDigitsContainer = std::make_unique<TileMutableDigitsContainer>(
true,
288 ATH_CHECK( muRcvDigitsContainer->status() );
292 auto muRcvRawChannelContainer = std::make_unique<TileMutableRawChannelContainer>(
true,
296 ATH_CHECK( muRcvRawChannelContainer->status() );
302 std::unique_ptr<TileMutableDigitsContainer> backgroundDigitContainer{};
306 ATH_MSG_DEBUG(
"Prepare background container for MC Overlay procedure");
308 backgroundDigitContainer = std::make_unique<TileMutableDigitsContainer>(
true,
311 ATH_CHECK( backgroundDigitContainer->status() );
315 TimedDigitContList digitContList;
319 if (digitContList.size() == 0) {
321 return StatusCode::SUCCESS;
325 for (
const auto* digitCollection : *(iTzeroDigitCont->second)) {
326 for (
const auto*
digit : *digitCollection) {
327 auto pDigits = std::make_unique<TileDigits>(*
digit);
328 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
333 if (tileDigitsContainerHandle.
isValid()) {
334 for (
const auto* digitCollection : *tileDigitsContainerHandle) {
335 for (
const auto*
digit : *digitCollection) {
336 auto pDigits = std::make_unique<TileDigits>(*
digit);
337 ATH_CHECK(backgroundDigitContainer->push_back(std::move(pDigits)));
341 ATH_MSG_ERROR(
"ReadHandle to Background Digits is invalid.");
342 return StatusCode::FAILURE;
346 collItrRndm = backgroundDigitContainer->begin();
347 lastCollRndm = backgroundDigitContainer->end();
356 std::vector<float> digitsBuffer_rndm(
m_nSamples);
357 std::vector<bool> good_bkg( 9 ,
false );
381 ATH_MSG_VERBOSE(
"(A.00) Looping over all collections for TMDB in the HIT container");
382 memset(pDigitSamplesArray, 0,
sizeof(pDigitSamplesArray));
403 memset(pDigitSamplesRndmArray, 0,
sizeof(pDigitSamplesRndmArray));
409 if (hitCollection->identify() != bkgDigitCollection->
identify()) {
410 ATH_MSG_ERROR (
"Frag IDs for hit collection and digits overlay collection do not match "
411 << MSG::hex << hitCollection->identify() <<
" != " << bkgDigitCollection->
identify()
413 return StatusCode::FAILURE;
416 ATH_MSG_DEBUG(
"Prepare buffer (digitsBuffer_rndm) for MC Overlay procdure: pileup digits");
418 for (
const auto* bkgDigit : *bkgDigitCollection) {
419 bool good_channel =
true;
425 digitsBuffer_rndm = (*bkgDigit).samples();
427 int nsamp_rndm = digitsBuffer_rndm.size();
431 for (
int js=nsamp_rndm; js<
m_nSamples; ++js) {
432 digitsBuffer_rndm[js] = digitsBuffer_rndm[js-1];
438 pDigitSamplesRndmArray[
channel][j] = digitsBuffer_rndm[j];
441 if (pDigitSamplesRndmArray[
channel][j]==0) good_channel =
false;
443 good_bkg[
channel] = good_channel;
447 for (
int j=0; j< (
int) digitsBuffer_rndm.size(); j++)
msg(
MSG::VERBOSE) << digitsBuffer_rndm[j] <<
" | ";
460 if ( hitCollection->empty() )
ATH_MSG_DEBUG(
"-- No hits in this drawer! Filling channels with either noise and pedestal or MC pileup overlay. --");
462 for (
const TileHit* tile_hit : *hitCollection) {
474 ATH_MSG_VERBOSE(
"(B.00) ++ Iterate over all the D layer channels with hits");
484 TMDBchan = 1 -
m_tileID->
pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
486 TMDBchan =
m_tileID->
pmt(pmt_id) + ((tower>9) ? (tower - 10) : 4);
488 TILEchan=EBchan[TMDBchan];
496 TMDBchan = 1 -
m_tileID->
pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
498 TMDBchan =
m_tileID->
pmt(pmt_id) + ((tower<7) ? (tower-1) : 7);
501 TILEchan=LBchan[TMDBchan];
504 double* pDigitSamples = pDigitSamplesArray[TMDBchan];
509 ATH_MSG_VERBOSE(
"(B.01) Correct pmt being transported in XXchan[]: "<<TMDBchan<<
" "<<TILEchan<<
"=?"
521 hit_calib =
std::round(hit_calib * 1000) / 1000;
530 int n_hits = tile_hit->size();
534 for (
int ihit = 0; ihit < n_hits; ++ihit) {
536 ATH_MSG_VERBOSE(
"(C.00) ++ Iterating over the hits of channel " << TILEchan <<
": hit " << ihit <<
"/"<< n_hits);
538 double e_hit = tile_hit->energy(ihit);
539 double e_pmt = e_hit * hit_calib;
541 ATH_MSG_VERBOSE(
"(C.01) Energy in scintillator [MeV]: " << e_hit <<
" true cell energy [MeV]: " << e_pmt);
543 double t_hit = tile_hit->time(ihit);
573 pDigitSamples[js] += e_pmt * shape;
577 <<
" Shape wt. = " << shape
578 <<
" Amp = " << pDigitSamples[js] <<
" [MeV]");
593 <<
" Amp = " << pDigitSamples[js]
594 <<
"[MeV] Energy: " << e_pmt <<
" LOGAIN from TileInfo");
600 ATH_MSG_DEBUG(
"(C.04) Went over " << n_hits <<
" hits for channel"
602 <<
" digits [MeV] "<< pDigitSamples[0]
603 <<
"/" << pDigitSamples[1]
604 <<
"/" << pDigitSamples[2]
605 <<
"/" << pDigitSamples[3]
606 <<
"/" << pDigitSamples[4]
607 <<
"/" << pDigitSamples[5]
608 <<
"/" << pDigitSamples[6]);
609 ATH_MSG_VERBOSE(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
625 ATH_MSG_VERBOSE(
"++ START filling of channels with background either noise+pedestal or overlay");
627 for (
int TMDBchan = 0; TMDBchan < upperLim; ++TMDBchan) {
629 double* pDigitSamples=pDigitSamplesArray[TMDBchan];
630 int TILEchan = (eb_ros) ? EBchan[TMDBchan] : LBchan[TMDBchan];
634 ATH_MSG_DEBUG(
"(D.) Going now to channel " <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan);
636 <<
" TMDBchan: " << TMDBchan <<
" TILEchan: " << TILEchan
639 <<
" drawer idx: " << drawerIdx
650 <<
" adc/pCb: "<< muRcv_Calib
657 <<
" final calibration factor adc/MeV: "<< mev2ADC_factor);
660 <<
" " << pDigitSamples[0]
661 <<
" " << pDigitSamples[1]
662 <<
" " << pDigitSamples[2]
663 <<
" " << pDigitSamples[3]
664 <<
" " << pDigitSamples[4]
665 <<
" " << pDigitSamples[5]
666 <<
" " << pDigitSamples[6]
667 <<
" [All ZERO if there is no hit in channel.] ");
669 if ( good_bkg[TMDBchan] ) {
679 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{Signal} [adc]: "<< pDigitSamples[js] * mev2ADC_factor <<
" -- Overlay");
680 digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
683 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E_{PileUp} [adc]: "<< pDigitSamplesRndmArray[TMDBchan][js] <<
" -- Overlay");
684 digitsBuffer[js] += pDigitSamplesRndmArray[TMDBchan][js];
687 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
691 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E_{Signal+PileUp} [adc]: "<< digitsBuffer[js] <<
" -- Overlay");
694 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");
701 <<
" noi " << muRcv_NoiseSigma
702 <<
" ped " << muRcv_Ped
703 <<
" cal " << muRcv_Calib
704 <<
" max " << muRcv_Max);
716 if (pedSim == 0.0) pedSim = 30.;
725 RandGaussQ::shootArray(*rngWrapper,
m_nSamples, Rndm, 0.0, 1.0);
726 RandFlat::shootArray(*rngWrapper, 1, Rndm_dG, 0.0, 1.0);
729 if (sigma_Hfn1 > 0 || sigma_Hfn2) {
735 if (Rndm_dG[0] < sigma_Norm) sigmaSim = sigma_Hfn1;
736 else sigmaSim = sigma_Hfn2;
738 sigmaSim = muRcv_NoiseSigma;
745 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" E [MeV]: "<< pDigitSamples[js]);
746 digitsBuffer[js] = pDigitSamples[js] * mev2ADC_factor;
747 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" calibration [adc/MeV] "<< mev2ADC_factor <<
"-> E [adc]: "<< digitsBuffer[js]);
750 digitsBuffer[js] += pedSim;
751 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding pedestal "<< pedSim <<
"-> E [adc]: "<< digitsBuffer[js]);
755 digitsBuffer[js] += sigmaSim * Rndm[js];
756 ATH_MSG_VERBOSE(
"(D.02.0"<< js+1 <<
") sample "<< js+1 <<
" adding noise "<< sigmaSim * Rndm[js] <<
"-> E [adc]: "<< digitsBuffer[js]);
760 if (digitsBuffer[js] > muRcv_Max) digitsBuffer[js] = muRcv_Max;
769 bool chanIsBad =
false;
773 chanIsBad =
status.isBad();
778 digitsBuffer[js] = 255;
780 ATH_MSG_VERBOSE(
"(D.03) Masking Channel: "<<
ros <<
'/' <<
drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
782 ATH_MSG_VERBOSE(
"(D.03) Good Channel : "<<
ros <<
'/' <<
drawer <<
'/' << TILEchan <<
" ("<< TMDBchan <<
") LowGain" );
786 std::unique_ptr<TileDigits> muonReceiverDigits = std::make_unique<TileDigits>(adc_id, digitsBuffer);
787 ATH_MSG_VERBOSE(
"++ Create a TileRawChannelObject object and set it into a container " );
789 ATH_CHECK( muRcvDigitsContainer->push_back(std::move(muonReceiverDigits)) );
790 ATH_CHECK( muRcvRawChannelContainer->push_back(muRcvRawChannel) );
793 <<
" Digitized pulse [ADC] "<< digitsBuffer[0]
794 <<
"/" << digitsBuffer[1]
795 <<
"/" << digitsBuffer[2]
796 <<
"/" << digitsBuffer[3]
797 <<
"/" << digitsBuffer[4]
798 <<
"/" << digitsBuffer[5]
799 <<
"/" << digitsBuffer[6] );
801 <<
" E [ADC]: "<< muRcvRawChannel->
amplitude()
802 <<
" Time [ns]: "<< muRcvRawChannel->
time()
803 <<
" Qf: "<< muRcvRawChannel->
quality() );
813 ATH_MSG_VERBOSE (
"(A.05) Send to event store all collected objects " );
819 ATH_CHECK( muRcvRawChannelCnt.
record(std::move(muRcvRawChannelContainer)) );
823 return StatusCode::SUCCESS;
831 ATH_MSG_INFO(
"TilePulseForTileMuonReceiver finalized successfully");
832 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.
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()
PileUpMergeSvc * m_mergeSvc
Pointer to PileUpMergeService.
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)
the preferred mechanism to access information from the different event stores in a pileup job.
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
Gaudi::Property< std::string > m_infoName
float getPed(unsigned int drawerIdx, unsigned int channel, unsigned int adc) const
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.
StatusCode retrieveSubEvtsData(const KEY &dataKey, TIMEDDATA &timedData)
retrieve keyed DATA objs for all sub-events and attach a time to them