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;
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)
const {
527 int gain1 = pCell->
gain1();
540 ++drawerEvtStatus[ros1][drawer1].nBadQuality;
544 bad1 = (gain1 < 0) || chStatus1.
isBad();
553 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
574 int gain2 = pCell->
gain2();
587 ++drawerEvtStatus[ros2][drawer2].nBadQuality;
591 bad2 = (gain2 < 0) || chStatus2.
isBad();
595 if (single_PMT_C10) {
601#ifdef ALLOW_DEBUG_COUT
605 << drawer2+1 <<
" status " << chan1 <<
"/" << chan2 <<
" "
606 << (chStatus1.
isBad()?
"bad":
"good") <<
"/"
607 << (chStatus2.
isBad()?
"bad":
"good") <<
"/"
608 << ((
m_RUN2plus)?
" RUN2+ cabling":
"RUN1 cabling")
614#ifdef ALLOW_DEBUG_COUT
616 std::cout <<
"Ene of chan1 was " << pCell->
ene1() <<
" changing to half of " << pCell->
ene2()
617 <<
" and setting bad1=true" << std::endl;
623 --drawerEvtStatus[ros1][drawer1].nMaskedChannels;
627#ifdef ALLOW_DEBUG_COUT
629 std::cout <<
"Ene of chan2 was " << pCell->
ene2() <<
" changing to half of " << pCell->
ene1()
630 <<
" and setting bad2=true" << std::endl;
636 --drawerEvtStatus[ros2][drawer2].nMaskedChannels;
642 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
643 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
658 }
else if (bad1 && !bad2) {
660 ++drawerEvtStatus[ros1][drawer1].nMaskedChannels;
662 float ene2 = pCell->
ene2();
663 pCell->
setEnergy(ene2, ene2, gain2, gain2);
667 uint8_t qual2 = pCell->
qual2();
670 uint8_t qual1 = qual2 + (gain1 - gain2);
671 if (qual1 >
m_qualityCut && gain1 > gain2) qual1 = qual2 - (gain1 - gain2);
681 }
else if (!bad1 && bad2) {
683 ++drawerEvtStatus[ros2][drawer2].nMaskedChannels;
685 float ene1 = pCell->
ene1();
686 pCell->
setEnergy(ene1, ene1, gain1, gain1);
690 uint8_t qual1 = pCell->
qual1();
693 uint8_t qual2 = qual1 + (gain2 - gain1);
694 if (qual2 >
m_qualityCut && gain2 > gain1) qual2 = qual1 - (gain2 - gain1);
728 return single_PMT_C10;
732template<
class ITERATOR,
class COLLECTION>
735 const ITERATOR & begin,
const ITERATOR & end, COLLECTION * coll,
741 const EventContext& ctx = Gaudi::Hive::currentContext();
743 wrapper->
setSeed (rngname, ctx);
744 CLHEP::HepRandomEngine* engine = wrapper->
getEngine (ctx);
756 float eCellTot = 0.0;
757 float eMBTSTot = 0.0;
758 float eE4prTot = 0.0;
759 bool EBdrawerPresent[128];
760 memset(EBdrawerPresent, 0,
sizeof(EBdrawerPresent));
761#ifdef USE_TILECELLS_DATAPOOL
769 bool overflow =
false;
770 bool underflow =
false;
771 bool overfit =
false;
774 std::vector<TileCell*> allCells (
m_tileID->cell_hash_max(),
nullptr);
775 std::vector<TileCell*> MBTSVec;
779 std::vector<TileCell*> E4prVec;
784 for (ITERATOR hitItr = begin; hitItr != end; ++hitItr) {
786 const TileHit* pHit = (*hitItr);
794 int hitsize = pHit->
size();
795 for (
int ind = 0; ind < hitsize; ++ind) {
796 float tim = pHit->
time(ind);
798 float ene = pHit->
energy(ind);
804 float ener = ener_min;
808 bool good_time =
false;
809 bool non_zero_time = (ehit!=0.0);
815 int channel =
m_tileHWID->channel(channel_id);
821 if (ener > 10000. * MeV) {
824 good_time = (fabs(time) < 25.);
827 bool MBTS =
false, E4pr =
false, E1_CELL =
false;
852 cell_id =
m_tileID->cell_id(cell_id);
865 else if (tower == 0 && sample ==
TileID::SAMP_D && pmt == 1) ros = 2;
879 unsigned char iqual =
iquality(qual);
881 unsigned char qbit =
qbits(drawerEvtStatus,
883 , overflow, underflow, overfit);
891 pCell->
set(NULL, cell_id);
899 if (msgLvl(MSG::VERBOSE)) {
900 msg(MSG::VERBOSE) <<
" E4' cell_id=" <<
m_tileTBID->to_string(cell_id)
901 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
905 <<
" iqual= " << (int) iqual
906 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
909 if (E4prVec[
index]) {
910 msg(MSG::WARNING) <<
" double E4' cell_id=" <<
m_tileTBID->to_string(cell_id)
911 <<
" ignoring previous value" <<
endmsg;
913 E4prVec[
index] = pCell;
922 ener /= emScale->calibrateChannel(drawerIdx, channel, gain, 1.,
927 unsigned char iqual =
iquality(qual);
929 unsigned char qbit =
qbits(drawerEvtStatus,
930 ros, drawer,
false, (good_time && non_zero_time)
947 if (msgLvl(MSG::VERBOSE)) {
948 msg(MSG::VERBOSE) <<
" MBTS cell_id=" <<
m_tileTBID->to_string(cell_id)
949 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
953 <<
" iqual= " << (int) iqual
954 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
957 if (MBTSVec[
index]) {
958 msg(MSG::WARNING) <<
" double MBTS cell_id=" <<
m_tileTBID->to_string(cell_id)
959 <<
" ignoring previous value" <<
endmsg;
961 MBTSVec[
index] = pCell;
967 unsigned char iqual =
iquality(qual);
969 unsigned char qbit =
qbits(drawerEvtStatus, ros, drawer,
true, non_zero_time,
974 int drawer2 =
m_cabling->E1_merged_with_run2plus(ros,drawer);
977 int index2 =
m_tileID->cell_hash(cell_id2);
980 allCells[index2] = pCell2;
982 pCell2->
set(dde2, cell_id2);
986 correctCell(pCell2, 1, pmt2, gain, ener, time, iqual, qbit);
989 <<
" split into " <<
m_tileID->to_string(cell_id2));
996 correctCell(pCell, 2, pmt, gain, ener, time, iqual, qbit);
1001 pCell->
set(dde, cell_id);
1003 correctCell(pCell, 1, pmt, gain, ener, time, iqual, qbit);
1006 if (msgLvl(MSG::VERBOSE)) {
1007 float calib1 = (ehit != 0.0) ? ener / ehit : 0.0;
1008 msg(MSG::VERBOSE) <<
" cell_id=" <<
m_tileID->to_string(cell_id, -2)
1009 <<
" adc_id=" <<
"5/0/" << ros <<
"/" << drawer <<
"/" << channel <<
"/" << gain
1010 <<
" calib=" << calib1
1011 <<
" nCell=" << nCell
1012 <<
" energy=" << ener <<
" (" << pCell->
energy() <<
", " << pCell->
eneDiff() <<
")" <<
endmsg;
1014 msg(MSG::VERBOSE) <<
" ehit= " << ehit
1015 <<
" time= " << time
1016 <<
" iqual= " << (int) iqual
1017 <<
" qbit = 0x" << MSG::hex << (
int) qbit << MSG::dec <<
endmsg;
1024 unsigned char iqual = 0;
1042 int side =
m_tileID->side(cell_id);
1043 int module =
m_tileID->module(cell_id);
1044 int sample =
m_tileID->sample(cell_id);
1049 bool single_PMT = Ecell || single_PMT_C10;
1053 if ( ! missing_D4 ) {
1056 if (!single_PMT) ++nTwo;
1059 pCell->
set(dde, cell_id);
1075 <<
" bad channels masked, new energy=" << pCell->
energy() );
1077 bool bad1=pCell->
badch1();
1078 bool bad2=pCell->
badch2();
1080 if (! (bad1 && bad2) ) {
1087 if (bad1 || bad2 || single_PMT) {
1089 float ene = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1092 <<
" sigma " << noiseSigma <<
" noise " << ene );
1100 int gain1=pCell->
gain1();
1101 int gain2=pCell->
gain2();
1105 float ene = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1107 <<
" sigma " << noiseSigma <<
" noise " << ene );
1116 noiseSigma *= M_SQRT1_2;
1117 float ene1 = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1118 float ene2 = RandGaussQ::shoot(engine, 0.0, noiseSigma);
1121 <<
" sigma " << noiseSigma*M_SQRT2 <<
" noise " << ene1+ene2 <<
" noise1 " << ene1 <<
" noise2 " << ene2 );
1128 coll->push_back(pCell);
1129 allCells[
index] = 0;
1136 for (
int side = 0; side <
NSIDE; ++side) {
1143 bool merged_MBTS = (
eta == 1 && (
phi&1) == 1 &&
m_RUN2);
1145 if (!pCell && !merged_MBTS) {
1161 <<
" bad channel masked, new energy=" << pCell->
energy() );
1193 <<
" bad channel masked, new energy=" << pCell->
energy() );
1201 if (msgLvl(MSG::DEBUG)) {
1202 msg(MSG::DEBUG) <<
" nChan=" << nChan
1203 <<
" RawChSum=" << eCh
1204 <<
" nCell=" << nCell
1206 <<
" nFake=" << nFake
1207 <<
" eneTot=" << eCellTot;
1210 msg(MSG::DEBUG) <<
" nMBTS=" << nMBTS
1211 <<
" eMBTS=" << eMBTSTot;
1213 msg(MSG::DEBUG) <<
" nE4pr=" << nE4pr
1214 <<
" 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)
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 maskBadChannel(TileDrawerEvtStatusArray &drawerEvtStatus, TileCell *pCell) const
method to check if channels are good or bad.
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
bool maskBadChannels(TileDrawerEvtStatusArray &drawerEvtStatus, TileCell *pCell, bool single_PMT_C10, bool Ecell) const
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