diff --git a/Detectors/TRD/simulation/include/TRDSimulation/Digitizer.h b/Detectors/TRD/simulation/include/TRDSimulation/Digitizer.h index b5c3f6ec49390..3cb901fc94a61 100644 --- a/Detectors/TRD/simulation/include/TRDSimulation/Digitizer.h +++ b/Detectors/TRD/simulation/include/TRDSimulation/Digitizer.h @@ -22,6 +22,8 @@ #include "DataFormatsTRD/Digit.h" #include "DataFormatsTRD/SignalArray.h" #include "DataFormatsTRD/Constants.h" +#include "DataFormatsTRD/CalVdriftExB.h" +#include "DataFormatsTRD/CalGain.h" #include "MathUtils/RandomRing.h" #include "SimulationDataFormat/MCTruthContainer.h" @@ -62,18 +64,35 @@ class Digitizer void setEventID(int entryID) { mEventID = entryID; } void setSrcID(int sourceID) { mSrcID = sourceID; } void setCalibrations(Calibrations* calibrations) { mCalib = calibrations; } + void setCalVdriftExB(const CalVdriftExB* calVdriftExB) { mCalVdriftExB = calVdriftExB; } + void setFedChamberStatus(int det, int value) + { + if (det >= constants::MAXCHAMBER) + return; + mFedChamberStatus[det] = value; + } + void setCalGain(const CalGain* calGain) { mCalGain = calGain; } void setCreateSharedDigits(bool flag) { mCreateSharedDigits = flag; } int getEventTime() const { return mTime; } int getEventID() const { return mEventID; } int getSrcID() const { return mSrcID; } bool getCreateSharedDigits() const { return mCreateSharedDigits; } + int getFedChamberStatus(int det) + { + if (det >= constants::MAXCHAMBER) + return -1.; + return mFedChamberStatus[det]; + } std::string dumpFlaggedChambers() const; private: - Geometry* mGeo = nullptr; // access to Geometry - PadResponse mPRF{}; // access to PadResponse - SimParam mSimParam{}; // simulation parameters - Calibrations* mCalib = nullptr; // access to Calibrations in CCDB + Geometry* mGeo = nullptr; // access to Geometry + PadResponse mPRF{}; // access to PadResponse + SimParam mSimParam{}; // simulation parameters + Calibrations* mCalib = nullptr; // access to Calibrations in CCDB + const CalVdriftExB* mCalVdriftExB = nullptr; // access to time-dependent calibrations CalVdriftExB in CCDB + const CalGain* mCalGain = nullptr; // access to time-dependent calibrations CalGain in CCDB + std::array mFedChamberStatus{}; // access to time-dependent FED chamber status in CCDB PileupTool pileupTool; // number of digitizer threads diff --git a/Detectors/TRD/simulation/include/TRDSimulation/SimParam.h b/Detectors/TRD/simulation/include/TRDSimulation/SimParam.h index b44f3a9104473..f7cad2e2fc4d9 100644 --- a/Detectors/TRD/simulation/include/TRDSimulation/SimParam.h +++ b/Detectors/TRD/simulation/include/TRDSimulation/SimParam.h @@ -66,6 +66,7 @@ class SimParam } // Getters + float getEffVdriftDefault() const { return mEffVdriftDefault; } float getGasGain() const { return mGasGain; } float getNoise() const { return mNoise; } float getChipGain() const { return mChipGain; } @@ -136,6 +137,8 @@ class SimParam float mInvTRFwid{static_cast(mTRFbin) / (mTRFhi - mTRFlo)}; ///< Inverse of the bin width of the integrated TRF and x-talk float mGasGain{4000.f}; ///< Gas gain + float mEffVdriftDefault{1.22f}; ///< The CCDB contains an effective drift velocity, and not the true drift velocity, so we anchor only the variations. This default parameter is the one reproducing data the best for run 568191. + ClassDefNV(SimParam, 2); // The TRD simulation parameters }; diff --git a/Detectors/TRD/simulation/src/Digitizer.cxx b/Detectors/TRD/simulation/src/Digitizer.cxx index 1cab4c2bcea62..03d824db7d87a 100644 --- a/Detectors/TRD/simulation/src/Digitizer.cxx +++ b/Detectors/TRD/simulation/src/Digitizer.cxx @@ -160,7 +160,9 @@ void Digitizer::process(std::vector const& hits) auto& signalsMap = mSignalsMapCollection[det]; // Jump to the next detector if the detector is // switched off, not installed, etc - if (mCalib->getChamberStatus()->isNoData(det)) { + // In the chamber Fed status, 3 corresponds to good chamber + // if (mCalib->getChamberStatus()->isNoData(det)) { + if (getFedChamberStatus(det) != 3) { continue; } if (!mGeo->chamberInGeometry(det)) { @@ -199,7 +201,7 @@ bool Digitizer::convertHits(const int det, const std::vector& hits, SignalC double padSignal[mNpad]; - const double calExBDetValue = mCalib->getExB(det); // T * V/cm (check units) + const double calExBDetValue = mCalVdriftExB->getExB(det, true); // T * V/cm (check units) const PadPlane* padPlane = mGeo->getPadPlane(det); const int layer = mGeo->getLayer(det); const float rowEndROC = padPlane->getRowEndROC(); @@ -253,8 +255,11 @@ bool Digitizer::convertHits(const int det, const std::vector& hits, SignalC absDriftLength /= std::sqrt(1 / (1 + calExBDetValue * calExBDetValue)); } - float driftVelocity = mCalib->getVDrift(det, colE, rowE); // The drift velocity - float t0 = mCalib->getT0(det, colE, rowE); // The T0 velocity + float driftVelocity = constants::VDRIFTDEFAULT; // The default drift velocity + if (TMath::Abs(mCalVdriftExB->getVdrift(det, true) - constants::VDRIFTDEFAULT) > 1e-6) { + driftVelocity = mCalVdriftExB->getVdrift(det, true) * constants::VDRIFTDEFAULT / mSimParam.getEffVdriftDefault(); // If they are available in the CCDB, we anchor the vdrift variations + } + float t0 = mCalib->getT0(det, colE, rowE); // The T0 velocity // Loop over all created electrons const int nElectrons = std::fabs(qTotal); @@ -277,7 +282,8 @@ bool Digitizer::convertHits(const int det, const std::vector& hits, SignalC // Apply E x B effects if (mSimParam.isExBOn()) { - locCd = locCd + calExBDetValue * driftLength; + // minus sign is necessary to be compatible with how Vdrift and ExB are calibrated + locCd = locCd - TMath::Tan(calExBDetValue) * driftLength; } // The electron position after diffusion and ExB in pad coordinates. rowE = padPlane->getPadRowNumberROC(locRd); @@ -292,7 +298,7 @@ bool Digitizer::convertHits(const int det, const std::vector& hits, SignalC continue; } const double colOffset = padPlane->getPadColOffset(colE, locCd + offsetTilt); - driftVelocity = mCalib->getVDrift(det, colE, rowE); // The drift velocity for the updated col and row + // driftVelocity = mCalib->getVDrift(det, colE, rowE); // The drift velocity for the updated col and row t0 = mCalib->getT0(det, colE, rowE); // The T0 velocity for the updated col and row // Convert the position to drift time [mus], using either constant drift velocity or // time structure of drift cells (non-isochronity, GARFIELD calculation). @@ -313,7 +319,8 @@ bool Digitizer::convertHits(const int det, const std::vector& hits, SignalC } // Apply the gas gain including fluctuations - const double signal = -(mSimParam.getGasGain()) * mLogRandomRings[thread].getNextValue(); + double timeDepGainFactor = mCalGain->getMPVdEdx(det, true) / constants::MPVDEDXDEFAULT; + const double signal = -(mSimParam.getGasGain()) * timeDepGainFactor * mLogRandomRings[thread].getNextValue(); // Apply the pad response if (mSimParam.prfOn()) { @@ -424,10 +431,10 @@ bool Digitizer::convertSignalsToADC(SignalContainer& signalMapCont, DigitContain int halfchamberside = (mcm > 3) ? 1 : 0; // 0=Aside, 1=Bside // Halfchambers that are switched off, masked by mCalib - if ((halfchamberside == 0 && mCalib->getChamberStatus()->isNoDataSideA(det)) || + /*if ((halfchamberside == 0 && mCalib->getChamberStatus()->isNoDataSideA(det)) || (halfchamberside == 1 && mCalib->getChamberStatus()->isNoDataSideB(det))) { continue; - } + }*/ // Check whether pad is masked // Bridged pads are not considered yet!!! diff --git a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx index 339f0e27ae050..e3cb11a724c3a 100644 --- a/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDDigitizerSpec.cxx @@ -15,6 +15,7 @@ #include "Framework/DataProcessorSpec.h" #include "Framework/DataRefUtils.h" #include "Framework/Lifetime.h" +#include "Framework/CCDBParamSpec.h" #include "Headers/DataHeader.h" #include "TStopwatch.h" #include "TChain.h" @@ -69,6 +70,9 @@ class TRDDPLDigitizerTask : public o2::base::BaseDPLDigitizer auto creationTime = pc.services().get().creation; simcal.getCCDBObjects(creationTime); mDigitizer.setCalibrations(&simcal); + pc.inputs().get("calvdexb"); + pc.inputs().get("calgain"); + pc.inputs().get*>("fedchamberstatus"); // read collision context from input auto context = pc.inputs().get("collisioncontext"); @@ -207,6 +211,28 @@ class TRDDPLDigitizerTask : public o2::base::BaseDPLDigitizer finished = true; } + void finaliseCCDB(ConcreteDataMatcher& matcher, void* obj) + { + if (matcher == ConcreteDataMatcher("TRD", "CALVDRIFTEXB", 0)) { + LOG(info) << "CalVdriftExB object has been updated"; + mDigitizer.setCalVdriftExB((const o2::trd::CalVdriftExB*)obj); + return; + } + if (matcher == ConcreteDataMatcher("TRD", "CALGAIN", 0)) { + LOG(info) << "CalGain object has been updated"; + mDigitizer.setCalGain((const o2::trd::CalGain*)obj); + return; + } + if (matcher == ConcreteDataMatcher("TRD", "FEDCHAMBERSTATUS", 0)) { + LOG(info) << "Fed chamber status has been updated"; + std::array* fedStatus = (std::array*)obj; + for (int det = 0; det < constants::MAXCHAMBER; det++) { + mDigitizer.setFedChamberStatus(det, (*fedStatus)[det]); + } + return; + } + } + private: Digitizer mDigitizer; std::vector mSimChains; @@ -230,10 +256,16 @@ o2::framework::DataProcessorSpec getTRDDigitizerSpec(int channel, bool mctruth) } outputs.emplace_back("TRD", "ROMode", 0, Lifetime::Timeframe); + std::vector inputs; + inputs.emplace_back("collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe); + inputs.emplace_back("calvdexb", "TRD", "CALVDRIFTEXB", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/CalVdriftExB")); + inputs.emplace_back("calgain", "TRD", "CALGAIN", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/CalGain")); + inputs.emplace_back("fedchamberstatus", "TRD", "FEDCHAMBERSTATUS", 0, Lifetime::Condition, ccdbParamSpec("TRD/Calib/DCSDPsFedChamberStatus")); + return DataProcessorSpec{ "TRDDigitizer", - Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe}}, - + // Inputs{InputSpec{"collisioncontext", "SIM", "COLLISIONCONTEXT", static_cast(channel), Lifetime::Timeframe}}, + inputs, outputs, AlgorithmSpec{adaptFromTask()},