diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/MuonCondAlg/TgcDigitTimeOffsetCondAlg.h b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/MuonCondAlg/TgcDigitTimeOffsetCondAlg.h new file mode 100644 index 0000000000000000000000000000000000000000..e603a7cf16a6226d982daf70bc5c15ed677f4b25 --- /dev/null +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/MuonCondAlg/TgcDigitTimeOffsetCondAlg.h @@ -0,0 +1,31 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef MUONCONDALG_TGCDIGITTIMEOFFSETCONDALG_H_ +#define MUONCONDALG_TGCDIGITTIMEOFFSETCONDALG_H_ + +#include "AthenaBaseComps/AthReentrantAlgorithm.h" +#include "AthenaPoolUtilities/CondAttrListCollection.h" +#include "GaudiKernel/ICondSvc.h" +#include "MuonCondData/TgcDigitTimeOffsetData.h" +#include "StoreGate/ReadCondHandleKey.h" +#include "StoreGate/WriteCondHandleKey.h" + +class TgcDigitTimeOffsetCondAlg : public AthReentrantAlgorithm +{ + public: + TgcDigitTimeOffsetCondAlg (const std::string& name, ISvcLocator* pSvcLocator); + virtual ~TgcDigitTimeOffsetCondAlg() = default; + virtual StatusCode initialize() override; + virtual StatusCode execute(const EventContext& ctx) const override; + + private: + SG::ReadCondHandleKey m_readKey{this, "ReadKey", "/TGC/DIGIT/TOFFSET", "SG key for TGCDIGITTOFFSET"}; + SG::WriteCondHandleKey m_writeKey{this, "WriteKey", "TGCDigitTimeOffsetData", "SG Key of TgcDigitTimeOffset"}; + + ServiceHandle m_condSvc{this, "CondSvc", "CondSvc"}; +}; + +#endif // MUONCONDALG_TGCDIGITTIMEOFFSETCONDALG_H_ + diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitASDposCondAlg.cxx b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitASDposCondAlg.cxx index a1a5f5592e4c1b40f5e9c42c9fa173a740ba13b6..1db7f7316961d51eea869d3a1156eb7b55f6145e 100644 --- a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitASDposCondAlg.cxx +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitASDposCondAlg.cxx @@ -56,8 +56,6 @@ StatusCode TgcDigitASDposCondAlg::execute(const EventContext& ctx) const // Fill auto outputCdo = std::make_unique(); - outputCdo->asdPos.assign(TgcDigitASDposData::N_STRIPASDPOS + TgcDigitASDposData::N_WIREASDPOS, std::vector(readHandle_ASDpos->size(), 0)); - size_t dbLine{}; std::string delimiter{";"}; for(const auto &[channel, attribute] : *readHandle_ASDpos.cptr()) { @@ -67,22 +65,29 @@ StatusCode TgcDigitASDposCondAlg::execute(const EventContext& ctx) const std::vector tokens; MuonCalib::MdtStringUtils::tokenize(blobline, tokens, delimiter); auto it = std::begin(tokens); - outputCdo->stationNum.push_back(stoi(*it)); + uint16_t station = static_cast(stoi(*it)); ++it; - outputCdo->stationEta.push_back(stoi(*it)); + uint16_t eta = static_cast(stoi(*it)); ++it; - outputCdo->stationPhi.push_back(stoi(*it)); + uint16_t phi = (stoi(*it) == -99) ? 0x1f : static_cast(stoi(*it)); + uint16_t chamberId = (station << 8) + (eta << 5) + phi; - for(int i=0;i strip_pos; + strip_pos.assign(TgcDigitASDposData::N_STRIPASDPOS, 0); + for (int i=0; i < TgcDigitASDposData::N_STRIPASDPOS; i++) { ++it; - outputCdo->asdPos[i][dbLine] = stof(*it); + strip_pos[i] = stof(*it); } - for(int i=0;istripAsdPos.insert(std::make_pair(chamberId, strip_pos)); + + std::vector wire_pos; + wire_pos.assign(TgcDigitASDposData::N_WIREASDPOS, 0); + for (int i=0; i < TgcDigitASDposData::N_WIREASDPOS; i++) { ++it; - outputCdo->asdPos[i + (int)TgcDigitASDposData::N_STRIPASDPOS][dbLine] = stof(*it); + wire_pos[i] = stof(*it); } - dbLine += 1; - } // end of for(attrmap) + outputCdo->wireAsdPos.insert(std::make_pair(chamberId, wire_pos)); + } // end of for(attrmap) // Record if (writeHandle.record(rangeIntersection, std::move(outputCdo)).isFailure()) { diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitTimeOffsetCondAlg.cxx b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitTimeOffsetCondAlg.cxx new file mode 100644 index 0000000000000000000000000000000000000000..a67b5e58f66d954beddc5e7ea7609d3a8467d33f --- /dev/null +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/TgcDigitTimeOffsetCondAlg.cxx @@ -0,0 +1,103 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#include "MuonCondAlg/TgcDigitTimeOffsetCondAlg.h" +#include "MuonCondSvc/MdtStringUtils.h" +#include "StoreGate/ReadCondHandle.h" +#include "StoreGate/WriteCondHandle.h" +#include "CoralBase/Blob.h" + +TgcDigitTimeOffsetCondAlg::TgcDigitTimeOffsetCondAlg(const std::string& name, ISvcLocator* pSvcLocator) +: AthReentrantAlgorithm(name, pSvcLocator) { +} + +StatusCode TgcDigitTimeOffsetCondAlg::initialize() { + ATH_MSG_DEBUG("initialize " << name()); + ATH_CHECK(m_condSvc.retrieve()); + ATH_CHECK(m_readKey.initialize()); + ATH_CHECK(m_writeKey.initialize()); + if (m_condSvc->regHandle(this, m_writeKey).isFailure()) { + ATH_MSG_FATAL("unable to register WriteCondHandle " << m_writeKey.fullKey() << " with CondSvc"); + return StatusCode::FAILURE; + } + return StatusCode::SUCCESS; +} + +StatusCode TgcDigitTimeOffsetCondAlg::execute(const EventContext& ctx) const { + SG::WriteCondHandle writeHandle{m_writeKey, ctx}; + if (writeHandle.isValid()) { + ATH_MSG_DEBUG("CondHandle " << writeHandle.fullKey() << " is already valid." + << ". In theory this should not be called, but may happen" + << " if multiple concurrent events are being processed out of order."); + return StatusCode::SUCCESS; + } + SG::ReadCondHandle readHandle_TOffset{m_readKey, ctx}; + if (readHandle_TOffset.cptr() == nullptr) { + ATH_MSG_ERROR("Null pointer to the read conditions object"); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Size of CondAttrListCollection" << readHandle_TOffset.fullKey() << " = " << readHandle_TOffset->size()); + EventIDRange rangeW_TOffset; + if (!readHandle_TOffset.range(rangeW_TOffset)) { + ATH_MSG_ERROR("Failed to retrieve validity range for " << readHandle_TOffset.key()); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("Range of input is " << rangeW_TOffset); + + // write condition object + EventIDRange rangeIntersection = EventIDRange::intersect(rangeW_TOffset); + if(rangeIntersection.start()>rangeIntersection.stop()) { + ATH_MSG_ERROR("Invalid intersection range: " << rangeIntersection); + return StatusCode::FAILURE; + } + + // Fill + auto outputCdo = std::make_unique(); + std::string delimiter{";"}; + for (const auto &[channel, attribute] : *readHandle_TOffset.cptr()) { + const coral::Blob& blob_strip = attribute["bTimeOffset_strip"].data(); + const char* charstrip = reinterpret_cast(blob_strip.startingAddress()); + std::string strstrip(charstrip); + + std::vector tokens; + MuonCalib::MdtStringUtils::tokenize(strstrip, tokens, delimiter); + auto it = std::begin(tokens); + uint16_t station_number = stoi(*it); + ++it; + uint16_t station_eta = stoi(*it); + ++it; + float offset_strip = stof(*it); + ++it; + uint16_t chamberId = (station_number << 3) + station_eta; + outputCdo->stripOffset.insert(std::make_pair(chamberId, offset_strip)); + + const coral::Blob& blob_wire = attribute["bTimeOffset_wire"].data(); + const char* charwire = reinterpret_cast(blob_wire.startingAddress()); + std::string strwire(charwire); + + tokens.clear(); + MuonCalib::MdtStringUtils::tokenize(strwire, tokens, delimiter); + it = std::begin(tokens); + station_number = stoi(*it); + ++it; + station_eta = stoi(*it); + ++it; + float offset_wire = stof(*it); + ++it; + chamberId = (station_number << 3) + station_eta; + outputCdo->wireOffset.insert(std::make_pair(chamberId, offset_wire)); + } // end of for(attrmap) + + // Record + if (writeHandle.record(rangeIntersection, std::move(outputCdo)).isFailure()) { + ATH_MSG_FATAL("Could not record TgcDigitTimeOffsetData " << writeHandle.key() + << " with EventRange " << rangeIntersection + << " into Conditions Store"); + return StatusCode::FAILURE; + } + ATH_MSG_DEBUG("recorded new " << writeHandle.key() << " with range " << rangeIntersection << " into Conditions Store"); + + return StatusCode::SUCCESS; +} + diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/components/MuonCondAlg_entries.cxx b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/components/MuonCondAlg_entries.cxx index 93288bf7a146f5998d3e5c3ed68d794b9e5d927f..da69dcb34b7cd21275008699cd673c4ab22d0f56 100644 --- a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/components/MuonCondAlg_entries.cxx +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondAlg/src/components/MuonCondAlg_entries.cxx @@ -7,6 +7,7 @@ #include "MuonCondAlg/RpcCondDbAlg.h" #include "MuonCondAlg/TgcCondDbAlg.h" #include "MuonCondAlg/TgcDigitASDposCondAlg.h" +#include "MuonCondAlg/TgcDigitTimeOffsetCondAlg.h" #include "MuonCondAlg/NswCalibDbAlg.h" DECLARE_COMPONENT(CscCondDbAlg) @@ -18,4 +19,5 @@ DECLARE_COMPONENT(MuonAlignmentCondAlg) DECLARE_COMPONENT(MdtCalibDbAlg) DECLARE_COMPONENT(MdtCalibFormatAlgTest) DECLARE_COMPONENT(TgcDigitASDposCondAlg) +DECLARE_COMPONENT(TgcDigitTimeOffsetCondAlg) DECLARE_COMPONENT(NswCalibDbAlg) diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitASDposData.h b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitASDposData.h index 8dde82a7cbd1ee4417618b180d88eddc6a0cc4a3..00b12b38de5986487a6675bd70e5c19a0ed48903 100644 --- a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitASDposData.h +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitASDposData.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ #ifndef TGCDIGITASDPOSDATA_H @@ -7,23 +7,22 @@ #include "AthenaKernel/BaseInfo.h" #include "AthenaKernel/CLASS_DEF.h" +#include #include - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * Contents of TGC_Digitization_AsdPosition.db * - * ================================================================== * - * |1|2|3|4|5|6|7|8|9|10|11|12|13| * - * * - * 1 -- station number(unsigned short) -> 41~48 * - * 2 -- station eta(unsigned short) -> 1~5 * - * 3 -- station phi(short) -> BW is -99, EI is 1~21, FI is 1~24 * - * 4~5 -- strip ASD position coordinate(float) * - * 6~13 -- Wire ASD position coordinate(float) * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * stripAsdPos : std::map> * + * wireAsdPos : std::map> * + * where * + * ChamberId = (station number)<<8 + (station eta)<<5 + (station phi) * + * station number: 41...48 * + * station eta: 1...5 * + * station phi: 0x1f for BW, 1...21 for EI, 1...24 for FI * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ class TgcDigitASDposData { -public: + public: TgcDigitASDposData(); virtual ~TgcDigitASDposData() = default; @@ -33,10 +32,8 @@ public: N_CHANNELINPUT_TOASD=16 }; - std::vector stationNum; - std::vector stationEta; - std::vector stationPhi; - std::vector> asdPos; + std::map> stripAsdPos; + std::map> wireAsdPos; }; CLASS_DEF(TgcDigitASDposData, 54799429, 1) diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitTimeOffsetData.h b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitTimeOffsetData.h new file mode 100644 index 0000000000000000000000000000000000000000..778c3dc5a6b8c8ec5f5c884282e4040c15e7053c --- /dev/null +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/MuonCondData/TgcDigitTimeOffsetData.h @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef MUONCONDDATA_TGCDIGITTIMEOFFSETDATA_H_ +#define MUONCONDDATA_TGCDIGITTIMEOFFSETDATA_H_ + +#include "AthenaKernel/BaseInfo.h" +#include "AthenaKernel/CLASS_DEF.h" +#include + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * stripOffset : std::map * + * wireOffset : std::map * + * where * + * ChamberId = (station number, 41...48)<<3 + (station eta, 1...5) * + * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +class TgcDigitTimeOffsetData +{ +public: + TgcDigitTimeOffsetData(); + virtual ~TgcDigitTimeOffsetData() = default; + + std::map stripOffset; + std::map wireOffset; +}; + +CLASS_DEF(TgcDigitTimeOffsetData, 236463561, 1) + +#include "AthenaKernel/CondCont.h" +CLASS_DEF(CondCont, 230286007, 1) + +#endif // MUONCONDDATA_TGCDIGITTIMEOFFSETDATA_H_ + diff --git a/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/src/TgcDigitTimeOffsetData.cxx b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/src/TgcDigitTimeOffsetData.cxx new file mode 100644 index 0000000000000000000000000000000000000000..2116551464b3826a14f2121d3b77aa1322310d0e --- /dev/null +++ b/MuonSpectrometer/MuonConditions/MuonCondGeneral/MuonCondData/src/TgcDigitTimeOffsetData.cxx @@ -0,0 +1,8 @@ +/* + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +*/ + +#include "MuonCondData/TgcDigitTimeOffsetData.h" + +TgcDigitTimeOffsetData::TgcDigitTimeOffsetData() +{} diff --git a/MuonSpectrometer/MuonConfig/python/MuonCondAlgConfig.py b/MuonSpectrometer/MuonConfig/python/MuonCondAlgConfig.py index c9ae27ba97423f69db0c2bc5af4d986449a6fed3..6f0eeef45771b7088968cda2dbd7fc03372627d2 100644 --- a/MuonSpectrometer/MuonConfig/python/MuonCondAlgConfig.py +++ b/MuonSpectrometer/MuonConfig/python/MuonCondAlgConfig.py @@ -152,7 +152,20 @@ def CscCondDbAlgCfg(flags, **kwargs): def TgcDigitASDposCondAlgCfg(flags): result = ComponentAccumulator() result.addCondAlgo(CompFactory.TgcDigitASDposCondAlg()) - result.merge(addFolders(flags, ["/TGC/DIGIT/ASDPOS"] , detDb="TGC_OFL", className="CondAttrListCollection")) + if flags.Digitization.UseUpdatedTGCConditions: + result.merge(addFolders(flags, ["/TGC/DIGIT/ASDPOS"], detDb="TGC_OFL", className="CondAttrListCollection")) + else: # Since the folder new and not defined at the presented global tag, it needs an explicit tag + result.merge(addFolders(flags, ["/TGC/DIGIT/ASDPOS"], tag='TgcDigitAsdPos-00-01', detDb="TGC_OFL", className="CondAttrListCollection")) + return result + +def TgcDigitTimeOffsetCondAlgCfg(flags): + result = ComponentAccumulator() + result.addCondAlgo(CompFactory.TgcDigitTimeOffsetCondAlg()) + + if flags.Digitization.UseUpdatedTGCConditions: + result.merge(addFolders(flags, ["/TGC/DIGIT/TOFFSET"], tag='TgcDigitTimeOffset-00-01', detDb="TGC_OFL", className="CondAttrListCollection")) # TODO The explicit tag will be removed, once this is available in the global tag. + else: # Since the folder new and not defined at the presented global tag, it needs an explicit tag + result.merge(addFolders(flags, ["/TGC/DIGIT/TOFFSET"], tag='TgcDigitTimeOffset-00-01', detDb="TGC_OFL", className="CondAttrListCollection")) return result def NswCalibDbAlgCfg(flags, **kwargs): diff --git a/MuonSpectrometer/MuonConfig/python/TGC_DigitizationConfig.py b/MuonSpectrometer/MuonConfig/python/TGC_DigitizationConfig.py index b53a2e63723a1b71516407b1a19b9c54a5bacedc..23faf0810aa2146733d0b144588d998d839bb94b 100644 --- a/MuonSpectrometer/MuonConfig/python/TGC_DigitizationConfig.py +++ b/MuonSpectrometer/MuonConfig/python/TGC_DigitizationConfig.py @@ -1,6 +1,6 @@ """Define methods to construct configured TGC Digitization tools and algorithms -Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration """ from AthenaConfiguration.ComponentAccumulator import ComponentAccumulator from AthenaConfiguration.ComponentFactory import CompFactory @@ -56,10 +56,11 @@ def TGC_DigitizationToolCfg(flags, name="TgcDigitizationTool", **kwargs): else: kwargs.setdefault("OutputSDOName", "TGC_SDO") - if flags.Digitization.UseUpdatedTGCConditions: - from MuonConfig.MuonCondAlgConfig import TgcDigitASDposCondAlgCfg - acc.merge(TgcDigitASDposCondAlgCfg(flags)) - kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") + from MuonConfig.MuonCondAlgConfig import TgcDigitASDposCondAlgCfg, TgcDigitTimeOffsetCondAlgCfg + acc.merge(TgcDigitASDposCondAlgCfg(flags)) + kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") + acc.merge(TgcDigitTimeOffsetCondAlgCfg(flags)) + kwargs.setdefault("TGCDigitTimeOffsetKey", "TGCDigitTimeOffsetData") from RngComps.RandomServices import AthRNGSvcCfg kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name) @@ -76,10 +77,11 @@ def TGC_OverlayDigitizationToolCfg(flags, name="Tgc_OverlayDigitizationTool", ** kwargs.setdefault("OutputObjectName", flags.Overlay.SigPrefix + "TGC_DIGITS") kwargs.setdefault("OutputSDOName", flags.Overlay.SigPrefix + "TGC_SDO") - if flags.Digitization.UseUpdatedTGCConditions: - from MuonConfig.MuonCondAlgConfig import TgcDigitASDposCondAlgCfg - acc.merge(TgcDigitASDposCondAlgCfg(flags)) - kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") + from MuonConfig.MuonCondAlgConfig import TgcDigitASDposCondAlgCfg, TgcDigitTimeOffsetCondAlgCfg + acc.merge(TgcDigitASDposCondAlgCfg(flags)) + kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") + acc.merge(TgcDigitTimeOffsetCondAlgCfg(flags)) + kwargs.setdefault("TGCDigitTimeOffsetKey", "TGCDigitTimeOffsetData") from RngComps.RandomServices import AthRNGSvcCfg kwargs.setdefault("RndmSvc", acc.getPrimaryAndMerge(AthRNGSvcCfg(flags)).name) diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/python/TGC_DigitizationConfig.py b/MuonSpectrometer/MuonDigitization/TGC_Digitization/python/TGC_DigitizationConfig.py index 32ae627d8cb0e2371984255aae82171c2d2bed7e..597248488cfc87b9cca0bc6f95a0a5002fbc0352 100644 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/python/TGC_DigitizationConfig.py +++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/python/TGC_DigitizationConfig.py @@ -1,4 +1,4 @@ -# Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration from Digitization.DigitizationFlags import jobproperties from AthenaCommon import CfgMgr @@ -26,6 +26,15 @@ def setupTgcDigitASDposCondAlg(): condSequence += CfgMgr.TgcDigitASDposCondAlg("TgcDigitASDposCondAlg") +def setupTgcDigitTimeOffsetCondAlg(): + from AthenaCommon.AlgSequence import AthSequencer + condSequence = AthSequencer("AthCondSeq") + if not hasattr(condSequence, "TgcDigitTimeOffsetCondAlg"): + from IOVDbSvc.CondDB import conddb + conddb.addFolder("TGC_OFL", "/TGC/DIGIT/TOFFSET TgcDigitTimeOffset-00-01", className='CondAttrListCollection', forceMC=True) # TODO remove explicit tag + condSequence += CfgMgr.TgcDigitTimeOffsetCondAlg("TgcDigitTimeOffsetCondAlg") + + def TgcDigitizationTool(name="TgcDigitizationTool", **kwargs): if jobproperties.Digitization.doXingByXingPileUp(): # PileUpTool approach # This should match the range for the TGC in Simulation/Digitization/share/MuonDigitization.py @@ -45,6 +54,8 @@ def TgcDigitizationTool(name="TgcDigitizationTool", **kwargs): setupTgcDigitASDposCondAlg() kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") + setupTgcDigitTimeOffsetCondAlg() + kwargs.setdefault("TGCDigitTimeOffsetKey", "TGCDigitTimeOffsetData") return CfgMgr.TgcDigitizationTool(name, **kwargs) @@ -67,11 +78,6 @@ def Tgc_OverlayDigitizationTool(name="Tgc_OverlayDigitizationTool", **kwargs): if not overlayFlags.isDataOverlay(): kwargs.setdefault("OutputSDOName",overlayFlags.evtStore()+"+TGC_SDO") - from Digitization.DigitizationFlags import digitizationFlags - if digitizationFlags.UseUpdatedTGCConditions(): - setupTgcDigitASDposCondAlg() - kwargs.setdefault("TGCDigitASDposKey", "TGCDigitASDposData") - return TgcDigitizationTool(name,**kwargs) def getTGC_OverlayDigitizer(name="TGC_OverlayDigitizer", **kwargs): diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_ASDpropTimeOffset.dat b/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_ASDpropTimeOffset.dat deleted file mode 100644 index d7291067895d0f1916e8cb2b60d0f6dd0f198683..0000000000000000000000000000000000000000 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_ASDpropTimeOffset.dat +++ /dev/null @@ -1,236 +0,0 @@ -41 1 0 1 16 -5 -42 1 0 1 16 -6 -42 2 0 1 16 -4.5 -42 3 0 1 16 -5 -42 4 0 1 16 -8 -43 1 0 1 16 -5 -44 1 0 1 16 -6 -44 2 0 1 16 -6 -44 3 0 1 16 -6 -44 4 0 1 16 -6 -44 5 0 1 16 -6 -45 1 0 1 16 -5 -46 1 0 1 16 -6 -46 2 0 1 16 -6 -46 3 0 1 16 -6 -46 4 0 1 16 -6 -46 5 0 1 16 -6 -47 1 0 1 16 -6 -48 1 0 1 16 -8 -41 -1 0 1 16 -5 -42 -1 0 1 16 -6 -42 -2 0 1 16 -4.5 -42 -3 0 1 16 -6 -42 -4 0 1 16 -8 -43 -1 0 1 16 -5 -44 -1 0 1 16 -6 -44 -2 0 1 16 -6 -44 -3 0 1 16 -6 -44 -4 0 1 16 -6 -44 -5 0 1 16 -6 -45 -1 0 1 16 -5 -46 -1 0 1 16 -6 -46 -2 0 1 16 -6 -46 -3 0 1 16 -6 -46 -4 0 1 16 -6 -46 -5 0 1 16 -6 -47 -1 0 1 16 -6 -48 -1 0 1 16 -8 -41 1 0 2 32 -5 -42 1 0 2 32 -6 -42 2 0 2 32 -4.5 -42 3 0 2 32 -5 -42 4 0 2 32 -8 -43 1 0 2 32 -5 -44 1 0 2 32 -6 -44 2 0 2 32 -6 -44 3 0 2 32 -6 -44 4 0 2 32 -6 -44 5 0 2 32 -6 -45 1 0 2 32 -5 -46 1 0 2 32 -6 -46 2 0 2 32 -6 -46 3 0 2 32 -6 -46 4 0 2 32 -6 -46 5 0 2 32 -6 -47 1 0 2 32 -7 -48 1 0 2 32 -9 -41 -1 0 2 32 -5 -42 -1 0 2 32 -6 -42 -2 0 2 32 -4.5 -42 -3 0 2 32 -5 -42 -4 0 2 32 -8 -43 -1 0 2 32 -5 -44 -1 0 2 32 -6 -44 -2 0 2 32 -6 -44 -3 0 2 32 -6 -44 -4 0 2 32 -6 -44 -5 0 2 32 -6 -45 -1 0 2 32 -5 -46 -1 0 2 32 -6 -46 -2 0 2 32 -6 -46 -3 0 2 32 -6 -46 -4 0 2 32 -6 -46 -5 0 2 32 -6 -47 -1 0 2 32 -7 -48 -1 0 2 32 -9 -41 1 0 3 48 -5 -42 1 0 3 48 -6 -42 2 0 3 48 -4.5 -43 1 0 3 48 -5 -44 1 0 3 48 -6 -44 2 0 3 48 -6 -45 1 0 3 48 -5 -46 1 0 3 48 -6 -46 2 0 3 48 -6 -41 -1 0 3 48 -5 -42 -1 0 3 48 -6 -42 -2 0 3 48 -4.5 -43 -1 0 3 48 -5 -44 -1 0 3 48 -6 -44 -2 0 3 48 -6 -45 -1 0 3 48 -5 -46 -1 0 3 48 -6 -46 -2 0 3 48 -6 -41 1 0 4 64 -5 -42 1 0 4 64 -6 -42 2 0 4 64 -4.5 -43 1 0 4 64 -5 -44 1 0 4 64 -6 -44 2 0 4 64 -6 -45 1 0 4 64 -5 -46 1 0 4 64 -6 -46 2 0 4 64 -6 -41 -1 0 4 64 -5 -42 -1 0 4 64 -6 -42 -2 0 4 64 -4.5 -43 -1 0 4 64 -5 -44 -1 0 4 64 -6 -44 -2 0 4 64 -6 -45 -1 0 4 64 -5 -46 -1 0 4 64 -6 -46 -2 0 4 64 -6 -41 1 0 5 80 -5 -42 1 0 5 80 -6 -43 1 0 5 80 -5 -44 1 0 5 80 -6 -44 2 0 5 80 -6 -45 1 0 5 80 -5 -46 1 0 5 80 -6 -46 2 0 5 80 -6 -41 -1 0 5 80 -5 -42 -1 0 5 80 -6 -43 -1 0 5 80 -5 -44 -1 0 5 80 -6 -44 -2 0 5 80 -6 -45 -1 0 5 80 -5 -46 -1 0 5 80 -6 -46 -2 0 5 80 -6 -41 1 0 6 96 -5 -42 1 0 6 96 -6 -43 1 0 6 96 -5 -44 1 0 6 96 -6 -44 2 0 6 96 -6 -45 1 0 6 96 -5 -46 1 0 6 96 -6 -46 2 0 6 96 -6 -41 -1 0 6 96 -5 -42 -1 0 6 96 -6 -43 -1 0 6 96 -5 -44 -1 0 6 96 -6 -44 -2 0 6 96 -6 -45 -1 0 6 96 -5 -46 -1 0 6 96 -6 -46 -2 0 6 96 -6 -41 1 0 7 112 -5 -43 1 0 7 112 -5 -44 1 0 7 112 -6 -44 2 0 7 112 -6 -45 1 0 7 112 -5 -46 2 0 7 112 -6 -41 -1 0 7 112 -5 -43 -1 0 7 112 -5 -44 -1 0 7 112 -6 -44 -2 0 7 112 -6 -45 -1 0 7 112 -5 -46 -2 0 7 112 -6 -43 1 0 8 128 -5 -45 1 0 8 128 -5 -43 -1 0 8 128 -5 -45 -1 0 8 128 -5 -41 1 1 1 16 -1.5 -42 1 1 1 16 -1.5 -42 2 1 1 16 -1.5 -42 3 1 1 16 -2 -42 4 1 1 16 -2 -43 1 1 1 16 -2 -44 1 1 1 16 -1.5 -44 2 1 1 16 -1.5 -44 3 1 1 16 -2 -44 4 1 1 16 -2 -44 5 1 1 16 -2 -45 1 1 1 16 -2 -46 1 1 1 16 -1.5 -46 2 1 1 16 -1.5 -46 3 1 1 16 -2 -46 4 1 1 16 -2 -46 5 1 1 16 -2 -47 1 1 1 16 -8 -48 1 1 1 16 -7.5 -41 -1 1 1 16 -1.5 -42 -1 1 1 16 -1.5 -42 -2 1 1 16 -1.5 -42 -3 1 1 16 -2 -42 -4 1 1 16 -2 -43 -1 1 1 16 -2 -44 -1 1 1 16 -1.5 -44 -2 1 1 16 -1.5 -44 -3 1 1 16 -2 -44 -4 1 1 16 -2 -44 -5 1 1 16 -2 -45 -1 1 1 16 -2 -46 -1 1 1 16 -1.5 -46 -2 1 1 16 -1.5 -46 -3 1 1 16 -2 -46 -4 1 1 16 -2 -46 -5 1 1 16 -2 -47 -1 1 1 16 -8 -48 -1 1 1 16 -7.5 -41 1 1 2 32 -1.5 -42 1 1 2 32 -1.5 -42 2 1 2 32 -1.5 -42 3 1 2 32 -2 -42 4 1 2 32 -2 -43 1 1 2 32 -2 -44 1 1 2 32 -1.5 -44 2 1 2 32 -1.5 -44 3 1 2 32 -2 -44 4 1 2 32 -2 -44 5 1 2 32 -2 -45 1 1 2 32 -2 -46 1 1 2 32 -1.5 -46 2 1 2 32 -1.5 -46 3 1 2 32 -2 -46 4 1 2 32 -2 -46 5 1 2 32 -2 -47 1 1 2 32 -8 -48 1 1 2 32 -7.5 -41 -1 1 2 32 -1.5 -42 -1 1 2 32 -1.5 -42 -2 1 2 32 -1.5 -42 -3 1 2 32 -2 -42 -4 1 2 32 -2 -43 -1 1 2 32 -2 -44 -1 1 2 32 -1.5 -44 -2 1 2 32 -1.5 -44 -3 1 2 32 -2 -44 -4 1 2 32 -2 -44 -5 1 2 32 -2 -45 -1 1 2 32 -2 -46 -1 1 2 32 -1.5 -46 -2 1 2 32 -1.5 -46 -3 1 2 32 -2 -46 -4 1 2 32 -2 -46 -5 1 2 32 -2 -47 -1 1 2 32 -8 -48 -1 1 2 32 -7.5 diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_timeWindowOffset.dat b/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_timeWindowOffset.dat deleted file mode 100644 index 2aae3603b921dae248e674b9c01e4d4997bd3d95..0000000000000000000000000000000000000000 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/share/TGC_Digitization_timeWindowOffset.dat +++ /dev/null @@ -1,76 +0,0 @@ -41 1 0 -2.5 -42 1 0 -2.5 -42 2 0 -3.0 -42 3 0 -4.0 -42 4 0 -3.0 -43 1 0 -2.5 -44 1 0 -2.0 -44 2 0 -1.5 -44 3 0 -3.0 -44 4 0 -3.0 -44 5 0 -3.0 -45 1 0 -2.5 -46 1 0 -2.0 -46 2 0 -1.5 -46 3 0 -3.0 -46 4 0 -3.0 -46 5 0 -3.0 -47 1 0 -1.5 -48 1 0 0.5 -41 -1 0 -2.5 -42 -1 0 -2.5 -42 -2 0 -3.0 -42 -3 0 -4.0 -42 -4 0 -3.0 -43 -1 0 -2.5 -44 -1 0 -2.0 -44 -2 0 -1.5 -44 -3 0 -3.0 -44 -4 0 -3.0 -44 -5 0 -3.0 -45 -1 0 -2.5 -46 -1 0 -2.0 -46 -2 0 -1.5 -46 -3 0 -3.0 -46 -4 0 -3.0 -46 -5 0 -3.0 -47 -1 0 -1.5 -48 -1 0 0.5 -41 1 1 -8.5 -42 1 1 -7.5 -42 2 1 -10.5 -42 3 1 -8.5 -42 4 1 -10.0 -43 1 1 -9.5 -44 1 1 -7.5 -44 2 1 -11.0 -44 3 1 -8.0 -44 4 1 -11.0 -44 5 1 -10.5 -45 1 1 -9.0 -46 1 1 -7.5 -46 2 1 -10.5 -46 3 1 -7.0 -46 4 1 -10.0 -46 5 1 -10.0 -47 1 1 -5.0 -48 1 1 -6.0 -41 -1 1 -8.5 -42 -1 1 -7.5 -42 -2 1 -10.5 -42 -3 1 -8.5 -42 -4 1 -10.0 -43 -1 1 -9.5 -44 -1 1 -7.5 -44 -2 1 -11.0 -44 -3 1 -8.0 -44 -4 1 -11.0 -44 -5 1 -10.5 -45 -1 1 -9.0 -46 -1 1 -7.5 -46 -2 1 -10.5 -46 -3 1 -7.0 -46 -4 1 -10.0 -46 -5 1 -10.0 -47 -1 1 -5.0 -48 -1 1 -6.0 diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.cxx b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.cxx index 5f142456bd73f1065e37992fe3d747b7de941a5e..7693e245427ca9ca53f64c5995dd77894cf3162b 100644 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.cxx +++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.cxx @@ -38,7 +38,6 @@ TgcDigitMaker::TgcDigitMaker(TgcHitIdHelper* hitIdHelper, m_runperiod = runperiod; m_idHelper = nullptr; m_efficiency[kWIRE] = m_efficiency[kSTRIP] = 1.000; // 100% efficiency for TGCSimHit_p1 - m_timeWindowOffsetSensor[kWIRE] = m_timeWindowOffsetSensor[kSTRIP] = 0.; m_gateTimeWindow[kOUTER][kWIRE] = 29.32; // 29.32ns = 26ns + 4 * 0.83ns(outer station) m_gateTimeWindow[kOUTER][kSTRIP] = 40.94; // 40.94ns = 26ns + 18 * 0.83ns(outer station) m_gateTimeWindow[kINNER][kWIRE] = 33.47; // 33.47ns = 26ns + 9 * 0.83ns(inner station) @@ -75,15 +74,9 @@ StatusCode TgcDigitMaker::initialize() // Read share/TGC_Digitization_deadChamber.dat file and store values in m_isDeadChamber. ATH_CHECK(readFileOfDeadChamber()); - // Read share/TGC_Digitization_timeWindowOffset.dat file and store values in m_timeWindowOffset. - ATH_CHECK(readFileOfTimeWindowOffset()); - // Read share/TGC_Digitization_alignment.dat file and store values in m_alignmentZ, m_alignmentT, m_alignmentS, m_alignmentTHS ATH_CHECK(readFileOfAlignment()); - // Read share/TGC_Digitization_ASDpropTimeOffset.dat file and store values in m_ASDpropTimeOffset, m_maxch. - ATH_CHECK(readFileOfASDpropTimeOffset()); - // Read share/TGC_Digitization_StripPosition.dat file and store values in m_StripPosition. ATH_CHECK(readFileOfStripPosition()); @@ -96,15 +89,27 @@ StatusCode TgcDigitMaker::initialize() TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, const double globalHitTime, const TgcDigitASDposData* ASDpos, + const TgcDigitTimeOffsetData* TOffset, CLHEP::HepRandomEngine* rndmEngine) { + // timing constant parameters + constexpr float sensor_propagation_time = 3.3 * CLHEP::ns / CLHEP::m; // Until MC10, 8.5*ns/m for wire, 8.7*ns/m for strip. + // Since MC11, 3.3*ns/m (the speed of light) is used + // from the Z->mumu data/MC comparison. + constexpr float cable_propagation_time = 5.0 * CLHEP::ns / CLHEP::m; + + // position constant parameters + constexpr float wire_pitch = 1.8 * CLHEP::mm; + constexpr float zwidth_frame = 17. * CLHEP::mm; + + ATH_MSG_DEBUG("executeDigi() Got HIT Id."); + ////////// convert ID for this digitizer system int Id = hit->TGCid(); std::string stationName= m_hitIdHelper->GetStationName(Id); int stationEta = m_hitIdHelper->GetStationEta(Id); int stationPhi = m_hitIdHelper->GetStationPhi(Id); int ilyr = m_hitIdHelper->GetGasGap(Id); - ATH_MSG_DEBUG("executeDigi() Got HIT Id."); // Check the chamber is dead or not. if(isDeadChamber(stationName, stationEta, stationPhi, ilyr)) return nullptr; @@ -118,13 +123,6 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, return nullptr; } - const Amg::Vector3D centreChamber = tgcChamber->globalPosition(); - float height = tgcChamber->getRsize(); - float hmin = sqrt(pow(centreChamber.x(),2)+pow(centreChamber.y(),2)) - height/2.; - float wirePitch = 1.8*CLHEP::mm; - float frameZwidth = 17. *CLHEP::mm; - float frameXwidth = 20. *CLHEP::mm; - IdContext tgcContext = m_idHelper->module_context(); IdentifierHash coll_hash; if(m_idHelper->get_hash(elemId, coll_hash, &tgcContext)) { @@ -137,6 +135,11 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, std::unique_ptr digits = std::make_unique(elemId, coll_hash); + + const Amg::Vector3D centreChamber = tgcChamber->globalPosition(); + float height = tgcChamber->getRsize(); + float hmin = sqrt(pow(centreChamber.x(),2)+pow(centreChamber.y(),2)) - height/2.; + // Direction cosine of incident angle of this track Amg::Vector3D direCos = hit->localDireCos(); @@ -147,11 +150,11 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, //adHocPositionShift(stationName, stationEta, stationPhi, direCos, localPos); // Local z direction is global r direction. - float distanceZ = 1.4*CLHEP::mm/direCos[0]*direCos[2]; + float distanceZ = 1.4*CLHEP::mm / direCos[0]*direCos[2]; float zLocal = localPos.z() + distanceZ; // Local y direction is global phi direction. - float distanceY = 1.4*CLHEP::mm/direCos[0]*direCos[1]; + float distanceY = 1.4*CLHEP::mm / direCos[0]*direCos[1]; // This ySign depends on the implementation of TGC geometry in G4 simulation // left-handed coordinate in A side(+z, stationEta>0) float ySign = (stationEta < 0) ? +1. : -1.; @@ -160,7 +163,7 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, // Time of flight correction for each chamber // the offset is set to 0 for ASD located at the postion where tof is minimum in each chamber, // i.e. the ASD at the smallest R in each chamber - double tofCorrection = (sqrt(pow(hmin+frameZwidth,2)+pow(centreChamber.z(),2))/(299792458.*(CLHEP::m/CLHEP::s)));//FIXME use CLHEP::c_light + double tofCorrection = (sqrt(pow(hmin+zwidth_frame, 2)+pow(centreChamber.z(),2)) / (299792458.*(CLHEP::m/CLHEP::s)));//FIXME use CLHEP::c_light // bunch time float bunchTime = globalHitTime - tofCorrection; @@ -170,10 +173,6 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, int iStationName = getIStationName(stationName); - ///////////// wire group number calculation /////////////// - TgcSensor sensor = kWIRE; - m_timeWindowOffsetSensor[sensor] = getTimeWindowOffset(stationName, stationEta, sensor); - double energyDeposit = hit->energyDeposit(); // Energy deposit in MeV // If TGCSimHit_p1 is used, energyDeposit is the default value of -9999. // If TGCSimHit_p2 is used, energyDeposit is equal to or greater than 0. @@ -181,9 +180,11 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, // For TGCSimHit_p1, old efficiency check with only isStrip variable is used. // For TGCSimHit_p2, new efficiency check with chamber dependent energy threshold is used. - if((energyDeposit< -1. && efficiencyCheck(sensor, rndmEngine)) || // Old efficiencyCheck for TGCSimHit_p1. - (energyDeposit>=-1. && efficiencyCheck(stationName, stationEta, stationPhi, ilyr, sensor, energyDeposit)) // New efficiencyCheck for TGCSimHit_p2 - ) { + + ///////////// wire group number calculation /////////////// + + if ((energyDeposit>=-1. && efficiencyCheck(stationName, stationEta, stationPhi, ilyr, kWIRE, energyDeposit)) || // efficiency check for TGCSimHit_p2 at first, + (energyDeposit< -1. && efficiencyCheck(kWIRE, rndmEngine))) { // Old efficiencyCheck for TGCSimHit_p1 int iWireGroup[2]; float posInWireGroup[2] = {0., 0.}; @@ -192,28 +193,27 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, // for chambers in which only the first wire is not connected : 1 // for chambers in which the first and last wires are not connected OR all wires are connected : 0 - double zPosInSensArea = zLocal + static_cast(tgcChamber->getTotalWires(ilyr)-nWireOffset)*wirePitch/2.; + double zPosInSensArea = zLocal + static_cast(tgcChamber->getTotalWires(ilyr)-nWireOffset)*wire_pitch/2.; // check a hit in the sensitive area - if(zPosInSensArea < 0. || zPosInSensArea > tgcChamber->getTotalWires(ilyr)*wirePitch) { + if(zPosInSensArea < 0. || zPosInSensArea > tgcChamber->getTotalWires(ilyr)*wire_pitch) { iWireGroup[iPosition] = 0; posInWireGroup[iPosition] = 0.; - ATH_MSG_DEBUG("executeDigi(): Wire: Hit position located at outside of a sensitive volume, " - << " id: " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr - << " position: " << zPosInSensArea - << " xlocal: " << zLocal - << " dir cosine: " << direCos[0] << "/" << direCos[1] << "/" << direCos[2] - << " active region: " << height-frameZwidth*2.); - } - else { + ATH_MSG_DEBUG("executeDigi(): Wire: Hit position located at outside of a sensitive volume, " + << " id: " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr + << " position: " << zPosInSensArea + << " xlocal: " << zLocal + << " dir cosine: " << direCos[0] << "/" << direCos[1] << "/" << direCos[2] + << " active region: " << height - zwidth_frame*2.); + } else { int igang = 1; int wire_index = 0; - while(wirePitch*(static_cast(wire_index)) < zPosInSensArea + while(wire_pitch*(static_cast(wire_index)) < zPosInSensArea && igang <= tgcChamber -> getNGangs(ilyr)) { wire_index += tgcChamber->getNWires(ilyr,igang); igang++; } - posInWireGroup[iPosition] = (zPosInSensArea/wirePitch-(static_cast(wire_index)))/(static_cast(tgcChamber->getNWires(ilyr,igang-1)))+1.; + posInWireGroup[iPosition] = (zPosInSensArea/wire_pitch-(static_cast(wire_index)))/(static_cast(tgcChamber->getNWires(ilyr,igang-1)))+1.; iWireGroup[iPosition] = ((1==igang) ? 1 : igang-1); } @@ -223,71 +223,68 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, (iWireGroup[0]<=iWireGroup[1]) ? (unsigned int)(1) : (unsigned int)(0)}; int iWG[2] = {iWireGroup[jWG[0]], iWireGroup[jWG[1]]}; float posInWG[2] = {posInWireGroup[jWG[0]], posInWireGroup[jWG[1]]}; - if(iWG[0]!=iWG[1]) { + if (iWG[0] != iWG[1]) { ATH_MSG_DEBUG("executeDigi(): Multihits found in WIRE GROUPs:" << iWG[0] << " " << iWG[1]); } - for(int iwg=iWG[0]; iwg<=iWG[1]; iwg++) { + // === BC tagging from the hit timing === + for(int iwg=iWG[0]; iwg <= iWG[1]; iwg++) { if(1<=iwg && iwg<=tgcChamber->getNGangs(ilyr)) { + // timing window offset + float wire_timeOffset = (TOffset != nullptr) ? this->getTimeOffset(TOffset, iStationName, stationEta, kWIRE) : 0.; + // EI/FI has different offset between two ASDs. + if (iStationName > 46) wire_timeOffset += (iwg < 17) ? 0.5 * CLHEP::ns : -0.5 * CLHEP::ns; + // TGC response time calculation float jit = timeJitter(direCos, rndmEngine); if(jit < jitter) jitter = jit; - const float wirePropagationTime = 3.3*CLHEP::ns/CLHEP::m; // 3.7*ns/m was used until MC10. float ySignPhi = (stationPhi%2==1) ? -1. : +1.; // stationPhi%2==0 : +1. : ASD attached at the smaller phi side of TGC // stationPhi%2==1 : -1. : ASD attached at the larger phi side of TGC - float wTimeDiffByRadiusOfInner = this->timeDiffByCableRadiusOfInner(iStationName, stationPhi, iwg); - float wDigitTime = bunchTime + jit + wirePropagationTime*(ySignPhi*yLocal + tgcChamber->chamberWidth(zLocal)/2.) + wTimeDiffByRadiusOfInner; - float wOffset = m_timeWindowOffsetSensor[sensor]; - float wASDDis{-1000}; - float wSigPropTimeDelay{-1000}; - if (ASDpos != nullptr) { - wASDDis = this->getDistanceToAsdFromSensor(ASDpos, iStationName, abs(stationEta), stationPhi, sensor, iwg, zLocal); - float wCableDis = wASDDis + (ySignPhi*yLocal + tgcChamber->chamberWidth(zLocal)/2.)/1000.; - wSigPropTimeDelay = this->getSigPropTimeDelay(wCableDis); - wDigitTime += wSigPropTimeDelay + wASDDis * 5; - wOffset += getASDpropTimeOffset(elemId, (int)sensor, iwg); - } + float wTimeDiffByRadiusOfInner = this->timeDiffByCableRadiusOfInner(iStationName, stationPhi, iwg); + double digit_time = bunchTime + jitter + wTimeDiffByRadiusOfInner; + float wASDDis{-1000.}; + if (ASDpos != nullptr) { + wASDDis = this->getDistanceToAsdFromSensor(ASDpos, iStationName, abs(stationEta), stationPhi, kWIRE, iwg, zLocal); + float wCableDis = wASDDis + (ySignPhi*yLocal + tgcChamber->chamberWidth(zLocal)/2.); + float wPropTime = sensor_propagation_time * (ySignPhi*yLocal + tgcChamber->chamberWidth(zLocal)/2.) + cable_propagation_time * wASDDis; + digit_time += this->getSigPropTimeDelay(wCableDis) + wPropTime; + } TgcStation station = (m_idHelper->stationName(elemId) > 46) ? kINNER : kOUTER; - uint16_t bctag = bcTagging(wDigitTime,m_gateTimeWindow[station][sensor],wOffset); - - if(bctag == 0x0) { - ATH_MSG_DEBUG("WireGroup: digitized time is outside of time window. " << wDigitTime - << " bunchTime: " << bunchTime << " time jitter: " << jitter - << " propagation time: " << wirePropagationTime*(ySignPhi*yLocal + height/2. + frameXwidth) - << " signal delay time: " << wSigPropTimeDelay - << " time difference by cable radius of inner station: " << wTimeDiffByRadiusOfInner - << " propagation time to the ASD from the sensor: " << wASDDis * 5); - } - else { - Identifier newId = m_idHelper -> channelID(stationName,stationEta,stationPhi, - ilyr, (int)sensor, iwg); - addDigit(newId,bctag, digits.get()); + uint16_t bctag = bcTagging(digit_time, m_gateTimeWindow[station][kWIRE], wire_timeOffset); + + if(bctag == 0x0) { + ATH_MSG_DEBUG("WireGroup: digitized time " << digit_time << " ns is outside of time window from " << wire_timeOffset + << ". bunchTime: " << bunchTime << " time jitter: " << jitter + << " propagation time: " << sensor_propagation_time*(ySignPhi*yLocal + tgcChamber->chamberWidth(zLocal)/2.) + cable_propagation_time * wASDDis + << " time difference by cable radius of inner station: " << wTimeDiffByRadiusOfInner); + } else { + Identifier newId = m_idHelper->channelID(stationName,stationEta,stationPhi, + ilyr, (int)kWIRE, iwg); + addDigit(newId, bctag, digits.get()); if(iwg==iWG[0]) { - randomCrossTalk(elemId, ilyr, sensor, iwg, posInWG[0], wDigitTime, wOffset, rndmEngine, digits.get()); + randomCrossTalk(elemId, ilyr, kWIRE, iwg, posInWG[0], digit_time, wire_timeOffset, rndmEngine, digits.get()); } - + ATH_MSG_DEBUG("WireGroup: newid breakdown digitTime x/y/z direcos height_gang bctag: " - << newId << " " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr << "/" - << sensor << "/" << iwg << " " - << wDigitTime << " " << localPos.x() << "/" << localPos.y() << "/" << localPos.z() << " " - << direCos.x() << "/" << direCos.y() << "/" << direCos.z() << " " - << height << " " << tgcChamber->getNWires(ilyr,iwg) << " " - << bctag); - } - } - else { - ATH_MSG_DEBUG("Wire Gang id is out of range. id, x/y/z, height: " << iwg - << " " << localPos.x() << "/" << localPos.y() << "/" << localPos.z() << " " << height); + << newId << " " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr << "/" + << "WIRE/" << iwg << " " + << digit_time << " " << localPos.x() << "/" << localPos.y() << "/" << localPos.z() << " " + << direCos.x() << "/" << direCos.y() << "/" << direCos.z() << " " + << height << " " << tgcChamber->getNWires(ilyr,iwg) << " " + << bctag); + } + } else { + ATH_MSG_DEBUG("Wire Gang id is out of range. id, x/y/z, height: " << iwg + << " " << localPos.x() << "/" << localPos.y() << "/" << localPos.z() << " " << height); } } } // end of wire group calculation ////////////// strip number calculation ////////////// - sensor = kSTRIP; - m_timeWindowOffsetSensor[sensor] = getTimeWindowOffset(stationName, stationEta, sensor); + TgcSensor sensor = kSTRIP; if((ilyr != 2 || (stationName.compare(0,2,"T1") != 0)) && // no stip in middle layers of T1* ((energyDeposit< -1. && efficiencyCheck(sensor, rndmEngine)) || // Old efficiencyCheck for TGCSimHit_p1. @@ -302,22 +299,20 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, for (int iPosition = 0; iPosition < 2; iPosition++) { // check a hit in the sensitive area - float zPos = zLocal+height/2.-frameZwidth; + float zPos = zLocal+height/2. - zwidth_frame; if (zPos < 0.) { iStrip[iPosition] = 0; posInStrip[iPosition] = 0.; ATH_MSG_DEBUG("Strip: Hit position located at outside of a sensitive volume, id, position, xlocal0/1, dir cosine: " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr << zPos << " " << zLocal << " " << direCos[0] << "/" << direCos[1] << "/" << direCos[2]); - } - else if (zPos > height-frameZwidth*2.) { + } else if (zPos > height - zwidth_frame*2.) { iStrip[iPosition] = tgcChamber -> getNStrips(ilyr) + 1; posInStrip[iPosition] = 0.; ATH_MSG_DEBUG("Strip: Hit position located at outside of a sensitive volume, id, position, active region: " << stationName << "/" << stationEta << "/" << stationPhi << "/" << ilyr - << zPos << " " << height-frameZwidth*2.); - } - else { // sensitive area + << zPos << " " << height-zwidth_frame*2.); + } else { // sensitive area // // for layout P03 @@ -374,48 +369,42 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, ATH_MSG_DEBUG("Multihits found in STRIPs:" << iStr[0] << " " << iStr[1]); } + // BC tagging from the timing + float strip_timeOffset = (TOffset != nullptr) ? this->getTimeOffset(TOffset, iStationName, stationEta, kSTRIP) : 0.; + for(int istr=iStr[0]; istr<=iStr[1]; istr++) { if(1<=istr && istr<=32) { // TGC response time calculation - const float stripPropagationTime = 3.3*CLHEP::ns/CLHEP::m; // 8.5*ns/m was used until MC10. - // Since MC11 3.3*ns/m (the speed of light) is used and was obtained with Z->mumu data/MC comparison. if(jitter > jitterInitial-0.1) { jitter = timeJitter(direCos, rndmEngine); } float zSignEta = (abs(stationEta)%2 == 1 && abs(stationEta) != 5) ? -1. : +1.; // if(abs(stationEta)%2 == 1 && abs(stationEta) != 5) : -1. : ASD attached at the longer base of TGC // else : +1. : ASD attached at the shorter base of TGC - float sTimeDiffByRadiusOfInner = this->timeDiffByCableRadiusOfInner(iStationName, stationPhi, istr); - float sDigitTime = bunchTime + jitter + stripPropagationTime*(height/2. + frameZwidth + zSignEta*zLocal) + sTimeDiffByRadiusOfInner; - float sOffset = m_timeWindowOffsetSensor[sensor]; - float sASDDis{-1000}; - float sSigPropTimeDelay{-1000}; - if (ASDpos != nullptr) { - sASDDis = this->getDistanceToAsdFromSensor(ASDpos, iStationName, abs(stationEta), stationPhi, sensor, istr, getStripPosition(stationName, abs(stationEta), istr)); - float sCableDis = sASDDis + (height/2. + frameZwidth + zSignEta*zLocal)/1000.; - sSigPropTimeDelay = this->getSigPropTimeDelay(sCableDis); - sDigitTime += sSigPropTimeDelay + sASDDis * 5; - sOffset += getASDpropTimeOffset(elemId, (int)sensor, istr); - } + float sTimeDiffByRadiusOfInner = this->timeDiffByCableRadiusOfInner(iStationName, stationPhi, istr); + float sDigitTime = bunchTime + jitter + sensor_propagation_time*(height/2. + zwidth_frame + zSignEta*zLocal) + sTimeDiffByRadiusOfInner; + float sASDDis{-1000}; + if (ASDpos != nullptr) { + sASDDis = this->getDistanceToAsdFromSensor(ASDpos, iStationName, abs(stationEta), stationPhi, sensor, istr, getStripPosition(stationName, abs(stationEta), istr)); + float sCableDis = sASDDis + (height/2. + zwidth_frame + zSignEta*zLocal); + sDigitTime += this->getSigPropTimeDelay(sCableDis) + sASDDis * cable_propagation_time; + } TgcStation station = (m_idHelper->stationName(elemId) > 46) ? kINNER : kOUTER; - uint16_t bctag = bcTagging(sDigitTime,m_gateTimeWindow[station][sensor],sOffset); + uint16_t bctag = bcTagging(sDigitTime,m_gateTimeWindow[station][sensor], strip_timeOffset); if(bctag == 0x0) { ATH_MSG_DEBUG("Strip: Digitized time is outside of time window. " << sDigitTime << " bunchTime: " << bunchTime << " time jitter: " << jitter - << " propagation time: " << stripPropagationTime*(height/2. + frameZwidth + zSignEta*zLocal) - << " signal delay time: " << sSigPropTimeDelay - << " time difference by cable radius of inner station: " << sTimeDiffByRadiusOfInner - << " propagation time to the ASD from the sensor: " << sASDDis * 5); - } - else { + << " propagation time: " << sensor_propagation_time*(height/2. + zwidth_frame + zSignEta*zLocal) + << " time difference by cable radius of inner station: " << sTimeDiffByRadiusOfInner); + } else { Identifier newId = m_idHelper -> channelID(stationName,stationEta,stationPhi, ilyr, (int)sensor, istr); addDigit(newId, bctag, digits.get()); if(istr==iStr[0]) { - randomCrossTalk(elemId, ilyr, sensor, iStr[0], posInStr[0], sDigitTime, sOffset, rndmEngine, digits.get()); + randomCrossTalk(elemId, ilyr, sensor, iStr[0], posInStr[0], sDigitTime, strip_timeOffset, rndmEngine, digits.get()); } ATH_MSG_DEBUG("Strip: newid breakdown digitTime x/y/z direcos r_center bctag: " @@ -426,8 +415,7 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, << height/2.+hmin << " " << bctag); } - } - else { + } else { ATH_MSG_DEBUG("Strip id is out of range: gap, id: " << ilyr << " " << istr); } } @@ -440,7 +428,6 @@ TgcDigitCollection* TgcDigitMaker::executeDigi(const TGCSimHit* hit, //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ StatusCode TgcDigitMaker::readFileOfTimeJitter() { - const char* const fileName = "TGC_Digitization_timejitter.dat"; std::string fileWithPath = PathResolver::find_file (fileName, "DATAPATH"); @@ -503,7 +490,7 @@ float TgcDigitMaker::timeJitter(const Amg::Vector3D& direCosLocal, CLHEP::HepRan while (prob > probRef) { prob = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0); - jitter = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0)*40.; // trial time jitter in nsec + jitter = CLHEP::RandFlat::shoot(rndmEngine, 0.0, 1.0) * 40.*CLHEP::ns; // trial time jitter int ithJitter = static_cast(jitter); // probability distribution calculated from weighted sum between neighboring bins of angles probRef = (1.-wAngle)*m_vecAngle_Time[ithAngle][ithJitter] @@ -823,65 +810,6 @@ StatusCode TgcDigitMaker::readFileOfDeadChamber() { return StatusCode::SUCCESS; } -StatusCode TgcDigitMaker::readFileOfTimeWindowOffset() { - // Indices to be used - int iStationName, stationEta, isStrip; - - for(iStationName=0; iStationName> iStationName >> stationEta >> isStrip >> timeWindowOffset; - ATH_MSG_DEBUG("TgcDigitMaker::readFileOfTimeWindowOffset" - << " stationName= " << iStationName - << " stationEta= " << stationEta - << " isStrip= " << isStrip - << " timeWindowOffset= " << timeWindowOffset); - - // Subtract offsets to use indices of isDeadChamber array - iStationName -= OFFSET_STATIONNAME; - stationEta -= OFFSET_STATIONETA; - isStrip -= OFFSET_ISSTRIP; - - // Check the indices are valid - if(iStationName<0 || iStationName>=N_STATIONNAME) continue; - if(stationEta <0 || stationEta >=N_STATIONETA ) continue; - if(isStrip <0 || isStrip >=N_ISSTRIP ) continue; - - m_timeWindowOffset[iStationName][stationEta][isStrip] = timeWindowOffset; - - // If it is the end of the file, get out from while loop. - if(ifs.eof()) break; - } - - // Close the TGC_Digitization_timeWindowOffset.dat file - ifs.close(); - - return StatusCode::SUCCESS; -} StatusCode TgcDigitMaker::readFileOfAlignment() { // Indices to be used @@ -949,83 +877,12 @@ StatusCode TgcDigitMaker::readFileOfAlignment() { if(ifs.eof()) break; } - // Close the TGC_Digitization_timeWindowOffset.dat file + // Close the TGC_Digitization_alignment.dat file ifs.close(); return StatusCode::SUCCESS; } -StatusCode TgcDigitMaker::readFileOfASDpropTimeOffset() { - // Indices to be used - int iStationName = -1; - int stationEta = -1; - int isStrip = -1; - int asdnum = -1; - - for(iStationName=0; iStationName> iStationName >> stationEta >> isStrip >> asdnum >> max_ch >> asd_propTimeOffset; - ATH_MSG_DEBUG("readFileOfASDpropTimeOffset" - << " stationName= " << iStationName - << " stationEta= " << stationEta - << " isStrip= " << isStrip - << " asdnum= " << asdnum - << " max_ch= " << max_ch - << " asd_propTimeOffset= " << asd_propTimeOffset); - - // Subtract offsets to use indices of ASDpropTimeOffset array - iStationName -= OFFSET_STATIONNAME; - stationEta -= OFFSET_STATIONETA; - isStrip -= OFFSET_ISSTRIP; - asdnum -= OFFSET_ASDNUM; - - // Check the indices are valid - if(iStationName<0 || iStationName>=N_STATIONNAME) continue; - if(stationEta <0 || stationEta >=N_STATIONETA ) continue; - if(isStrip <0 || isStrip >=N_ISSTRIP ) continue; - if(asdnum <0 || asdnum >=N_ASDNUM ) continue; - - m_maxch[iStationName][stationEta][isStrip][asdnum] = max_ch; - m_ASDpropTimeOffset[iStationName][stationEta][isStrip][asdnum] = asd_propTimeOffset; - - // If it is the end of the file, get out from while loop. - if(ifs.eof()) break; - } - - // Close the TGC_Digitization_ASDpropTimeOffset.dat file - ifs.close(); - - return StatusCode::SUCCESS; -} StatusCode TgcDigitMaker::readFileOfStripPosition() { //Indices to be used @@ -1218,22 +1075,6 @@ bool TgcDigitMaker::isDeadChamber(const std::string& stationName, int stationEta return v_isDeadChamber; } -double TgcDigitMaker::getTimeWindowOffset(const std::string& stationName, int stationEta, const TgcSensor sensor) const { - // Convert std::string stationName to int iStationName from 41 to 48 - int iStationName = getIStationName(stationName); - - // Subtract offsets to use these as the indices of the energyThreshold array - iStationName -= OFFSET_STATIONNAME; - stationEta -= OFFSET_STATIONETA; - - // Check the indices are valid - if(iStationName<0 || iStationName>=N_STATIONNAME) return 0.; - if(stationEta <0 || stationEta >=N_STATIONETA ) return 0.; - - // Values were determined to reproduce the fraction of Previous BC hit fraction in Z->mumu data during Periods B,D,E in 2011. - return m_timeWindowOffset[iStationName][stationEta][sensor]; -} - int TgcDigitMaker::getIStationName(const std::string& stationName) const { int iStationName = 0; if( stationName=="T1F") iStationName = 41; @@ -1283,32 +1124,6 @@ void TgcDigitMaker::adHocPositionShift(const std::string& stationName, int stati localPos.z() = localPos.z()+localDisplacementZByX-localDisplacementZ; } -float TgcDigitMaker::getASDpropTimeOffset(const Identifier elemId, - const int isStrip, - const int channel) const -{ - int StationName = m_idHelper->stationName(elemId) - OFFSET_STATIONNAME; - int stationEta = m_idHelper->stationEta(elemId) - OFFSET_STATIONETA; - int stationPhi = m_idHelper->stationPhi(elemId) - OFFSET_STATIONPHI; - int iIsStrip = isStrip - OFFSET_ISSTRIP; - - std::array maxch{}; - double asdpropTimeOffset = 0.; - - if((StationName>=0 && StationName=0 && stationEta =0 && stationPhi 16 && channel < 27)) { int cablenum = (stationPhi >= 13) ? 25 - stationPhi : stationPhi; - return 2.3 - 0.06 * cablenum; + delay += 2.3*CLHEP::ns - 0.06*CLHEP::ns * float(cablenum); } - return 0.0; + return delay; } -float TgcDigitMaker::getSigPropTimeDelay(const float cableDistance) const { - - return 0.0049 * std::pow(cableDistance, 2) + 0.0002 * cableDistance; +double TgcDigitMaker::getSigPropTimeDelay(const float cableDistance) const { + constexpr std::array par{0.0049 * CLHEP::ns, 0.0002 * CLHEP::ns}; + return par[0] * std::pow(cableDistance / CLHEP::m, 2) + par[1] * cableDistance / CLHEP::m; } float TgcDigitMaker::getDistanceToAsdFromSensor(const TgcDigitASDposData* readCdo, @@ -1351,23 +1167,31 @@ float TgcDigitMaker::getDistanceToAsdFromSensor(const TgcDigitASDposData* readCd const TgcSensor sensor, const int channel, const float position) const { + // EIFI has different parameter for phi, BW is same parameter for phi (i.e. -99 in DB). + int phiId = (iStationName >= 47) ? stationPhi : 0x1f; + uint16_t chamberId = (iStationName << 8) + (stationEta << 5) + phiId; - int phiId = (iStationName >= 47) ? stationPhi : -99; - int dbNum = -99; + unsigned int asdNo = static_cast(channel-1) / TgcDigitASDposData::N_CHANNELINPUT_TOASD; - for(unsigned int i_dbNum=0;i_dbNumstationNum.size();i_dbNum++) { - if(iStationName != readCdo->stationNum.at(i_dbNum)) continue; - if(stationEta != readCdo->stationEta.at(i_dbNum)) continue; - if(phiId != readCdo->stationPhi.at(i_dbNum)) continue; - dbNum = i_dbNum; - break; - } + float asd_position = 0.; + auto it = (sensor == kSTRIP) ? readCdo->stripAsdPos.find(chamberId) : readCdo->wireAsdPos.find(chamberId); - unsigned int asdNum[TgcSensor::N_SENSOR]; - asdNum[TgcSensor::kSTRIP] = (channel-1) / TgcDigitASDposData::N_CHANNELINPUT_TOASD; - asdNum[TgcSensor::kWIRE] = (channel-1) / TgcDigitASDposData::N_CHANNELINPUT_TOASD + TgcDigitASDposData::N_STRIPASDPOS; + if ((sensor == kSTRIP && it != readCdo->stripAsdPos.end()) || + (sensor == kWIRE && it != readCdo->wireAsdPos.end())) { + asd_position = it->second[asdNo] * CLHEP::m; + } else { + ATH_MSG_WARNING("Undefined chamberID is provided! station=" << iStationName <<", eta=" << stationEta << ", phi=" << phiId); + } - float disToAsd = fabs( position*CLHEP::mm/CLHEP::m - readCdo->asdPos[ asdNum[sensor] ][dbNum] ); + float distance = fabs(position - asd_position); + return distance; +} - return disToAsd; +float TgcDigitMaker::getTimeOffset(const TgcDigitTimeOffsetData* readCdo, + const uint16_t station_num, + const int station_eta, + const TgcSensor sensor) const { + uint16_t chamberId = (station_num << 3) + static_cast(std::abs(station_eta)); + return ((sensor == TgcSensor::kSTRIP) ? readCdo->stripOffset.find(chamberId)->second : readCdo->wireOffset.find(chamberId)->second); } + diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.h b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.h index f1f1f013ffcd6be149c7b03a6aacb36e2a4e5f8c..2507d2c6c5bede21c8aa2af23e05166b971c14c5 100644 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.h +++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitMaker.h @@ -20,6 +20,7 @@ #include "GeoPrimitives/GeoPrimitives.h" #include "Identifier/Identifier.h" #include "MuonCondData/TgcDigitASDposData.h" +#include "MuonCondData/TgcDigitTimeOffsetData.h" namespace CLHEP { class HepRandomEngine; @@ -36,9 +37,7 @@ class TGCSimHit; //--- class description class TgcDigitMaker : public AthMessaging { - //------ for public public: - TgcDigitMaker(TgcHitIdHelper* hitIdHelper, const MuonGM::MuonDetectorManager * mdManager, unsigned int runperiod); @@ -78,6 +77,7 @@ class TgcDigitMaker : public AthMessaging { TgcDigitCollection* executeDigi(const TGCSimHit* hit, const double globalHitTime, const TgcDigitASDposData* ASDpos, + const TgcDigitTimeOffsetData* TOffset, CLHEP::HepRandomEngine* rndmEngine); //====== for private @@ -137,12 +137,8 @@ class TgcDigitMaker : public AthMessaging { StatusCode readFileOfCrossTalk(); /** Read share/TGC_Digitization_deadChamber.dat file */ StatusCode readFileOfDeadChamber(); - /** Read share/TGC_Digitization_timeWindowOffset.dat file */ - StatusCode readFileOfTimeWindowOffset(); /** Read share/TGC_Digitization_alignment.dat file */ StatusCode readFileOfAlignment(); - /** Read share/TGC_Digitization_ASDpropTimeOffset.dat file */ - StatusCode readFileOfASDpropTimeOffset(); /** Read share/TGC_Digitization_StripPosition.dat file */ StatusCode readFileOfStripPosition(); @@ -153,32 +149,29 @@ class TgcDigitMaker : public AthMessaging { const float time_offset, CLHEP::HepRandomEngine* rndmEngine, TgcDigitCollection* digits) const; /** Method to check a chamber is dead or active */ bool isDeadChamber(const std::string& stationName, int stationEta, int stationPhi, int gasGap); - /** Method to get time window offset */ - double getTimeWindowOffset(const std::string& stationName, int stationEta, const TgcSensor sensor) const; /** Get stationName integer from stationName string */ int getIStationName(const std::string& staionName) const; /** Ad hoc implementation of detector position shift */ void adHocPositionShift(const std::string& stationName, int stationEta, int stationPhi, const Amg::Vector3D& direCos, Amg::Vector3D &localPos) const; - /** Method to get propagation time offset of the ASD */ - float getASDpropTimeOffset(const Identifier elemId, const int isStrip, const int channel) const; /** Method to get position of Strip channel */ float getStripPosition(const std::string& stationName, int stationEta, int channel) const; /** Method to get signal propagation time delay */ - float getSigPropTimeDelay(const float cableDistance) const; + double getSigPropTimeDelay(const float cableDistance) const; /** Method to get time difference by cable radius of inner */ float timeDiffByCableRadiusOfInner(const int iStationName, const int stationPhi, const int channel) const; /** Method to get propagation time to the ASD from the sensor */ float getDistanceToAsdFromSensor(const TgcDigitASDposData* readCdo, const int iStationName, const int stationEta, const int stationPhi, const TgcSensor sensor, const int channel, const float position) const; + /** Method to get time offset to absorb signal delay */ + float getTimeOffset(const TgcDigitTimeOffsetData* readCdo, const uint16_t station_num, const int station_eta, const TgcSensor sensor) const; + private: /** Energy threshold value for each chamber */ double m_energyThreshold[N_STATIONNAME][N_STATIONETA][N_STATIONPHI][N_GASGAP][N_ISSTRIP]{}; /** Cross talk probabilty for each chamber */ double m_crossTalk[N_STATIONNAME][N_STATIONETA][N_STATIONPHI][N_GASGAP][N_ISSTRIP][N_CROSSTALK_PARAMETER]{}; /** Dead chamber flag for each chamber */ bool m_isDeadChamber[N_STATIONNAME][N_STATIONETA][N_STATIONPHI][N_GASGAP]{}; - /** Time window offset for each chamber */ - double m_timeWindowOffset[N_STATIONNAME][N_STATIONETA][N_ISSTRIP]{}; /** Alignment z constants. Translation in the global r direction */ double m_alignmentZ[N_STATIONNAME][N_STATIONETA][N_STATIONPHI]{}; @@ -191,8 +184,6 @@ class TgcDigitMaker : public AthMessaging { /** Position of Strip Channel (Longer base or Shorter base) */ float m_StripPos[N_STATIONNAME][N_ABSSTATIONETA][N_STRIPCHANNEL]{}; - /** ASD propagation time offset for each chamber */ - float m_ASDpropTimeOffset[N_STATIONNAME][N_STATIONETA][N_ISSTRIP][N_ASDNUM]{}; /** max channel for ASD */ float m_maxch[N_STATIONNAME][N_STATIONETA][N_ISSTRIP][N_ASDNUM]{}; @@ -205,12 +196,11 @@ class TgcDigitMaker : public AthMessaging { float m_efficiency[N_SENSOR]{}; /** - define offsets and widths of time windows for signals from + define the time windows for signals from wiregangs and strips. The offsets are defined as relative time - diffference with respect to the time after TOF and cable + differences with respect to the time after TOF and cable length corrections. Bunch crossing time is specified. */ - double m_timeWindowOffsetSensor[N_SENSOR]{}; double m_gateTimeWindow[N_STATION][N_SENSOR]{}; double m_bunchCrossingTime; }; diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx index e6dde2c47a8956bc6cfbdd66eb93b26ec32c1207..7751183f86df6ad996a2e80bca87ff324f88d032 100644 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx +++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.cxx @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ #include "TgcDigitizationTool.h" @@ -68,6 +68,7 @@ StatusCode TgcDigitizationTool::initialize() // Initialize Read(Cond)HandleKey ATH_CHECK(m_hitsContainerKey.initialize(true)); ATH_CHECK(m_readCondKey_ASDpos.initialize(!m_readCondKey_ASDpos.empty())); + ATH_CHECK(m_readCondKey_TimeOffset.initialize(!m_readCondKey_TimeOffset.empty())); //initialize the output WriteHandleKeys ATH_CHECK(m_outputDigitCollectionKey.initialize()); @@ -289,8 +290,18 @@ StatusCode TgcDigitizationTool::digitizeCore(const EventContext& ctx) { if (!m_readCondKey_ASDpos.empty()) { SG::ReadCondHandle readHandle_ASDpos{m_readCondKey_ASDpos, ctx}; ASDpos = readHandle_ASDpos.cptr(); + } else { + ATH_MSG_ERROR("ASD Position parameters /TGC/DIGIT/ASDPOS must be available for TGC_Digitization. Check the configuration!"); } - + const TgcDigitTimeOffsetData *TOffset{}; + if (!m_readCondKey_TimeOffset.empty()) { + SG::ReadCondHandle readHandle_TimeOffset{m_readCondKey_TimeOffset, ctx}; + TOffset = readHandle_TimeOffset.cptr(); + } else { + ATH_MSG_ERROR("Timing Offset parameters /TGC/DIGIT/TOFFSET must be available for TGC_Digitization. Check the configuration!"); + } + + TimedHitCollection::const_iterator i, e; while(m_thpcTGC->nextDetectorElement(i, e)) { ATH_MSG_DEBUG("TgcDigitizationTool::digitizeCore next element"); @@ -301,7 +312,7 @@ StatusCode TgcDigitizationTool::digitizeCore(const EventContext& ctx) { const TGCSimHit& hit = *phit; double globalHitTime = hitTime(phit); double tof = phit->globalTime(); - TgcDigitCollection* digiHits = m_digitizer->executeDigi(&hit, globalHitTime, ASDpos, rndmEngine); + TgcDigitCollection* digiHits = m_digitizer->executeDigi(&hit, globalHitTime, ASDpos, TOffset, rndmEngine); if(!digiHits) continue; diff --git a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h index e09554a1ea556a285d61c3309d64913e7bde1ad9..a4b1a4fc2c4f514c2e2a6c2207207161785fefa7 100644 --- a/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h +++ b/MuonSpectrometer/MuonDigitization/TGC_Digitization/src/TgcDigitizationTool.h @@ -1,7 +1,7 @@ /* -*- C++ -*- */ /* - Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration */ #ifndef MUONDIGITIZATION_TGC_DIGITIZATIONTOOL_H @@ -23,6 +23,7 @@ #include "MuonDigitContainer/TgcDigitContainer.h" #include "MuonSimData/MuonSimDataCollection.h" #include "MuonCondData/TgcDigitASDposData.h" +#include "MuonCondData/TgcDigitTimeOffsetData.h" class PileUpMergeSvc; class TgcDigitMaker; @@ -93,6 +94,7 @@ private: SG::ReadHandleKey m_hitsContainerKey{this, "InputObjectName", "TGC_Hits", "name of the input object"}; std::string m_inputHitCollectionName{""}; SG::ReadCondHandleKey m_readCondKey_ASDpos{this,"TGCDigitASDposKey","","ReadCondHandleKey for TGCDigitASDposData"}; + SG::ReadCondHandleKey m_readCondKey_TimeOffset{this,"TGCDigitTimeOffsetKey","","ReadCondHandleKey for TGCDigitTimeOffsetData"}; SG::WriteHandleKey m_outputDigitCollectionKey{this,"OutputObjectName","TGC_DIGITS","WriteHandleKey for Output TgcDigitContainer"}; // name of the output digits SG::WriteHandleKey m_outputSDO_CollectionKey{this,"OutputSDOName","TGC_SDO","WriteHandleKey for Output MuonSimDataCollection"}; // name of the output SDOs diff --git a/Simulation/Digitization/test/test_MC16a_Digi_tf_configuration.py b/Simulation/Digitization/test/test_MC16a_Digi_tf_configuration.py index f6cadc0cf20341e00e04ad255dfd9cdbdca7189c..96deaf691e418e31290cfd8403ec8e81d5247994 100755 --- a/Simulation/Digitization/test/test_MC16a_Digi_tf_configuration.py +++ b/Simulation/Digitization/test/test_MC16a_Digi_tf_configuration.py @@ -338,7 +338,7 @@ class TestDigitizationMC16a(unittest.TestCase): def test___TgcDigitizationTool_properties(self): tested_configurable_name = 'StandardSignalOnlyTruthPileUpToolsAlg.TgcDigitizationTool' - expected_property_list = ['DetStore', 'EvtStore', 'ExtraInputs', 'ExtraOutputs', 'FirstXing', 'InputObjectName', 'LastXing', 'OutputObjectName', 'OutputSDOName', 'PileUpMergeSvc', 'RndmSvc', 'TGCDigitASDposKey'] + expected_property_list = ['DetStore', 'EvtStore', 'ExtraInputs', 'ExtraOutputs', 'FirstXing', 'InputObjectName', 'LastXing', 'OutputObjectName', 'OutputSDOName', 'PileUpMergeSvc', 'RndmSvc', 'TGCDigitASDposKey', 'TGCDigitTimeOffsetKey'] expected_nonstring_properties = {'LastXing': '75', 'FirstXing': '-50'} expected_string_properties = {} # Not checking any specific property values self._detailed_ConfigurablePropertiesCheck(