23#include "CaloDetDescr/CaloDetDescrElement.h"
42#include <CLHEP/Random/Randomize.h>
43#include <CLHEP/Units/SystemOfUnits.h>
48#define USE_TILECELLS_DATAPOOL
51#ifdef USE_TILECELLS_DATAPOOL
52#define NEWTILECELL tileCellsP.nextElementPtr
54#define NEWTILECELL new TileCell
58using CLHEP::RandGaussQ;
72 const IInterface* parent)
73 : base_class(
type, name, parent)
86 declareInterface<TileCellBuilderFromHit>(
this );
134 if (detStore()->retrieve(
m_mbtsMgr).isFailure()) {
135 ATH_MSG_WARNING(
"Unable to retrieve MbtsDetDescrManager from DetectorStore" );
185 ATH_MSG_INFO(
"TileCellBuilderFromHit initialization completed" );
187 return StatusCode::SUCCESS;
194 return StatusCode::SUCCESS;
198 const EventContext& ctx)
const
220 std::unique_ptr<TileCellContainer> MBTSCells;
225 std::unique_ptr<TileCellContainer> E4prCells;
231 SelectAllObject<TileHitContainer>::const_iterator begin = selAll.
begin();
232 SelectAllObject<TileHitContainer>::const_iterator end = selAll.
end();
237 caloNoise = noiseH.
cptr();
242 build (caloNoise, drawerEvtStatus, begin, end, theCellContainer,
243 MBTSCells.get(), E4prCells.get(), *samplingFraction);
258 if (theCellContainer->
hasCalo(caloNum)) {
279 unsigned int flag = 0;
281 int drConsecMaxMax = 0;
284 for (
int p = 1; p < 5; ++p) {
295 for (
int d = 0; d < 64; ++d) {
296 if (evt[d].nChannels == 0) {
300 }
else if (evt[d].nMaskedChannels >= evt[d].nChannels) {
305 if (drConsec > drConsecMax) {
306 drConsecMax = drConsec;
307 if (drConsecMax > drConsecMaxMax) {
308 drConsecMaxMax = drConsecMax;
309 drConsecNum = ((p - 1) << 6) | (d - drConsec);
316 if (evt[d].nBadQuality) ++hasBadQ;
317 if (evt[d].nOverflow) ++hasOver;
318 if (evt[d].nUnderflow) ++hasUnder;
319 if (evt[d].nSomeSignal) ++hasSig;
322 if (drConsec != 0 && drConsecMax < 64) {
323 for (
int d = 0; d < drConsecMax; ++d) {
324 if (evt[d].nChannels == 0 || evt[d].nMaskedChannels >= evt[d].nChannels) {
330 if (drConsec > drConsecMax) {
331 drConsecMax = drConsec;
344 if (hasBadQ > 15) fl |= 0x00001000;
345 if (hasOver) fl |= 0x00000100;
346 if (hasUnder) fl |= 0x00000010;
347 if (hasSig) fl |= 0x00000001;
349#ifdef ALLOW_DEBUG_COUT
350 std::cout<<
"partition "<<p<<
" drAbsent "<<drAbsent<<
" drMasked "<<drMasked<<
" drConsec "<<drConsecMax
351 <<
" hasBadQ "<<hasBadQ<<
" hasOver "<<hasOver<<
" hasUnder "<<hasUnder<<
" hasSig "<<hasSig<<std::endl;
353 flag |= fl << (p - 1);
357 flag |= (std::min(15, drConsecMaxMax) << 16);
364 flag |= (drConsecNum << 20);
365#ifdef ALLOW_DEBUG_COUT
366 std::cout<<
"warning in partition " << (drConsecNum>>6)+1 <<
" for modules "
367 <<(drConsecNum)%64 <<
" - " <<(drConsecNum+drConsecMaxMax-1)%64 <<std::endl;
371#ifdef ALLOW_DEBUG_COUT
372 std::cout<<
"partition flag 0x0"<<std::hex<<flag<<std::dec<<
" error "<<
error<<std::endl;
384 ATH_MSG_DEBUG(
" set eventInfo for Tile for this event to 0x" << MSG::hex << flag << MSG::dec );
399 ATH_MSG_WARNING(
" cannot retrieve EventInfo, will not set Tile information " );
403 ATH_MSG_DEBUG(
"TileCellBuilderFromHit execution completed." );
405 return StatusCode::SUCCESS;
410 ,
float ener,
float time,
unsigned char iqual,
unsigned char qbit)
const {
416 switch (correction) {
432 int ros,
int drawer,
bool count_over
433 ,
bool good_time,
bool good_ener,
bool overflow,
bool underflow,
bool overfit)
const {
435 ++drawerEvtStatus[ros][drawer].nChannels;
438 if (overflow) ++drawerEvtStatus[ros][drawer].nOverflow;
439 if (underflow) ++drawerEvtStatus[ros][drawer].nUnderflow;
441#ifdef ALLOW_DEBUG_COUT
442 if (overflow) std::cout <<
"channel with overflow " << ((count_over)?
"":
"MBTS") << std::endl;
443 if (underflow) std::cout <<
"channel with underflow " << ((count_over)?
"":
"MBTS") << std::endl;
444 if (overfit) std::cout <<
"channel with corrected overflow " << ((count_over)?
"":
"MBTS") << std::endl;
455 ++drawerEvtStatus[ros][drawer].nSomeSignal;
465 TileCell* pCell,
const EventContext& ctx)
const
472 int channel =
m_tileHWID->channel(channel_id);
474 int gain = pCell->
gain1();
481 ++drawerEvtStatus[ros][drawer].nBadQuality;
491 ++drawerEvtStatus[ros][drawer].nMaskedChannels;
520 TileCell* pCell,
bool single_PMT_C10,
bool Ecell,
521 const EventContext& ctx)
const {
528 int gain1 = pCell->
gain1();
541 ++drawerEvtStatus[ros1][drawer1].nBadQuality;
545 bad1 = (gain1 < 0) || chStatus1.
isBad();
554 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
575 int gain2 = pCell->
gain2();
588 ++drawerEvtStatus[ros2][drawer2].nBadQuality;
592 bad2 = (gain2 < 0) || chStatus2.
isBad();
596 if (single_PMT_C10) {
602#ifdef ALLOW_DEBUG_COUT
606 << drawer2+1 <<
" status " << chan1 <<
"/" << chan2 <<
" "
607 << (chStatus1.
isBad()?
"bad":
"good") <<
"/"
608 << (chStatus2.
isBad()?
"bad":
"good") <<
"/"
609 << ((
m_RUN2plus)?
" RUN2+ cabling":
"RUN1 cabling")
615#ifdef ALLOW_DEBUG_COUT
617 std::cout <<
"Ene of chan1 was " << pCell->
ene1() <<
" changing to half of " << pCell->
ene2()
618 <<
" and setting bad1=true" << std::endl;
624 --drawerEvtStatus[ros1][drawer1].nMaskedChannels;
628#ifdef ALLOW_DEBUG_COUT
630 std::cout <<
"Ene of chan2 was " << pCell->
ene2() <<
" changing to half of " << pCell->
ene1()
631 <<
" and setting bad2=true" << std::endl;
637 --drawerEvtStatus[ros2][drawer2].nMaskedChannels;
643 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
644 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
659 }
else if (bad1 && !bad2) {
661 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
663 float ene2 = pCell->
ene2();
664 pCell->
setEnergy(ene2, ene2, gain2, gain2);
668 uint8_t qual2 = pCell->
qual2();
671 uint8_t qual1 = qual2 + (gain1 - gain2);
672 if (qual1 >
m_qualityCut && gain1 > gain2) qual1 = qual2 - (gain1 - gain2);
682 }
else if (!bad1 && bad2) {
684 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
686 float ene1 = pCell->
ene1();
687 pCell->
setEnergy(ene1, ene1, gain1, gain1);
691 uint8_t qual1 = pCell->
qual1();
694 uint8_t qual2 = qual1 + (gain2 - gain1);
695 if (qual2 >
m_qualityCut && gain2 > gain1) qual2 = qual1 - (gain2 - gain1);
729 return single_PMT_C10;
733template<
class ITERATOR,
class COLLECTION>
736 const ITERATOR & begin,
const ITERATOR & end, COLLECTION * coll,
742 const EventContext& ctx = Gaudi::Hive::currentContext();
744 wrapper->
setSeed (rngname, ctx);
745 CLHEP::HepRandomEngine* engine = wrapper->
getEngine (ctx);
757 float eCellTot = 0.0;
758 float eMBTSTot = 0.0;
759 float eE4prTot = 0.0;
760 bool EBdrawerPresent[128];
761 memset(EBdrawerPresent, 0,
sizeof(EBdrawerPresent));
762#ifdef USE_TILECELLS_DATAPOOL
770 bool overflow =
false;
771 bool underflow =
false;
772 bool overfit =
false;
775 std::vector<TileCell*> allCells (
m_tileID->cell_hash_max(),
nullptr);
776 std::vector<TileCell*> MBTSVec;
780 std::vector<TileCell*> E4prVec;
785 for (ITERATOR hitItr = begin; hitItr != end; ++hitItr) {
787 const TileHit* pHit = (*hitItr);
795 int hitsize = pHit->
size();
796 for (
int ind = 0; ind < hitsize; ++ind) {
797 float tim = pHit->
time(ind);
799 float ene = pHit->
energy(ind);
805 float ener = ener_min;
809 bool good_time =
false;
810 bool non_zero_time = (ehit!=0.0);
816 int channel =
m_tileHWID->channel(channel_id);
822 if (ener > 10000. *
MeV) {
825 good_time = (fabs(time) < 25.);
828 bool MBTS =
false, E4pr =
false, E1_CELL =
false;
853 cell_id =
m_tileID->cell_id(cell_id);
866 else if (tower == 0 && sample ==
TileID::SAMP_D && pmt == 1) ros = 2;
880 unsigned char iqual =
iquality(qual);
882 unsigned char qbit =
qbits(drawerEvtStatus,
884 , overflow, underflow, overfit);
892 pCell->
set(NULL, cell_id);
900 if (msgLvl(MSG::VERBOSE)) {
901 msg(MSG::VERBOSE) <<
" E4' cell_id=" <<
m_tileTBID->to_string(cell_id)
902 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
906 <<
" iqual= " << (int) iqual
907 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
910 if (E4prVec[
index]) {
911 msg(MSG::WARNING) <<
" double E4' cell_id=" <<
m_tileTBID->to_string(cell_id)
912 <<
" ignoring previous value" <<
endmsg;
914 E4prVec[
index] = pCell;
923 ener /= emScale->calibrateChannel(drawerIdx, channel, gain, 1.,
928 unsigned char iqual =
iquality(qual);
930 unsigned char qbit =
qbits(drawerEvtStatus,
931 ros, drawer,
false, (good_time && non_zero_time)
948 if (msgLvl(MSG::VERBOSE)) {
949 msg(MSG::VERBOSE) <<
" MBTS cell_id=" <<
m_tileTBID->to_string(cell_id)
950 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
954 <<
" iqual= " << (int) iqual
955 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
958 if (MBTSVec[
index]) {
959 msg(MSG::WARNING) <<
" double MBTS cell_id=" <<
m_tileTBID->to_string(cell_id)
960 <<
" ignoring previous value" <<
endmsg;
962 MBTSVec[
index] = pCell;
968 unsigned char iqual =
iquality(qual);
970 unsigned char qbit =
qbits(drawerEvtStatus, ros, drawer,
true, non_zero_time,
975 int drawer2 =
m_cabling->E1_merged_with_run2plus(ros,drawer);
978 int index2 =
m_tileID->cell_hash(cell_id2);
981 allCells[index2] = pCell2;
983 pCell2->
set(dde2, cell_id2);
987 correctCell(pCell2, 1, pmt2, gain, ener, time, iqual, qbit);
990 <<
" split into " <<
m_tileID->to_string(cell_id2));
997 correctCell(pCell, 2, pmt, gain, ener, time, iqual, qbit);
1002 pCell->
set(dde, cell_id);
1004 correctCell(pCell, 1, pmt, gain, ener, time, iqual, qbit);
1007 if (msgLvl(MSG::VERBOSE)) {
1008 float calib1 = (ehit != 0.0) ? ener / ehit : 0.0;
1009 msg(MSG::VERBOSE) <<
" cell_id=" <<
m_tileID->to_string(cell_id, -2)
1010 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
1011 <<
" calib=" << calib1
1012 <<
" nCell=" << nCell
1013 <<
" energy=" << ener <<
" (" << pCell->
energy() <<
", " << pCell->
eneDiff() <<
")" <<
endmsg;
1015 msg(MSG::VERBOSE) <<
" ehit= " << ehit
1016 <<
" time= " << time
1017 <<
" iqual= " << (int) iqual
1018 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
1025 unsigned char iqual = 0;
1043 int side =
m_tileID->side(cell_id);
1044 int module =
m_tileID->module(cell_id);
1045 int sample =
m_tileID->sample(cell_id);
1050 bool single_PMT = Ecell || single_PMT_C10;
1054 if ( ! missing_D4 ) {
1057 if (!single_PMT) ++nTwo;
1060 pCell->
set(dde, cell_id);
1074 if (
maskBadChannels (drawerEvtStatus, pCell, single_PMT_C10, Ecell, ctx))
1076 <<
" bad channels masked, new energy=" << pCell->
energy() );
1078 bool bad1=pCell->
badch1();
1079 bool bad2=pCell->
badch2();
1081 if (! (bad1 && bad2) ) {
1088 if (bad1 || bad2 || single_PMT) {
1090 float ene = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1093 <<
" sigma " << noiseSigma <<
" noise " << ene );
1101 int gain1=pCell->
gain1();
1102 int gain2=pCell->
gain2();
1106 float ene = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1108 <<
" sigma " << noiseSigma <<
" noise " << ene );
1117 noiseSigma *= M_SQRT1_2;
1118 float ene1 = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1119 float ene2 = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1122 <<
" sigma " << noiseSigma*M_SQRT2 <<
" noise " << ene1+ene2 <<
" noise1 " << ene1 <<
" noise2 " << ene2 );
1129 coll->push_back(pCell);
1130 allCells[
index] = 0;
1137 for (
int side = 0; side <
NSIDE; ++side) {
1144 bool merged_MBTS = (
eta == 1 && (
phi&1) == 1 &&
m_RUN2);
1146 if (!pCell && !merged_MBTS) {
1162 <<
" bad channel masked, new energy=" << pCell->
energy() );
1194 <<
" bad channel masked, new energy=" << pCell->
energy() );
1202 if (msgLvl(MSG::DEBUG)) {
1203 msg(MSG::DEBUG) <<
" nChan=" << nChan
1204 <<
" RawChSum=" << eCh
1205 <<
" nCell=" << nCell
1207 <<
" nFake=" << nFake
1208 <<
" eneTot=" << eCellTot;
1211 msg(MSG::DEBUG) <<
" nMBTS=" << nMBTS
1212 <<
" eMBTS=" << eMBTSTot;
1214 msg(MSG::DEBUG) <<
" nE4pr=" << nE4pr
1215 <<
" eE4pr=" << eE4prTot;
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
An interface for getting the name of a class as a string.
Helpers for checking error return status codes and reporting errors.
SelectAllObjectMT< DCC, OBJECT > SelectAllObject
Handle class for reading from StoreGate.
Handle class for recording to StoreGate.
static const InterfaceID IID_ITileCellBuilderFromHit("TileCellBuilderFromHit", 1, 0)
TileContainer< TileCell > TileCellContainer
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.
Container class for CaloCell.
bool hasCalo(const CaloCell_ID::SUBCALO caloNum) const
tell wether it has been filled with cells (maybe none) of a given calo
void setHasCalo(const CaloCell_ID::SUBCALO caloNum)
set which calo has been filled.
CaloCell_Base_ID::SUBCALO SUBCALO
double energy() const
get energy (data member)
const CaloDetDescrElement * caloDDE() const
get pointer to CaloDetDescrElement (data member)
void set(const CaloDetDescrElement *caloDDE, const Identifier &ID)
Fast method to change the identity of a cell.
CaloGain::CaloGain gain() const
get gain (data member )
Identifier ID() const
get ID (from cached data member) non-virtual and inline for fast access
This class groups all DetDescr information related to a CaloCell.
Identifier identify() const override final
cell identifier
IdentifierHash onl2() const
cell online identifier 2
IdentifierHash onl1() const
cell online identifier 1
float getEffectiveSigma(const Identifier id, const int gain, const float energy) const
static std::string name()
Return the name of class T as a string.
a typed memory pool that saves time spent allocation small object.
value_type push_back(value_type pElem)
This is a "hash" representation of an Identifier.
const_pointer_type cptr()
virtual bool isValid() override final
Can the handle be successfully dereferenced?
const_pointer_type cptr()
Dereference the pointer.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
Class holding bad channel problems.
static unsigned int getDrawerIdx(unsigned int ros, unsigned int drawer)
Returns a drawer hash.
const MbtsDetDescrManager * m_mbtsMgr
Pointer to MbtsDetDescrManager.
unsigned char iquality(float qual) const
int m_qualityCut
cut on channel quality (set energy to m_zeroEnergy for them)
bool maskBadChannel(TileDrawerEvtStatusArray &drawerEvtStatus, TileCell *pCell, const EventContext &ctx) const
method to check if channels are good or bad.
SG::ReadHandleKey< xAOD::EventInfo > m_eventInfoKey
static const InterfaceID & interfaceID()
float m_zeroEnergy
energy to store in every PMT if both PMT are bad
bool maskBadChannels(TileDrawerEvtStatusArray &drawerEvtStatus, TileCell *pCell, bool single_PMT_C10, bool Ecell, const EventContext &ctx) const
TileCellBuilderFromHit(const std::string &type, const std::string &name, const IInterface *parent)
Contructor.
virtual StatusCode initialize() override
Initializer.
TileDrawerEvtStatus TileDrawerEvtStatusArray[5][64]
status of every drawer
float m_maxTime
maximum time for the PMTs in the cels
const TileTBID * m_tileTBID
Pointer to TileTBID.
virtual StatusCode process(CaloCellContainer *theCellContainer, const EventContext &ctx) const override
method to process all raw channels and store them in container
static const int NCELLMBTS
unsigned char qbits(TileDrawerEvtStatusArray &drawerEvtStatus, int ros, int drawer, bool count_over, bool good_time, bool good_ener, bool overflow, bool underflow, bool good_overflowfit) const
method to compute the cell quality bits
SG::ReadCondHandleKey< TileEMScale > m_emScaleKey
Name of TileEMScale in condition store.
const TileDetDescrManager * m_tileMgr
Pointer to TileDetDescrManager.
SG::ReadHandleKey< TileHitContainer > m_hitContainerKey
SG::ReadCondHandleKey< TileSamplingFraction > m_samplingFractionKey
Name of TileSamplingFraction in condition store.
void build(const CaloNoise *caloNoise, TileDrawerEvtStatusArray &drawerEvtStatus, const ITERATOR &begin, const ITERATOR &end, COLLECTION *coll, TileCellContainer *MBTSCells, TileCellContainer *E4prCells, const TileSamplingFraction *samplingFraction) const
static const int NCELLE4PR
const TileID * m_tileID
Pointer to TileID.
float m_minTime
minimum time for the PMTs in the cels
void correctCell(TileCell *pCell, int correction, int pmt, int gain, float ener, float time, unsigned char iqual, unsigned char qbit) const
Compute calibrated energy, time, etc.
virtual StatusCode finalize() override
const TileHWID * m_tileHWID
Pointer to TileHWID.
const TileCablingService * m_cabling
Pointer to TileCabling.
bool m_maskBadChannels
if true=> bad channels are masked
SG::WriteHandleKey< TileCellContainer > m_E4prContainerKey
virtual ~TileCellBuilderFromHit()
Destructor.
TileFragHash::TYPE m_RChType
Type of TileRawChannels (Fit, OF2, etc.).
float m_eneForTimeCutMBTS
similar cut for MBTS in pC
int e4pr_index(int phi) const
ToolHandle< ITileBadChanTool > m_tileBadChanTool
SG::ReadCondHandleKey< CaloNoise > m_caloNoiseKey
float m_noiseSigma
cell electronic noise if CaloNoise is switched off
int mbts_index(int side, int phi, int eta) const
ServiceHandle< TileCablingSvc > m_cablingSvc
Name of Tile cabling service.
ServiceHandle< IAthRNGSvc > m_rndmSvc
< Random number service to use
float m_eneForTimeCut
keep time for channels with energy above cut
SG::WriteHandleKey< TileCellContainer > m_MBTSContainerKey
uint8_t qual1(void) const
get quality of first PMT (data member)
void addEnergy(float e, int pmt, int gain)
set energy and gain for one PMT
float time1(void) const
get time of first PMT
void setEnergy_nonvirt(float e1, float e2, int gain1, int gain2)
void setQual2(unsigned char qual)
set quality of second PMT
void setTime_nonvirt(float t)
float eneDiff(void) const
all get methods
virtual void setEnergy(float ene) override final
set total energy, reset eneDiff to zero (final override of CaloCell method)
int gain2(void) const
get gain of second PMT
bool badch1(void) const
check if first PMT is in bad channel list and masked
uint8_t qbit2(void) const
get quality bits of second PMT (data member)
int gain1(void) const
get gain of first PMT
uint8_t qual2(void) const
get quality of second PMT (data member)
void setQbit1(unsigned char qbit)
set quality bits of first PMT
void setQbit2(unsigned char qbit)
set quality bits of second PMT
void setQuality(unsigned char qual, unsigned char qbit, int pmt)
set quality value and quality bits for one PMT (TileCell specific overloads)
void setQual1(unsigned char qual)
set quality of first PMT
float ene1(void) const
get energy of first PMT
virtual void setTime(float t) override final
set cell time, reset timeDiff
bool badch2(void) const
check if second PMT is in bad channel list and masked
float time2(void) const
get time of second PMT
uint8_t qbit1(void) const
get quality bits of first PMT (data member)
float ene2(void) const
get energy of second PMT
This class keep detailed status info about one drawer in a given event.
Hash table for Tile fragments (==drawers ==collections in StoreGate).
float time(int ind=0) const
Return time of ind-th sub-hit.
float energy(int ind=0) const
Return energy of ind-th sub-hit.
Identifier identify(void) const
Return logical ID of the pmt.
int size(void) const
Return length of energy/time vectors.
Condition object to keep and provide Tile Calorimeter sampling fraction and number of photoelectrons.
float getSamplingFraction(unsigned int drawerIdx, unsigned int channel) const
Return Tile Calorimeter sampling fraction.
@ Tile
The Tile calorimeter.
EventFlagErrorState
States that a given sub-detector could be in.
@ Warning
The sub-detector issued a warning.
@ NotSet
The flag was not set to anything.
@ Error
The sub-detector issued an error.
@ VIEW_ELEMENTS
this data object is a view, it does not own its elmts