From 22b0e9a62e4b0e4bd7f7df587c9d45297335fae9 Mon Sep 17 00:00:00 2001 From: Andreas Molander Date: Wed, 29 Nov 2023 23:34:56 +0200 Subject: [PATCH] FIT: Base TOF for sim hits on hit pos instead of fixed detector pos - Estimate time-of-flight for MC hits based on location of the hits, instead of hard coded detector locations. This way the TOF is compensated for, when detector geometries are misaligned. - Add additional config parameters for hit time offset (should it be needed). --- .../FIT/FDD/base/include/FDDBase/Constants.h | 15 --------- Detectors/FIT/FDD/simulation/CMakeLists.txt | 21 ++++++------ .../include/FDDSimulation/FDDDigParam.h | 32 +++++++++++++++++++ .../FIT/FDD/simulation/src/Digitizer.cxx | 12 +++++-- .../FDD/simulation/src/FDDSimulationLinkDef.h | 1 + .../FT0/base/include/FT0Base/FT0DigParam.h | 6 ++-- .../FIT/FT0/simulation/src/Digitizer.cxx | 12 +++++-- .../include/FV0Simulation/Digitizer.h | 12 +++++-- .../include/FV0Simulation/FV0DigParam.h | 11 ++++--- .../FIT/FV0/simulation/src/Digitizer.cxx | 19 ++++++----- 10 files changed, 94 insertions(+), 47 deletions(-) create mode 100644 Detectors/FIT/FDD/simulation/include/FDDSimulation/FDDDigParam.h diff --git a/Detectors/FIT/FDD/base/include/FDDBase/Constants.h b/Detectors/FIT/FDD/base/include/FDDBase/Constants.h index d15da52232af3..f3c315457c46d 100644 --- a/Detectors/FIT/FDD/base/include/FDDBase/Constants.h +++ b/Detectors/FIT/FDD/base/include/FDDBase/Constants.h @@ -37,21 +37,6 @@ constexpr float PMNbOfSecElec = 6.0; // Number of secondary electrons e constexpr int NTimeBinsPerBC = 256; // number of samples per BC -// Detector TOF correction in ns -constexpr float FDAdist = 1696.67; -constexpr float FDCdist = 1954.4; -constexpr float LayerWidth = 1.27; - -constexpr float getTOFCorrection(int det) -{ - constexpr float TOFCorr[4] = { - (FDCdist + LayerWidth) / o2::constants::physics::LightSpeedCm2NS, - (FDCdist - LayerWidth) / o2::constants::physics::LightSpeedCm2NS, - (FDAdist - LayerWidth) / o2::constants::physics::LightSpeedCm2NS, - (FDAdist + LayerWidth) / o2::constants::physics::LightSpeedCm2NS}; - return TOFCorr[det]; -} - } // namespace fdd } // namespace o2 diff --git a/Detectors/FIT/FDD/simulation/CMakeLists.txt b/Detectors/FIT/FDD/simulation/CMakeLists.txt index 0179b6bbe1e10..ec217c4419830 100644 --- a/Detectors/FIT/FDD/simulation/CMakeLists.txt +++ b/Detectors/FIT/FDD/simulation/CMakeLists.txt @@ -11,22 +11,25 @@ o2_add_library(FDDSimulation SOURCES src/Detector.cxx - src/Digitizer.cxx - PUBLIC_LINK_LIBRARIES O2::SimulationDataFormat - O2::FDDBase - O2::DataFormatsFDD - O2::DetectorsRaw - O2::DetectorsBase - ROOT::Physics) + src/Digitizer.cxx + PUBLIC_LINK_LIBRARIES O2::CommonUtils + O2::SimulationDataFormat + O2::FDDBase + O2::DataFormatsFDD + O2::DetectorsRaw + O2::DetectorsBase + ROOT::Physics) o2_target_root_dictionary(FDDSimulation HEADERS include/FDDSimulation/Detector.h - include/FDDSimulation/Digitizer.h - include/FDDSimulation/DigitizationParameters.h) + include/FDDSimulation/Digitizer.h + include/FDDSimulation/DigitizationParameters.h + include/FDDSimulation/FDDDigParam.h) o2_add_executable(digit2raw COMPONENT_NAME fdd SOURCES src/digit2raw.cxx PUBLIC_LINK_LIBRARIES O2::FDDRaw Boost::program_options) + o2_data_file(COPY data DESTINATION Detectors/FDD/simulation) \ No newline at end of file diff --git a/Detectors/FIT/FDD/simulation/include/FDDSimulation/FDDDigParam.h b/Detectors/FIT/FDD/simulation/include/FDDSimulation/FDDDigParam.h new file mode 100644 index 0000000000000..b927c54b2a2d1 --- /dev/null +++ b/Detectors/FIT/FDD/simulation/include/FDDSimulation/FDDDigParam.h @@ -0,0 +1,32 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file FDDDigParam.h +/// \brief Configurable digitization parameters +/// +/// \author Andreas Molander + +#ifndef ALICEO2_FDD_DIG_PARAM +#define ALICEO2_FDD_DIG_PARAM + +#include "CommonUtils/ConfigurableParamHelper.h" + +namespace o2::fdd +{ +struct FDDDigParam : o2::conf::ConfigurableParamHelper { + float hitTimeOffsetA = 0; ///< Hit time offset on the A side [ns] + float hitTimeOffsetC = 0; ///< Hit time offset on the C side [ns] + + O2ParamDef(FDDDigParam, "FDDDigParam"); +}; +} // namespace o2::fdd + +#endif // ALICEO2_FDD_DIG_PARAM diff --git a/Detectors/FIT/FDD/simulation/src/Digitizer.cxx b/Detectors/FIT/FDD/simulation/src/Digitizer.cxx index adb056792d8e4..403c0b4c0a0e6 100644 --- a/Detectors/FIT/FDD/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FDD/simulation/src/Digitizer.cxx @@ -10,8 +10,10 @@ // or submit itself to any jurisdiction. #include "FDDSimulation/Digitizer.h" + +#include "CommonDataFormat/InteractionRecord.h" +#include "FDDSimulation/FDDDigParam.h" #include "SimulationDataFormat/MCTruthContainer.h" -#include #include "TMath.h" #include "TRandom.h" @@ -66,7 +68,11 @@ void Digitizer::process(const std::vector& hits, double delayScintillator = mRndScintDelay.getNextValue(); double timeHit = delayScintillator + hit.GetTime(); - timeHit -= getTOFCorrection(int(iChannel / 4)); // account for TOF to detector + // Subtract time-of-flight from hit time + const float timeOfFlight = hit.GetPos().R() / o2::constants::physics::LightSpeedCm2NS; + const float timeOffset = iChannel < 8 ? FDDDigParam::Instance().hitTimeOffsetC : FDDDigParam::Instance().hitTimeOffsetA; + + timeHit += -timeOfFlight + timeOffset; timeHit += mIntRecord.getTimeNS(); o2::InteractionRecord irHit(timeHit); // BC in which the hit appears (might be different from interaction BC for slow particles) @@ -420,3 +426,5 @@ void Digitizer::BCCache::print() const printf("\n"); } } + +O2ParamImpl(FDDDigParam); \ No newline at end of file diff --git a/Detectors/FIT/FDD/simulation/src/FDDSimulationLinkDef.h b/Detectors/FIT/FDD/simulation/src/FDDSimulationLinkDef.h index 9f57fa111c081..30f111c5ad2bf 100644 --- a/Detectors/FIT/FDD/simulation/src/FDDSimulationLinkDef.h +++ b/Detectors/FIT/FDD/simulation/src/FDDSimulationLinkDef.h @@ -19,6 +19,7 @@ #pragma link C++ class o2::base::DetImpl < o2::fdd::Detector> + ; #pragma link C++ class o2::fdd::Digitizer + ; #pragma link C++ class o2::fdd::DigitizationParameters + ; +#pragma link C++ class o2::fdd::FDDDigParam + ; #pragma link C++ class o2::dataformats::MCTruthContainer < o2::fdd::MCLabel> + ; #endif diff --git a/Detectors/FIT/FT0/base/include/FT0Base/FT0DigParam.h b/Detectors/FIT/FT0/base/include/FT0Base/FT0DigParam.h index fb8b6492354f1..1750aa0ef9233 100644 --- a/Detectors/FIT/FT0/base/include/FT0Base/FT0DigParam.h +++ b/Detectors/FIT/FT0/base/include/FT0Base/FT0DigParam.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file FT0DigParam.h +/// \file FT0DigParam.h /// \brief Configurable digitization parameters #ifndef ALICEO2_FT0_DIG_PARAM @@ -29,8 +29,8 @@ struct FT0DigParam : o2::conf::ConfigurableParamHelper { float mAmp_trsh = 100; // [ph.e] float mAmpRecordLow = -4; // integrate charge from float mAmpRecordUp = 15; // to [ns] - float mC_side_cable_cmps = 2.86; // ns - float mA_side_cable_cmps = 11.110; // ns + float hitTimeOffsetA = 0; ///< hit time offset on the A side [ns] + float hitTimeOffsetC = 0; ///< hit time offset on the C side [ns] int mtrg_central_trh = 600.; // channels int mtrg_semicentral_trh = 300.; // channels diff --git a/Detectors/FIT/FT0/simulation/src/Digitizer.cxx b/Detectors/FIT/FT0/simulation/src/Digitizer.cxx index 583f62019f8a0..32111431cf653 100644 --- a/Detectors/FIT/FT0/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FT0/simulation/src/Digitizer.cxx @@ -13,7 +13,8 @@ #include "FT0Simulation/DigitizationConstants.h" #include "FT0Base/FT0DigParam.h" #include "SimulationDataFormat/MCTruthContainer.h" -#include +#include "CommonConstants/PhysicsConstants.h" +#include "CommonDataFormat/InteractionRecord.h" #include "TMath.h" #include "TRandom.h" @@ -207,11 +208,16 @@ void Digitizer::process(const std::vector* hits, const auto& params = FT0DigParam::Instance(); Int_t hit_ch = hit.GetDetectorID(); Bool_t is_A_side = (hit_ch < 4 * mGeometry.NCellsA); - Float_t time_compensate = is_A_side ? params.mA_side_cable_cmps : params.mC_side_cable_cmps; - Double_t hit_time = hit.GetTime() - time_compensate; + + // Subtract time-of-flight from hit time + const Float_t timeOfFlight = hit.GetPos().R() / o2::constants::physics::LightSpeedCm2NS; + const Float_t timeOffset = is_A_side ? params.hitTimeOffsetA : params.hitTimeOffsetC; + Double_t hit_time = hit.GetTime() - timeOfFlight + timeOffset; + if (hit_time > 150) { continue; // not collect very slow particles } + auto relBC = o2::InteractionRecord{hit_time}; if (mCache.size() <= relBC.bc) { mCache.resize(relBC.bc + 1); diff --git a/Detectors/FIT/FV0/simulation/include/FV0Simulation/Digitizer.h b/Detectors/FIT/FV0/simulation/include/FV0Simulation/Digitizer.h index 3d36f255d5094..6956d8126ce53 100644 --- a/Detectors/FIT/FV0/simulation/include/FV0Simulation/Digitizer.h +++ b/Detectors/FIT/FV0/simulation/include/FV0Simulation/Digitizer.h @@ -90,8 +90,16 @@ class Digitizer private: static constexpr int BCCacheMin = 0, BCCacheMax = 7, NBC2Cache = 1 + BCCacheMax - BCCacheMin; - void createPulse(float mipFraction, int parID, const double hitTime, std::array const& cachedIR, - int nCachedIR, const int detID); + /// Create signal pulse based on MC hit + /// \param mipFraction Fraction of the MIP energy deposited in the cell + /// \param parID Particle ID + /// \param hitTime Time of the hit + /// \param hitR Length to IP from the position of the hit + /// \param cachedIR Cached interaction records + /// \param nCachedIR Number of cached interaction records + /// \param detID Detector cell ID + void createPulse(float mipFraction, int parID, const double hitTime, const float hitR, + std::array const& cachedIR, int nCachedIR, const int detID); long mTimeStamp; // TF (run) timestamp InteractionTimeRecord mIntRecord; // Interaction record (orbit, bc) -> InteractionTimeRecord diff --git a/Detectors/FIT/FV0/simulation/include/FV0Simulation/FV0DigParam.h b/Detectors/FIT/FV0/simulation/include/FV0Simulation/FV0DigParam.h index 347f2e7bb707a..1dac216871c68 100644 --- a/Detectors/FIT/FV0/simulation/include/FV0Simulation/FV0DigParam.h +++ b/Detectors/FIT/FV0/simulation/include/FV0Simulation/FV0DigParam.h @@ -9,7 +9,7 @@ // granted to it by virtue of its status as an Intergovernmental Organization // or submit itself to any jurisdiction. -/// \file FV0DigParam.h +/// \file FV0DigParam.h /// \brief Configurable digitization parameters #ifndef ALICEO2_FV0_DIG_PARAM @@ -22,9 +22,11 @@ namespace o2::fv0 { // parameters of FV0 digitization / transport simulation struct FV0DigParam : o2::conf::ConfigurableParamHelper { - float photoCathodeEfficiency = 0.23; // quantum efficiency = nOfPhotoE_emitted_by_photocathode / nIncidentPhotons - float lightYield = 0.01; // light collection efficiency to be tuned using collision data [1%] - float adcChannelsPerMip = 16; // Default: 16 for pp and 8 for PbPb + float hitTimeOffset = 0.0; ///< Hit time offset [ns] + + float photoCathodeEfficiency = 0.23; // quantum efficiency = nOfPhotoE_emitted_by_photocathode / nIncidentPhotons + float lightYield = 0.01; // light collection efficiency to be tuned using collision data [1%] + float adcChannelsPerMip = 16; // Default: 16 for pp and 8 for PbPb float getChannelsPerMilivolt() const { return adcChannelsPerMip / 7.5; } // Non-trivial conversion depending on the pulseshape: amplitude to charge float chargeThrForMeanTime = 5; // Charge threshold, only above which the time is taken into account in calculating the mean time of all qualifying channels @@ -55,7 +57,6 @@ struct FV0DigParam : o2::conf::ConfigurableParamHelper { bool isIntegrateFull = false; // Full charge integration widow in 25 ns float cfdCheckWindow = 2.5; // time window for the cfd in ns to trigger the charge integration int avgNumberPhElectronPerMip = 201; // avg number of photo-electrons per MIP - float globalTimeOfFlight = 315.0 / o2::constants::physics::LightSpeedCm2NS; // TODO [check the correct value for distance of FV0 to IP] float mCfdDeadTime = 15.6; // [ns] float mCFD_trsh = 3.; // [mV] float getCFDTrshInAdc() const { return mCFD_trsh * getChannelsPerMilivolt(); } // [ADC channels] diff --git a/Detectors/FIT/FV0/simulation/src/Digitizer.cxx b/Detectors/FIT/FV0/simulation/src/Digitizer.cxx index 184e6dbbd09f8..1c94b14f029cf 100644 --- a/Detectors/FIT/FV0/simulation/src/Digitizer.cxx +++ b/Detectors/FIT/FV0/simulation/src/Digitizer.cxx @@ -98,8 +98,8 @@ void Digitizer::process(const std::vector& hits, for (auto ids : hitIdx) { const auto& hit = hits[ids]; Int_t detId = hit.GetDetectorID(); - Double_t hitEdep = hit.GetHitValue() * 1e3; //convert to MeV - Float_t const hitTime = hit.GetTime() * 1e9; + Double_t hitEdep = hit.GetHitValue() * 1e3; // convert to MeV + Float_t const hitTime = hit.GetTime() * 1e9; // convert to ns // TODO: check how big is inaccuracy if more than 1 'below-threshold' particles hit the same detector cell if (hitEdep < FV0DigParam::Instance().singleMipThreshold || hitTime > FV0DigParam::Instance().singleHitTimeThreshold) { continue; @@ -138,15 +138,17 @@ void Digitizer::process(const std::vector& hits, if (tNS < 0 && cachedIR[nCachedIR] > irHit) { continue; // don't go to negative BC/orbit (it will wrap) } - setBCCache(cachedIR[nCachedIR++]); // ensure existence of cached container - } //BCCache loop - createPulse(mipFraction, hit.GetTrackID(), hitTime, cachedIR, nCachedIR, detId); + // ensure existence of cached container + setBCCache(cachedIR[nCachedIR++]); + } // BCCache loop + + createPulse(mipFraction, hit.GetTrackID(), hitTime, hit.GetPos().R(), cachedIR, nCachedIR, detId); } //while loop } //hitloop } -void Digitizer::createPulse(float mipFraction, int parID, const double hitTime, +void Digitizer::createPulse(float mipFraction, int parID, const double hitTime, const float hitR, std::array const& cachedIR, int nCachedIR, const int detId) { @@ -160,8 +162,9 @@ void Digitizer::createPulse(float mipFraction, int parID, const double hitTime, } } - ///Time of flight subtracted from Hit time //TODO have different TOF according to thr ring number - Int_t const NBinShift = std::lround((hitTime - FV0DigParam::Instance().globalTimeOfFlight) / FV0DigParam::Instance().waveformBinWidth); + // Subtract time-of-flight from hit time + const float timeOfFlight = hitR / o2::constants::physics::LightSpeedCm2NS; + Int_t const NBinShift = std::lround((hitTime - timeOfFlight + FV0DigParam::Instance().hitTimeOffset) / FV0DigParam::Instance().waveformBinWidth); if (NBinShift >= 0 && NBinShift < FV0DigParam::Instance().waveformNbins) { mPmtResponseTemp.resize(FV0DigParam::Instance().waveformNbins, 0.);