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;
17 constexpr double reciprocalSpeedOfLight = 1. / Gaudi::Units::c_light;
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;
66 return StatusCode::FAILURE;
75 return StatusCode::SUCCESS;
79 double lorentzAngle {0.};
85 fieldCache.
getField(globalPos.data(), magneticField.data());
88 double phi = globalPos.phi();
89 double bfield = (magneticField.x()*std::sin(
phi)-magneticField.y()*std::cos(
phi))*1000.;
93 bool changeSign = ( globalPos.z() < 0. ? (gasGap==1 || gasGap==3) : (gasGap==2 || gasGap==4) );
94 if (changeSign) bfield = -bfield;
101 for (
unsigned int i = 0; i < prepData->
stripNumbers().size(); ++i){
110 calibClus.push_back(std::move(calibStrip));
112 return StatusCode::SUCCESS;
120 std::vector<NSWCalib::CalibratedStrip>& calibClus)
const {
122 double lorentzAngle {0.};
128 fieldCache.
getField(globalPos.data(), magneticField.data());
131 double phi = globalPos.phi();
132 double bfield = (magneticField.x()*std::sin(
phi)-magneticField.y()*std::cos(
phi))*1000.;
136 bool changeSign = ( globalPos.z() < 0. ? (gasGap==1 || gasGap==3) : (gasGap==2 || gasGap==4) );
137 if (changeSign) bfield = -bfield;
144 for (
unsigned int i = 0; i < prepData.
stripNumbers().size(); ++i){
153 calibClus.push_back(std::move(calibStrip));
155 return StatusCode::SUCCESS;
165 const double lorentzAngle,
171 return StatusCode::FAILURE;
176 calibStrip.
time = time;
194 float max_half_drifttime = (vDrift != 0 ) ? 2.5/vDrift : 50.;
198 ATH_MSG_VERBOSE(
"Original drift time: " << time <<
" new max half drift time: " << max_half_drifttime
203 double vDriftCorrected = vDrift * std::cos(lorentzAngle);
211 calibStrip.
dx = std::sin(lorentzAngle) * calibStrip.
time * vDrift;
213 return StatusCode::SUCCESS;
230 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - Failed to fetch global position for "
232 return StatusCode::FAILURE;
236 float time{-std::numeric_limits<float>::max()},
237 charge{-std::numeric_limits<float>::max()};
244 calibStrip.
time = time - globalPos.norm() * reciprocalSpeedOfLight -
mmPeakTime();
253 <<
" with pdo: " << mmRawData->
charge() <<
", tdo: "<< mmRawData->
time()
254 <<
", relBCID "<< mmRawData->
relBcid() <<
", charge and time in counts: "
256 << calibStrip.
charge <<
" electrons time after corrections " << calibStrip.
time
257 <<
" ns time before corrections "<< time <<
"ns");
269 return StatusCode::SUCCESS;
284 ATH_MSG_WARNING(__func__<<
"() "<<__LINE__<<
" - Failed to retrieve a valid global position for "
286 return StatusCode::FAILURE;
289 float time{-std::numeric_limits<float>::max()},
charge{-std::numeric_limits<float>::max()};
307 return StatusCode::SUCCESS;
314 return StatusCode::SUCCESS;
319 const std::vector<double>& driftDistances,
320 std::vector<double>& driftTimes)
const {
325 fieldCache.
getField(globalPos.data(), magneticField.data());
328 const double phi = globalPos.phi();
329 double bfield = (magneticField.x()*std::sin(
phi)-magneticField.y()*std::cos(
phi))*1000.;
333 bool changeSign = ( globalPos.z() < 0. ? (gasGap==1 || gasGap==3) : (gasGap==2 || gasGap==4) );
334 if (changeSign) bfield = -bfield;
335 double cos2_lorentzAngle = std::pow(std::cos ( (bfield>0. ? 1. : -1.)*
m_lorentzAngleFunction(std::abs(bfield)) * toRad), 2);
337 for (
const double dist : driftDistances){
338 double time = dist / (
m_vDrift*cos2_lorentzAngle);
339 driftTimes.push_back(time);
341 return StatusCode::SUCCESS;
365 pdo = c * calib.slope + calib.intercept;
390 charge = (pdo-calib.intercept)/calib.slope;
415 float tdoTime = -999.9;
418 if(t >= lowerBound+i_relBCID*25 && t < (lowerBound+25)+i_relBCID*25){
419 tdoTime = i_relBCID*25 - t;
424 if(tdoTime < lowerBound) {
428 tdo = tdoTime*calib.slope + calib.intercept;
441 float tdoTime = -999.9;
444 if(t >= lowerBound+i_relBCID*25 && t < (lowerBound+25)+i_relBCID*25){
445 tdoTime = i_relBCID*25 - t;
450 if(tdoTime < lowerBound) {
454 tdo = tdoTime*calib.slope + calib.intercept;
461 ATH_MSG_ERROR(
"Cannot find conditions data container for T0s!");
463 std::optional<float>
t0 = readT0->
getT0(
id);
465 ATH_MSG_DEBUG(
"failed to retrieve good t0 from database, skipping t0 calibration");
469 float newTime = time + (targetT0 - (*t0));
471 <<
" t0 from database " << (*
t0) <<
" t0 target " << targetT0 <<
" new time " << newTime);
502 time = relBCID*25. - (tdo-calib.intercept)/calib.slope + peakTime;
508 properties.driftVelocity =
m_vDrift;
509 properties.longitudinalDiffusionSigma =
m_longDiff;
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
double charge(const T &p)
void getInitializedCache(MagField::AtlasFieldCache &cache) const
get B field cache for evaluation as a function of 2-d or 3-d position.
Local cache for magnetic field (based on MagFieldServices/AtlasFieldSvcTLS.h)
void getField(const double *ATH_RESTRICT xyz, double *ATH_RESTRICT bxyz, double *ATH_RESTRICT deriv=nullptr)
get B field value at given position xyz[3] is in mm, bxyz[3] is in kT if deriv[9] is given,...
Identifier channelID(int stationName, int stationEta, int stationPhi, int multilayer, int gasGap, int channel) const
int gasGap(const Identifier &id) const override
get the hashes
int multilayer(const Identifier &id) const
const Amg::Transform3D & localToGlobalTransform(const ActsTrk::GeometryContext &ctx) const
Returns the transformation from the local coordinate system of the readout element into the global AT...
An MMReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station con...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position – local or global If the strip number is outside the range of valid strips,...
const MuonChannelDesign * getDesign(const Identifier &id) const
returns the MuonChannelDesign class for the given identifier
bool stripGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
virtual const Trk::PlaneSurface & surface() const override
access to chamber surface (phi orientation), uses the first gas gap
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
const MMReadoutElement * getMMReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
const sTgcReadoutElement * getsTgcReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
An sTgcReadoutElement corresponds to a single STGC module; therefore typicaly a barrel muon station c...
virtual bool stripPosition(const Identifier &id, Amg::Vector2D &pos) const override final
strip position - should be renamed to channel position If the strip number is outside the range of va...
bool stripGlobalPosition(const Identifier &id, Amg::Vector3D &gpos) const
Class to represent MM measurements.
const std::vector< uint16_t > & stripNumbers() const
returns the list of strip numbers
const std::vector< short int > & stripTimes() const
returns the list of times
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
const std::vector< int > & stripCharges() const
returns the list of charges
Temporary class to hold the MM RDO.
static constexpr int s_BCWindow
static constexpr double s_lowerTimeBound
const Identifier & identify() const
bool timeAndChargeInCounts() const
double getCTPCorrectedDriftVelocity(const Identifier &identifier, const double theta) const
bool timeAndChargeInCounts() const
static constexpr int s_BCWindow
static constexpr double s_lowerTimeBound
unsigned int charge() const
const Identifier identify() const
const CalibConstants * getCalibForChannel(const CalibDataType type, const Identifier &channelId) const
Retrieves the calibration constant for a particular readout channel.
Conditions data object to calibrate the timeoff set of each individual channel in the NSW.
std::optional< float > getT0(const Identifier &channelId) const
Retrieve the t0 calibration constant for a given NSW channel.
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for PlaneSurface: GlobalToLocal method without dynamic memory allocation - boolean checks i...
Identifier identify() const
return the identifier
const std::vector< Identifier > & rdoList() const
return the List of rdo identifiers (pointers)
const std::vector< uint16_t > & stripNumbers() const
returns the list of strip numbers
const Identifier & identify() const
: Returns the Athena identifier of the micro mega cluster It's constructed from the measurementHash &...
IdentifierHash layerHash() const
Returns the hash of the associated layer (Needed for surface retrieval)
const std::vector< int > & stripCharges() const
returns the list of charges
const std::vector< int16_t > & stripTimes() const
returns the list of times
const MuonGMR4::MmReadoutElement * readoutElement() const
Retrieve the associated MmReadoutElement.
ConstVectorMap< N > localPosition() const
Returns the local position of the measurement.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
const T * get(const ReadCondHandleKey< T > &key, const EventContext &ctx)
Convenience function to retrieve an object given a ReadCondHandleKey.
double channelWidth() const
calculate local channel width
std::function< double(double)> angleFunction
#define THROW_EXCEPTION(MESSAGE)