10#include "GaudiKernel/PhysicalConstants.h"
11#include "GaudiKernel/SystemOfUnits.h"
13#define DEFINE_VECTOR(dType, varName, nEles) \
14 std::vector<dType> varName{}; \
15 varName.reserve(nEles);
18 constexpr double halfGapWidth = 2.52;
25 const IInterface* p) :
27 declareInterface<IMMClusterBuilderTool>(
this);
33 return StatusCode::SUCCESS;
37 std::vector<MMPrepData>&& MMprds,
38 std::vector<std::unique_ptr<MMPrepData>>& clustersVec)
const {
42 for (std::vector<MMPrepData>& prdsOfLayer : prdsPerLayer) {
43 if (prdsOfLayer.size() < 2)
continue;
45 std::vector<std::vector<uint>> idxClusters =
clusterLayer(prdsOfLayer);
47 for (std::vector<uint>& clustIds : idxClusters) {
52 for (
unsigned idx : clustIds) {
56 const double q = toMerge.
charge();
67 stripFeatures.emplace_back(std::move(clusFeat));
68 clustConstituents.emplace_back(std::move(toMerge));
74 return StatusCode::FAILURE;
87 return StatusCode::SUCCESS;
99 prdsPerLayer.at(layer).push_back(std::move(prd));
103 for (std::vector<MMPrepData>& prdsInLay : prdsPerLayer) {
105 return idHelper.channel(a.identify()) <
106 idHelper.channel(b.identify());
112 std::vector<std::vector<uint>>
117 int gasGap = idHelper.
gasGap(MMPrdsPerLayer.at(0).identify());
120 if (
msgLvl(MSG::VERBOSE)) {
121 for (
const auto& prd : MMPrdsPerLayer) {
123 <<
" local positionX " << prd.localPosition().x() <<
" time " << prd.time()
124 <<
" corrected time " << prd.time() <<
" angle to IP "<< prd.globalPosition().theta() <<
" "
125 << prd.globalPosition().theta() / Gaudi::Units::degree);
128 std::vector<std::vector<uint>> idxClusters{};
130 idxClusters.push_back(std::vector<uint>{0});
131 for (
uint i_strip = 1; i_strip < MMPrdsPerLayer.size(); i_strip++) {
133 idxClusters.back().push_back(i_strip);
135 idxClusters.push_back(std::vector<uint>{i_strip});
138 if (
msgLvl(MSG::VERBOSE)) {
139 ATH_MSG_DEBUG(
"Found " << idxClusters.size() <<
" clusters");
140 for (
const auto& idxCluster : idxClusters) {
ATH_MSG_DEBUG(
"cluster: " << idxCluster); }
145std::pair<double, double>
148 const std::vector<NSWCalib::CalibratedStrip>& constituents,
152 double clusterPosition{0}, clusterPositionErrorSq{0.};
154 double qtot{0}, meanDriftDist{0.}, meanDriftDistError{0.};
155 double meanPosX{0.}, meanPosXError{0.};
158 const double driftDist = clustFeat.distDrift;
160 const double charge = clustFeat.charge * Gaudi::Units::perThousand;
161 const double chargeSq = std::pow(
charge, 2);
163 meanPosX += clustFeat.locPos.x() *
charge;
164 meanPosXError += clustFeat.resLongDistDrift * chargeSq;
165 meanDriftDist += driftDist *
charge;
166 meanDriftDistError += clustFeat.resTransDistDrift * chargeSq;
168 <<
" drift dist " << driftDist <<
" +- " << std::sqrt(clustFeat.resTransDistDrift)
169 <<
" xpos: "<< clustFeat.locPos.x() <<
" +- " << std::sqrt(clustFeat.resLongDistDrift)
170 <<
" xMeanPos " << meanPosX / qtot <<
" +- " << std::sqrt(meanPosXError) / qtot
171 <<
" meanPosXError " << meanPosXError <<
" meanDriftDist " << meanDriftDist / qtot
172 <<
" meanDriftDist Error " << std::sqrt(meanDriftDistError) / qtot
173 <<
" charge " <<
charge <<
" qtot " << qtot);
176 double meanPosXErrorSq = meanPosXError / (qtot * qtot);
177 meanDriftDist /= qtot;
178 double meanDriftDistErrorSq = meanDriftDistError / (qtot * qtot);
180 const double tanTheta = std::tan(dirEstimate.theta());
181 double correction = tanTheta * (meanDriftDist - halfGapWidth);
182 if (
m_idHelperSvc->mmIdHelper().gasGap(constituents[0].identifier) % 2 == 0) {
183 correction = -1. * correction;
185 double correctionErrorSq = tanTheta * tanTheta * meanDriftDistErrorSq;
187 clusterPosition = meanPosX + correction;
188 clusterPositionErrorSq = correctionErrorSq + meanPosXErrorSq;
192 errorCalibIn.
stripId = constituents[0].identifier;
194 errorCalibIn.
locPhi = dirEstimate.phi();
195 errorCalibIn.
locTheta = dirEstimate.theta();
202 <<
" meanX " << meanPosX <<
" +-" << std::sqrt(meanPosXErrorSq) <<
" mean drift dist " << meanDriftDist <<
" +- "
203 << std::sqrt(meanDriftDistErrorSq) <<
" correction " << correction <<
" +- " << std::sqrt(correctionErrorSq)
204 <<
" final position " << clusterPosition <<
" +- " << std::sqrt(clusterPositionErrorSq));
205 return std::make_pair(clusterPosition, localUncertainty*localUncertainty);
209 const std::vector<Muon::MMPrepData>& constituents,
210 const double clusterPosition,
211 const double clusterPositionErrorSq,
212 std::vector<std::unique_ptr<Muon::MMPrepData>>& mergedClust)
const {
223 rdoList.push_back(clustFeat.identify());
224 stripNumbers.push_back(
channel(clustFeat));
225 stripTimes.push_back(clustFeat.time());
226 stripCharges.push_back(clustFeat.charge());
227 stripDriftDists.push_back(clustFeat.driftDist());
229 stripDriftDistErrors.emplace_back(cov(0,0), cov(1,1));
230 totalCharge += clustFeat.charge();
235 covN.coeffRef(0, 0) = clusterPositionErrorSq;
236 Amg::Vector2D localClusterPositionV(clusterPosition, constituents[0].localPosition().
y());
237 Identifier idStrip0 = constituents[0].identify();
239 std::unique_ptr<MMPrepData> prdN = std::make_unique<MMPrepData>(idStrip0,
240 constituents[0].collectionHash(),
241 std::move(localClusterPositionV),
244 constituents[0].detectorElement(),
248 std::move(stripNumbers),
249 std::move(stripTimes),
250 std::move(stripCharges));
252 prdN->setDriftDist(std::move(stripDriftDists), std::move(stripDriftDistErrors));
255 mergedClust.push_back(std::move(prdN));
256 return StatusCode::SUCCESS;
260 const std::vector<NSWCalib::CalibratedStrip>& calibratedStrips,
268 return RIO_Author::unKnownAuthor;
271 constexpr uint8_t toolAuthor =
static_cast<uint8_t
>(RIO_Author::ClusterTimeProjectionClusterBuilder);
272 std::pair<double, double> posAndErrorSq =
getClusterPositionPRD(*errorCalibDB.
cptr(), toolAuthor, calibratedStrips, directionEstimate);
274 clusterLocalPosition[
Trk::locX] = posAndErrorSq.first;
276 covN.coeffRef(0, 0) = posAndErrorSq.second;
279 return RIO_Author::ClusterTimeProjectionClusterBuilder;
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_VERBOSE(x)
double charge(const T &p)
bool msgLvl(const MSG::Level lvl) const
int gasGap(const Identifier &id) const override
get the hashes
int multilayer(const Identifier &id) const
Class to represent MM measurements.
@ ClusterTimeProjectionClusterBuilder
float driftDist() const
Returns the Drift Distance.
int charge() const
Returns the AD.
double clusterUncertainty(const Input &clustInfo) const
const_pointer_type cptr()
const Amg::Vector2D & localPosition() const
return the local position reference
Identifier identify() const
return the identifier
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Eigen::Matrix< double, 2, 1 > Vector2D
Eigen::Matrix< double, 3, 1 > Vector3D
Amg::Vector3D toLocal(const Amg::Transform3D &toLocalTrans, const Amg::Vector3D &dir)
Rotates a direction vector into a local frame: x-axis : Parallell to the radial direction of the dete...
NRpcCablingAlg reads raw condition data and writes derived condition data to the condition store.
IMMClusterBuilderTool::RIO_Author RIO_Author
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.