6 #include "GaudiKernel/SystemOfUnits.h"
7 #include "GaudiKernel/PhysicalConstants.h"
15 constexpr
double toRad =
M_PI/180;
16 constexpr
double pitchErr = 0.425 * 0.425 / 12;
20 static const std::map<std::string, float> map_transDiff {{
"ArCo2_937", 0.036},
21 {
"ArCo2_8020", 0.019}, {
"ArCo2iC4H10_9352", 0.035}};
22 static const std::map<std::string, float> map_longDiff {{
"ArCo2_937", 0.019},
23 {
"ArCo2_8020", 0.022 }, {
"ArCo2iC4H10_9352", 0.0195}};
24 static const std::map<std::string, float> map_vDrift {{
"ArCo2_937", 0.047},
25 {
"ArCo2_8020", 0.040}, {
"ArCo2iC4H10_9352", 0.045}};
29 constexpr
double const MM_electronsPerfC = 6241.;
30 constexpr
double const sTGC_pCPerfC = 1000.;
36 static const std::map<std::string, angleFunction> map_lorentzAngleFunctionPars {
37 {
"ArCo2_937", [](
double x) {
return 0.f + 58.87f*
x -2.983f*
x*
x -10.62f*
x*
x*
x + 2.818f*
x*
x*
x*
x;}},
38 {
"ArCo2_8020", [](
double x) {
return 0.f + 58.87f*
x -2.983f*
x*
x -10.62f*
x*
x*
x + 2.818f*
x*
x*
x*
x;}},
39 {
"ArCo2iC4H10_9352", [](
double x) {
return 0.f + 58.87f*
x -2.983f*
x*
x -10.62f*
x*
x*
x + 2.818f*
x*
x*
x*
x;}}};
42 static const std::map<std::string, float> map_interactionDensitySigma {{
"ArCo2_937", 4.04 / 5.},
43 {
"ArCo2_8020", 4.04 / 5.}, {
"ArCo2iC4H10_9352", 4.04 / 5.}};
44 static const std::map<std::string, float> map_interactionDensityMean {{
"ArCo2_937", 16.15 / 5.},
45 {
"ArCo2_8020", 16.15 / 5.}, {
"ArCo2iC4H10_9352", 16.15 / 5.}};
60 return StatusCode::SUCCESS;
64 if (!map_vDrift.count(m_gasMixture)) {
65 ATH_MSG_FATAL(
"Configured Micromegas with unkown gas mixture: " << m_gasMixture);
66 return StatusCode::FAILURE;
69 m_vDrift = map_vDrift.find(m_gasMixture)->second;
70 m_transDiff = map_transDiff.find(m_gasMixture)->second;
71 m_longDiff = map_longDiff.find(m_gasMixture)->second;
72 m_interactionDensitySigma = map_interactionDensitySigma.find(m_gasMixture)->second;
73 m_interactionDensityMean = map_interactionDensityMean.find(m_gasMixture)->second;
74 m_lorentzAngleFunction = map_lorentzAngleFunctionPars.find(m_gasMixture)->second;
75 return StatusCode::SUCCESS;
81 if(!readTdoPdo.isValid()){
82 ATH_MSG_ERROR(
"Cannot find conditions data container for TDOs and PDOs!");
85 return readTdoPdo.cptr();
91 if (!ctpClusterCalibDB.isValid()) {
92 ATH_MSG_FATAL(
"Failed to retrieve the parameterized errors "<<ctpClusterCalibDB.fullKey());
95 return ctpClusterCalibDB.cptr();
101 double lorentzAngle {0.};
102 if(m_applyMmBFieldCalib){
105 if (!loadMagneticField(ctx, fieldCache))
return StatusCode::FAILURE;
107 fieldCache.
getField(globalPos.data(), magneticField.data());
110 double phi = globalPos.phi();
114 int gasGap = m_idHelperSvc->mmIdHelper().gasGap(prepData->
identify());
116 if (changeSign) bfield = -bfield;
119 lorentzAngle = (bfield>0. ? 1. : -1.)*m_lorentzAngleFunction(std::abs(bfield)) * toRad;
130 ATH_CHECK(calibrateStrip(ctx,
id,
time,
charge, (globPos.theta() / toRad) , lorentzAngle, calibStrip));
132 calibClus.push_back(std::move(calibStrip));
134 return StatusCode::SUCCESS;
142 std::vector<NSWCalib::CalibratedStrip>& calibClus)
const {
144 double lorentzAngle {0.};
145 if(m_applyMmBFieldCalib){
148 if (!loadMagneticField(ctx, fieldCache))
return StatusCode::FAILURE;
150 fieldCache.
getField(globalPos.data(), magneticField.data());
153 double phi = globalPos.phi();
157 int gasGap = m_idHelperSvc->mmIdHelper().gasGap(prepData.
identify());
159 if (changeSign) bfield = -bfield;
162 lorentzAngle = (bfield>0. ? 1. : -1.)*m_lorentzAngleFunction(std::abs(bfield)) * toRad;
173 ATH_CHECK(calibrateStrip(ctx,
id,
time,
charge, (globPos.theta() / toRad) , lorentzAngle, calibStrip));
175 calibClus.push_back(std::move(calibStrip));
177 return StatusCode::SUCCESS;
187 if(!localStripPosition(
id,locPos)) {
188 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
" Failed to retrieve local strip position "<<m_idHelperSvc->toString(
id));
189 return StatusCode::FAILURE;
198 Identifier gasGapId = m_idHelperSvc->mmIdHelper().channelID(
id, m_idHelperSvc->mmIdHelper().multilayer(
id),
199 m_idHelperSvc->mmIdHelper().gasGap(
id), 1);
201 double vDrift = m_vDrift;
203 if(m_CalibDriftVelocityFromData){
204 vDrift = getCTPClusterCalibData(ctx)->getCTPCorrectedDriftVelocity(gasGapId,
theta);
207 float max_half_drifttime = (vDrift != 0 ) ? 2.5/vDrift : 50.;
210 calibStrip.
time =
time + (max_half_drifttime - m_mmT0TargetValue);
211 ATH_MSG_VERBOSE(
"Original drift time: " <<
time <<
" new max half drift time: " << max_half_drifttime <<
" new time: " << calibStrip.
time <<
" targett0 " << m_mmT0TargetValue );
215 double vDriftCorrected = vDrift *
std::cos(lorentzAngle);
223 calibStrip.
dx =
std::sin(lorentzAngle) * calibStrip.
time * vDrift;
225 return StatusCode::SUCCESS;
234 if(!localStripPosition(rdoId,locPos)) {
235 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
" Failed to retrieve local strip position "<<m_idHelperSvc->toString(rdoId));
236 return StatusCode::FAILURE;
256 calibStrip.
time =
time - globalPos.norm() * reciprocalSpeedOfLight - mmPeakTime();
258 if(m_applyMmT0Calib){
259 calibStrip.
time = applyT0Calibration(ctx, rdoId, calibStrip.
time);
264 ATH_MSG_DEBUG(
"Calibrating RDO " << m_idHelperSvc->toString(rdoId) <<
"with pdo: " << mmRawData->
charge() <<
" tdo: "<< mmRawData->
time() <<
" relBCID "<< mmRawData->
relBcid() <<
" charge and time in counts " <<
265 mmRawData->
timeAndChargeInCounts() <<
" isData "<< m_isData <<
" to charge: " << calibStrip.
charge <<
" electrons time after corrections " << calibStrip.
time <<
" ns time before corrections "<<
time <<
"ns");
276 calibStrip.
locPos = locPos;
278 return StatusCode::SUCCESS;
294 if(!localStripPosition(rdoId,locPos)) {
295 ATH_MSG_WARNING(__FILE__<<
":"<<__LINE__<<
" Failed to retrieve local strip position "<<m_idHelperSvc->toString(rdoId));
296 return StatusCode::FAILURE;
308 calibStrip.
time =
time - stgcPeakTime();
310 if(m_applysTgcT0Calib){
311 calibStrip.
time = applyT0Calibration(ctx, rdoId, calibStrip.
time);
315 calibStrip.
locPos = locPos;
316 return StatusCode::SUCCESS;
321 if (!readHandle.isValid()) {
322 ATH_MSG_ERROR(
"doDigitization: Failed to retrieve AtlasFieldCacheCondObj with key " << m_fieldCondObjInputKey.key());
325 readHandle.cptr()->getInitializedCache(fieldCache);
331 if (!loadMagneticField(ctx, fieldCache))
return StatusCode::FAILURE;
333 fieldCache.
getField(globalPos.data(), magneticField.data());
336 const double phi = globalPos.phi();
340 int gasGap = m_idHelperSvc->mmIdHelper().gasGap(prepData->
identify());
342 if (changeSign) bfield = -bfield;
343 double cos2_lorentzAngle =
std::pow(
std::cos ( (bfield>0. ? 1. : -1.)*m_lorentzAngleFunction(std::abs(bfield)) * toRad), 2);
345 for (
const double dist : driftDistances){
346 double time = dist / (m_vDrift*cos2_lorentzAngle);
347 driftTimes.push_back(
time);
349 return StatusCode::SUCCESS;
367 if (m_idHelperSvc->isMM (chnlId))
c /= MM_electronsPerfC;
368 else if(m_idHelperSvc->issTgc(chnlId))
c *= sTGC_pCPerfC;
395 if (m_idHelperSvc->isMM (chnlId))
charge *= MM_electronsPerfC;
396 else if(m_idHelperSvc->issTgc(chnlId))
charge /= sTGC_pCPerfC;
404 if (!tdoPdoData)
return false;
405 if (m_idHelperSvc->isMM (chnlId))
return timeToTdoMM (tdoPdoData,
time, chnlId, tdo, relBCID);
406 else if(m_idHelperSvc->issTgc(chnlId))
return timeToTdoSTGC(tdoPdoData,
time, chnlId, tdo, relBCID);
412 const float t =
time - m_mmPeakTime - m_mmLatencyMC;
419 float tdoTime = -999.9;
422 if(
t >= lowerBound+i_relBCID*25 &&
t < (lowerBound+25)+i_relBCID*25){
423 tdoTime = i_relBCID*25 -
t;
428 if(tdoTime < lowerBound) {
438 const float t =
time - m_stgcPeakTime - m_stgcLatencyMC;
445 float tdoTime = -999.9;
448 if(
t >= lowerBound+i_relBCID*25 &&
t < (lowerBound+25)+i_relBCID*25){
449 tdoTime = i_relBCID*25 -
t;
454 if(tdoTime < lowerBound) {
464 if(!readT0.isValid()){
465 ATH_MSG_ERROR(
"Cannot find conditions data container for T0s!");
468 bool isGood = readT0->getT0(
id,
t0);
469 if(!isGood ||
t0==0){
470 ATH_MSG_DEBUG(
"failed to retrieve good t0 from database, skipping t0 calibration");
473 float targetT0 = (m_idHelperSvc->isMM(
id) ? m_mmT0TargetValue : m_stgcT0TargetValue);
474 float newTime =
time + (targetT0 -
t0);
475 ATH_MSG_DEBUG(
"doing T0 calibration for RDO " << m_idHelperSvc->toString(
id) <<
" time " <<
time <<
" t0 from database " <<
t0 <<
" t0 target " << targetT0 <<
" new time " << newTime);
502 float mmLatency = (m_isData? m_mmLatencyData : m_mmLatencyMC );
503 float stgcLatency = (m_isData? m_stgcLatencyData : m_stgcLatencyMC);
505 const float peakTime = m_idHelperSvc->isMM(chnlId) ? mmPeakTime() + mmLatency : stgcPeakTime() + stgcLatency;
506 time = relBCID*25. - (tdo-
calib.intercept)/
calib.slope + peakTime;
513 properties.longitudinalDiffusionSigma = m_longDiff;
514 properties.transverseDiffusionSigma = m_transDiff;
515 properties.interactionDensityMean = m_interactionDensityMean;
516 properties.interactionDensitySigma = m_interactionDensitySigma;
517 properties.lorentzAngleFunction = m_lorentzAngleFunction;
526 if(m_idHelperSvc->isMM(
id)){
530 }
else if(m_idHelperSvc->issTgc(
id)){