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();
 
   61                 clusFeat.locPos = toMerge.localPosition();
 
   62                 clusFeat.distDrift = toMerge.driftDist();
 
   63                 clusFeat.resTransDistDrift = toMerge.localCovariance()(0, 0);
 
   64                 clusFeat.resLongDistDrift = toMerge.localCovariance()(1, 1);
 
   67                 stripFeatures.emplace_back(std::move(clusFeat));
 
   68                 clustConstituents.emplace_back(std::move(toMerge));
 
   72             if (!errorCalibDB.isValid()) {
 
   74                 return StatusCode::FAILURE;
 
   87     return StatusCode::SUCCESS;
 
   98         int layer = 4 * (idHelper.multilayer(
id) - 1) + (idHelper.gasGap(
id) - 1);
 
   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());
 
  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() << 
" " 
  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});
 
  139         ATH_MSG_DEBUG(
"Found " << idxClusters.size() << 
" clusters");
 
  140         for (
const auto& idxCluster : idxClusters) { 
ATH_MSG_DEBUG(
"cluster: " << idxCluster); }
 
  145 std::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;
 
  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);
 
  185     double correctionErrorSq = tanTheta * tanTheta * meanDriftDistErrorSq;
 
  188     clusterPositionErrorSq = correctionErrorSq + meanPosXErrorSq;
 
  192     errorCalibIn.
stripId = constituents[0].identifier;
 
  193     errorCalibIn.clusterAuthor = 
author;
 
  194     errorCalibIn.locPhi = dirEstimate.phi();
 
  195     errorCalibIn.locTheta = dirEstimate.theta();
 
  197     errorCalibIn.clusterSize = constituents.size();
 
  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,
 
  266     if (!errorCalibDB.isValid()) {
 
  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;