ATLAS Offline Software
Classes | Public Types | Public Member Functions | Private Member Functions | Static Private Member Functions | Private Attributes | List of all members
Muon::DCMathSegmentMaker Class Reference

#include <DCMathSegmentMaker.h>

Inheritance diagram for Muon::DCMathSegmentMaker:
Collaboration diagram for Muon::DCMathSegmentMaker:

Classes

struct  Cluster2D
 
struct  HitInXZ
 
struct  segmentCreationInfo
 
struct  TubeEnds
 

Public Types

using EtaPhiHitsPair = std::pair< std::vector< const MuonClusterOnTrack * >, std::vector< const MuonClusterOnTrack * > >
 
using IdHitMap = std::map< Identifier, EtaPhiHitsPair >
 
using ChIdHitMap = std::map< Identifier, IdHitMap >
 
using ClusterVec = std::vector< Cluster2D >
 
using ClusterVecPair = std::pair< ClusterVec, ClusterVec >
 

Public Member Functions

virtual ~DCMathSegmentMaker ()=default
 
virtual StatusCode initialize ()
 
void find (const std::vector< const Trk::RIO_OnTrack * > &rios, Trk::SegmentCollection *segColl=nullptr) const
 find segments starting from a list of RIO_OnTrack objects, implementation of IMuonSegmentMaker interface routine. More...
 
void find (const std::vector< const Trk::RIO_OnTrack * > &rios1, const std::vector< const Trk::RIO_OnTrack * > &rios2) const
 find segments starting from a list of RIO_OnTrack objects in multiple chambers, implementation of IMuonSegmentMaker interface routine Will call: More...
 
void find (const std::vector< const MdtDriftCircleOnTrack * > &mdts, const std::vector< const MuonClusterOnTrack * > &clusters, Trk::SegmentCollection *segColl=nullptr) const
 find segments starting from: More...
 
void find (const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, const std::vector< const MdtDriftCircleOnTrack * > &mdts, const std::vector< const MuonClusterOnTrack * > &clusters, bool hasPhiMeasurements=false, Trk::SegmentCollection *segColl=nullptr, double momentum=1e9, double sinAngleCut=0, double beta=1.) const
 find segments starting from: More...
 
void find (const Trk::TrackRoad &road, const std::vector< std::vector< const MdtDriftCircleOnTrack * > > &mdts, const std::vector< std::vector< const MuonClusterOnTrack * > > &clusters, Trk::SegmentCollection *segColl, bool hasPhiMeasurements=false, double momentum=1e9) const
 find segments starting from: More...
 

Private Member Functions

bool errorScalingRegion (const Identifier &id) const
 apply error scaling for low mometum tracks More...
 
double errorScaleFactor (const Identifier &id, double curvature, bool hasPhiMeasurements) const
 calculate error scaling factor More...
 
std::vector< IdentifiercalculateHoles (const EventContext &ctx, Identifier chid, const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, bool hasMeasuredCoordinate, std::set< Identifier > &deltaVec, std::set< Identifier > &outoftimeVec, const std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec) const
 
TrkDriftCircleMath::DCVec createDCVec (const std::vector< const MdtDriftCircleOnTrack * > &mdts, double errorScale, std::set< Identifier > &chamberSet, double &phimin, double &phimax, TrkDriftCircleMath::DCStatistics &dcStatistics, const Amg::Transform3D &gToStation, const Amg::Transform3D &amdbToGlobal) const
 
ClusterVecPair create1DClusters (const std::vector< const MuonClusterOnTrack * > &clusters) const
 
ClusterVecPair create2DClusters (const std::vector< const MuonClusterOnTrack * > &clusters) const
 
ClusterVecPair createSpacePoints (const ChIdHitMap &chIdHitMap) const
 
ClusterVecPair createSpacePoints (const IdHitMap &gasGapHitMap) const
 
Cluster2D createSpacePoint (const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const MuonClusterOnTrack *phiHit) const
 
Cluster2D createRpcSpacePoint (const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const std::vector< const MuonClusterOnTrack * > &phiHits) const
 
Cluster2D createTgcSpacePoint (const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const MuonClusterOnTrack *phiHit) const
 
TrkDriftCircleMath::CLVec createClusterVec (const Identifier &chid, ClusterVec &spVec, const Amg::Transform3D &gToStation) const
 
void associateMDTsToSegment (const Amg::Vector3D &gdir, TrkDriftCircleMath::Segment &segment, const TrkDriftCircleMath::ChamberGeometry *multiGeo, const Amg::Transform3D &gToStation, const Amg::Transform3D &amdbToGlobal, std::set< Identifier > &deltaVec, std::set< Identifier > &outoftimeVec, std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec, double beta=1.) const
 
std::pair< std::pair< int, int >, bool > associateClustersToSegment (const TrkDriftCircleMath::Segment &segment, const Identifier &chid, const Amg::Transform3D &gToStation, ClusterVecPair &spVecs, double phimin, double phimax, std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec) const
 
TrkDriftCircleMath::MdtChamberGeometry createChamberGeometry (const Identifier &chid, const Amg::Transform3D &gToStation) const
 
const MdtDriftCircleOnTrackfindFirstRotInChamberWithMostHits (const std::vector< const MdtDriftCircleOnTrack * > &mdts) const
 
bool updateSegmentPhi (const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, Amg::Vector2D &segLocPos, Trk::LocalDirection &segLocDir, Trk::PlaneSurface &surf, const std::vector< const Trk::MeasurementBase * > &rots, double phimin, double phimax) const
 
bool checkBoundsInXZ (double xline, double zline, double dXdZ, const std::vector< HitInXZ > &hits) const
 check whether all hits are in bounds in the XZ plane More...
 
TubeEnds localTubeEnds (const MdtDriftCircleOnTrack &mdt, const Amg::Transform3D &gToSegment, const Amg::Transform3D &segmentToG) const
 calculate positions of tube ends More...
 
bool checkPhiConsistency (double phi, double phimin, double phimax) const
 check whether phi is consistent with segment phi More...
 
Amg::Vector3D updateDirection (double linephi, const Trk::PlaneSurface &surf, const Amg::Vector3D &roaddir, bool isCurvedSegment) const
 update the global direction, keeping the phi of the input road direction but using the local angle YZ More...
 
std::unique_ptr< MuonSegmentcreateSegment (const EventContext &ctx, TrkDriftCircleMath::Segment &segment, const Identifier &chid, const Amg::Vector3D &roadpos, const Amg::Vector3D &roaddir2, const std::vector< const MdtDriftCircleOnTrack * > &mdts, bool hasPhiMeasurements, segmentCreationInfo &sInfo, double beta=1.) const
 
const MdtPrepDatafindMdt (const EventContext &ctx, const Identifier &id) const
 

Static Private Member Functions

static DataVector< const Trk::MeasurementBasecreateROTVec (std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec)
 
static double distanceToSegment (const TrkDriftCircleMath::Segment &segment, const Amg::Vector3D &hitPos, const Amg::Transform3D &gToStation)
 
static std::pair< double, double > residualAndPullWithSegment (const TrkDriftCircleMath::Segment &segment, const Cluster2D &spacePoint, const Amg::Transform3D &gToStation)
 
static void updatePhiRanges (double phiminNew, double phimaxNew, double &phiminRef, double &phimaxRef)
 update phi ranges More...
 

Private Attributes

SG::ReadCondHandleKey< MuonGM::MuonDetectorManagerm_DetectorManagerKey
 pointers to IdHelpers More...
 
ServiceHandle< Muon::IMuonIdHelperSvcm_idHelperSvc
 
ServiceHandle< IMuonEDMHelperSvcm_edmHelperSvc
 
ToolHandle< IMdtDriftCircleOnTrackCreatorm_mdtCreator
 
ToolHandle< IMdtDriftCircleOnTrackCreatorm_mdtCreatorT0
 
ToolHandle< IMuonClusterOnTrackCreatorm_clusterCreator
 
ToolHandle< IMuonCompetingClustersOnTrackCreatorm_compClusterCreator
 
PublicToolHandle< MuonEDMPrinterToolm_printer
 
ToolHandle< IMdtSegmentFinderm_segmentFinder
 
ToolHandle< IMuonSegmentFittingToolm_segmentFitter
 
ToolHandle< IMuonSegmentSelectionToolm_segmentSelectionTool
 
ToolHandle< IDCSLFitProviderm_dcslFitProvider
 
Gaudi::Property< double > m_sinAngleCut {this, "SinAngleCut", 0.2}
 
Gaudi::Property< bool > m_doGeometry {this, "DoGeometry", true}
 
Gaudi::Property< bool > m_curvedErrorScaling {this, "CurvedErrorScaling", true}
 
Gaudi::Property< bool > m_doSpacePoints {this, "UseTriggerSpacePoints", true}
 
Gaudi::Property< bool > m_createCompetingROTsEta {this, "CreateCompetingROTsEta", true}
 
Gaudi::Property< bool > m_createCompetingROTsPhi {this, "CreateCompetingROTsPhi", true}
 
Gaudi::Property< bool > m_refitParameters {this, "RefitSegment", false}
 
Gaudi::Property< bool > m_addUnassociatedPhiHits {this, "AddUnassociatedPhiHits", false}
 
Gaudi::Property< bool > m_strictRoadDirectionConsistencyCheck {this, "StrictRoadDirectionConsistencyCheck", true}
 
Gaudi::Property< double > m_maxAssociateClusterDistance {this, "MaxAssociateClusterDistance", 3000.}
 
Gaudi::Property< bool > m_allMdtHoles {this, "AllMdtHoles", false}
 
Gaudi::Property< bool > m_removeDeltas {this, "RemoveDeltasFromSegmentQuality", true}
 
Gaudi::Property< bool > m_reject1DTgcSpacePoints {this,"Reject1DTgcSpacePoints", true }
 
Gaudi::Property< bool > m_usePreciseError {this, "UsePreciseError", false}
 
Gaudi::Property< bool > m_outputFittedT0 {this, "OutputFittedT0", false}
 
Gaudi::Property< double > m_preciseErrorScale {this, "PreciseErrorScale", 2.}
 
Gaudi::Property< bool > m_doTimeOutChecks {this, "UseTimeOutGard", false}
 
Gaudi::Property< bool > m_recoverBadRpcCabling {this, "RecoverBadRpcCabling", false}
 
Gaudi::Property< bool > m_updatePhiUsingPhiHits {this, "UpdatePhiUsingPhiHits", false}
 
Gaudi::Property< bool > m_assumePointingPhi {this, "AssumePointingPhi", false }
 
Gaudi::Property< bool > m_redo2DFit {this, "Redo2DFit", true}
 
SG::ReadHandleKey< Muon::MdtPrepDataContainerm_mdtKey {this, "MdtPrepDataContainer", "MDT_DriftCircles"}
 
SG::ReadCondHandleKey< Muon::MuonIntersectGeoDatam_chamberGeoKey {this, "ChamberGeoKey", "MuonStationIntersects", "Pointer to hole search service"}
 

Detailed Description

Implementation of a IMuonSegmentMaker.

For more details look at the mainpage of this package.

Definition at line 96 of file DCMathSegmentMaker.h.

Member Typedef Documentation

◆ ChIdHitMap

Definition at line 102 of file DCMathSegmentMaker.h.

◆ ClusterVec

Definition at line 158 of file DCMathSegmentMaker.h.

◆ ClusterVecPair

Definition at line 159 of file DCMathSegmentMaker.h.

◆ EtaPhiHitsPair

Definition at line 99 of file DCMathSegmentMaker.h.

◆ IdHitMap

Definition at line 101 of file DCMathSegmentMaker.h.

Constructor & Destructor Documentation

◆ ~DCMathSegmentMaker()

virtual Muon::DCMathSegmentMaker::~DCMathSegmentMaker ( )
virtualdefault

Member Function Documentation

◆ associateClustersToSegment()

std::pair< std::pair< int, int >, bool > Muon::DCMathSegmentMaker::associateClustersToSegment ( const TrkDriftCircleMath::Segment segment,
const Identifier chid,
const Amg::Transform3D gToStation,
ClusterVecPair spVecs,
double  phimin,
double  phimax,
std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &  rioDistVec 
) const
private

calculate distance to segment

Definition at line 1284 of file DCMathSegmentMaker.cxx.

1286  {
1287  typedef IdDataVec<std::pair<double, Cluster2D> > GasGapData;
1288  typedef IdDataVec<GasGapData> ChamberData;
1289  typedef std::vector<ChamberData> ChamberDataVec;
1290  ChamberDataVec chamberDataVec;
1291  bool isEndcap = m_idHelperSvc->isEndcap(chid);
1292 
1293  // keep track of the number of eta/phi hits on the segment
1294  bool refit = false;
1295  std::pair<std::pair<int, int>, bool> netaPhiHits(std::make_pair(0, 0), false);
1296  if (segment.clusters().empty()) return netaPhiHits;
1297 
1298  std::vector<const Trk::MeasurementBase*> phiHits;
1299 
1300  // only refit if there are sufficient phi hits and no multiple phi hits per surface
1301  refit = true;
1302 
1303  // keep track of detector elements which space points added to the track
1304  std::set<Identifier> detElOnSegments;
1305  std::set<MuonStationIndex::PhiIndex> phiIndices;
1306 
1307  ATH_MSG_DEBUG(" Associating clusters: " << segment.clusters().size() << " number of space points " << spVecs.first.size());
1308 
1309  // associate space points and sort them per detector element and gas gap
1310  for (const TrkDriftCircleMath::Cluster& clust : segment.clusters()) {
1311  ATH_MSG_VERBOSE(" accessing cluster: " << clust.index());
1312  const Cluster2D& spacePoint = spVecs.first[clust.index()];
1313 
1314  // skip corrupt space points
1315  if (spacePoint.corrupt()) {
1316  ATH_MSG_DEBUG(" Found corrupt space point: index " << clust.index());
1317  continue;
1318  }
1319  // reject TGC clusters that are not 2D
1320  if (m_reject1DTgcSpacePoints && !spacePoint.is2D() && m_idHelperSvc->isTgc(spacePoint.identify())) {
1321  ATH_MSG_DEBUG(" Rejecting 1D tgc space point " << m_idHelperSvc->toString(spacePoint.identify()));
1322  continue;
1323  }
1324  if (m_assumePointingPhi && spacePoint.is2D() && !checkPhiConsistency(spacePoint.globalPos.phi(), phimin, phimax)) {
1325  ATH_MSG_DEBUG(" Inconsistent phi angle, dropping space point: phi " << spacePoint.globalPos.phi() << " range " << phimin
1326  << " " << phimax);
1327  continue;
1328  }
1329 
1330  std::pair<double, double> resPull = residualAndPullWithSegment(segment, spacePoint, gToStation);
1331 
1332  // if empty or new chamber, add chamber
1333  if (chamberDataVec.empty() || chamberDataVec.back().id != spacePoint.detElId) {
1334  detElOnSegments.insert(spacePoint.detElId);
1335  chamberDataVec.emplace_back(spacePoint.detElId);
1336  MuonStationIndex::PhiIndex phiIndex = m_idHelperSvc->phiIndex(spacePoint.detElId);
1337  phiIndices.insert(phiIndex);
1338  }
1339 
1340  // reference to current chamber data
1341  ChamberData& chamber = chamberDataVec.back();
1342 
1343  // if same detector element
1344  if (spacePoint.detElId == chamber.id) {
1345  // if chamber empty or new gas gap, add gasp gap
1346  if (chamber.data.empty() || chamber.data.back().id != spacePoint.gasGapId) {
1347  chamber.data.emplace_back(spacePoint.gasGapId);
1348  }
1349  }
1350 
1351  // reference to current gas gap data
1352  GasGapData& gasGap = chamber.data.back();
1353  gasGap.data.emplace_back(resPull.second, spacePoint);
1354  }
1355 
1356  // calculate the distance between the first and last station, use r in barrel and z in endcaps
1357  double posFirstPhiStation{FLT_MAX}, posLastPhiStation{0.};
1358 
1359  // loop over chambers and create competing ROTs per chamber
1360  for (ChamberData& chamb : chamberDataVec) {
1361  // select best clusters per gas gap in chamber
1362  std::list<const Trk::PrepRawData*> etaClusterVec{}, phiClusterVec{};
1363  std::set<Identifier> etaIds;
1364  // loop over gas gaps
1365  for (GasGapData& gasGap : chamb.data) {
1366  // sort space points by their pull with the segment
1367  std::sort(gasGap.data.begin(), gasGap.data.end(), SortClByPull());
1368 
1369  // select all space points with a pull that is within 1 of the best pull
1370  double bestPull = std::abs(gasGap.data.front().first);
1371 
1372  // count number of associated clusters in gas gap
1373  unsigned int nassociatedSp = 0;
1374  GasGapData::EntryVec::const_iterator cl_it = gasGap.data.begin();
1375  while (cl_it != gasGap.data.end() && std::abs(cl_it->first) - bestPull < 1.) {
1376  const Cluster2D& sp = cl_it->second;
1378  double dist = distanceToSegment(segment, sp.globalPos, gToStation);
1379  ATH_MSG_VERBOSE(" selected space point: " << m_idHelperSvc->toString(sp.identify()) << " pull "
1380  << std::abs(cl_it->first) << " distance to segment " << dist << " phi "
1381  << sp.globalPos.phi());
1382 
1383  // here keep open the option not to create CompetingMuonClustersOnTrack
1384  if (sp.etaHit) {
1385  if (!etaIds.count(sp.etaHit->identify())) {
1386  etaIds.insert(sp.etaHit->identify());
1387 
1389  etaClusterVec.push_back(sp.etaHit->prepRawData());
1390  else {
1391  rioDistVec.emplace_back(dist, sp.etaHit->uniqueClone());
1392  ++netaPhiHits.first.first;
1393  }
1394  }
1395  }
1396  if (!sp.phiHits.empty()) {
1398  // can have multiple phi hits per cluster, loop over phi hits and add them
1399  std::transform(sp.phiHits.begin(), sp.phiHits.end(), std::back_inserter(phiClusterVec),
1400  [](const Muon::MuonClusterOnTrack* clus){
1401  return clus->prepRawData();
1402  });
1403  } else {
1404  // can have multiple phi hits per cluster, loop over phi hits and add them
1405  for (const MuonClusterOnTrack* phi_hit : sp.phiHits) {
1406  rioDistVec.emplace_back(dist, phi_hit->uniqueClone());
1407  ++netaPhiHits.first.second;
1408  phiHits.push_back(phi_hit);
1409 
1410  // calculate position
1411  double phiPos = isEndcap ? std::abs(phi_hit->globalPosition().z()) : phi_hit->globalPosition().perp();
1412  posFirstPhiStation = std::min(phiPos, posFirstPhiStation);
1413  posLastPhiStation = std::max(phiPos, posLastPhiStation);
1414  }
1415  if (sp.phiHits.size() > 1) refit = false;
1416  }
1417  }
1418  ++nassociatedSp;
1419  ++cl_it;
1420  }
1421  // multiple clusters in same gas gap, don't refit
1422  if (!m_createCompetingROTsPhi && nassociatedSp > 1) refit = false;
1423  }
1424 
1426  // create competing ROT for eta hits
1427  if (!etaClusterVec.empty()) {
1428  std::unique_ptr<const CompetingMuonClustersOnTrack> etaCompCluster = m_compClusterCreator->createBroadCluster(etaClusterVec, 0.);
1429  if (!etaCompCluster) {
1430  ATH_MSG_DEBUG(" failed to create competing ETA ROT " << etaClusterVec.size());
1431  } else {
1432  double dist = distanceToSegment(segment, etaCompCluster->globalPosition(), gToStation);
1433  ++netaPhiHits.first.first;
1434  if (msgLvl(MSG::VERBOSE)) {
1435  ATH_MSG_VERBOSE(" selected cluster: " << m_idHelperSvc->toString(etaClusterVec.front()->identify()));
1436  for (unsigned int i = 0; i < etaCompCluster->containedROTs().size(); ++i) {
1438  " content: " << m_idHelperSvc->toString(etaCompCluster->containedROTs()[i]->identify()));
1439  }
1440  }
1441  rioDistVec.emplace_back(dist, std::move(etaCompCluster));
1442  }
1443  }
1444  }
1445 
1447  // create competing ROT for phi hits
1448  if (!phiClusterVec.empty()) {
1449  std::unique_ptr<const CompetingMuonClustersOnTrack> phiCompCluster = m_compClusterCreator->createBroadCluster(phiClusterVec, 0.);
1450  if (!phiCompCluster) {
1451  ATH_MSG_DEBUG(" failed to create competing PHI ROT " << phiClusterVec.size());
1452  } else {
1453  double dist = distanceToSegment(segment, phiCompCluster->globalPosition(), gToStation);
1454  phiHits.push_back(phiCompCluster.get());
1455 
1456  ++netaPhiHits.first.second;
1457 
1458  if (msgLvl(MSG::VERBOSE)) {
1459  ATH_MSG_VERBOSE(" selected cluster: " << m_idHelperSvc->toString(phiClusterVec.front()->identify()));
1460  for (unsigned int i = 0; i < phiCompCluster->containedROTs().size(); ++i) {
1462  " content: " << m_idHelperSvc->toString(phiCompCluster->containedROTs()[i]->identify()));
1463  }
1464  }
1465 
1466 
1467  // calculate position
1468  double phiPos = isEndcap ? std::abs(phiCompCluster->globalPosition().z()) :
1469  phiCompCluster->globalPosition().perp();
1470  posFirstPhiStation = std::min(phiPos,posFirstPhiStation);
1471  posLastPhiStation = std::max(phiPos,posLastPhiStation);
1472  rioDistVec.emplace_back(dist, std::move(phiCompCluster));
1473 
1474  }
1475  }
1476  }
1477  }
1478 
1479  // add phi hits that were not associated with an eta hit (only in barrel)
1480  if ((!spVecs.second.empty() || m_recoverBadRpcCabling) && m_addUnassociatedPhiHits && !isEndcap) {
1482 
1483  std::map<Identifier, std::list<const Trk::PrepRawData*> > phiClusterMap;
1484 
1485  std::set<const MuonClusterOnTrack*> selectedClusters;
1486  std::vector<const Cluster2D*> phiClusters;
1487  phiClusters.reserve(spVecs.second.size());
1488 
1489  // create lists of PrepRawData per detector element
1490  for (const Cluster2D& phi_clus :spVecs.second) {
1491  if (!phi_clus.phiHit || phi_clus.corrupt()) {
1492  ATH_MSG_WARNING(" phi clusters without phi hit!!");
1493  continue;
1494  }
1495  phiClusters.push_back(&phi_clus);
1496  selectedClusters.insert(phi_clus.phiHit);
1497  }
1498 
1499  unsigned int recoveredUnassociatedPhiHits(0);
1500  if (m_recoverBadRpcCabling) {
1501  // now loop over 2D space points and add the phi hits to the list if the detEl is not yet added to the
1502  // segment
1503  for (const Cluster2D& rpc_clust : spVecs.first) {
1504  // skip clusters without phi hit
1505  if (!rpc_clust.phiHit || rpc_clust.corrupt()) continue;
1506 
1507  // skip clusters in detector elements that are already associated (ok as this is only done for RPC)
1508  if (detElOnSegments.count(rpc_clust.detElId)) continue;
1509 
1510  MuonStationIndex::PhiIndex phiIndex = m_idHelperSvc->phiIndex(rpc_clust.detElId);
1511  // skip clusters in detector layer
1512  if (phiIndices.count(phiIndex)) continue;
1513 
1514  bool wasFound = false;
1515  for (const MuonClusterOnTrack* phi_hit : rpc_clust.phiHits) {
1516  // now to avoid duplicate also skip if the given ROT is already in the list
1517  if (!selectedClusters.insert(phi_hit).second) {
1518  // flag as found
1519  wasFound = true;
1520 
1521  // just because I'm paranoid, remove the hits from this cluster that were already inserted up to
1522  // here
1523  for (const MuonClusterOnTrack* erase_me : rpc_clust.phiHits) {
1524  if (erase_me == phi_hit) break;
1525  selectedClusters.erase(erase_me);
1526  }
1527  break;
1528  }
1529  }
1530  if (wasFound) continue;
1531 
1532  // if we get here we should add the hit
1533  phiClusters.push_back(&rpc_clust);
1534  ++recoveredUnassociatedPhiHits;
1535  }
1536  }
1537 
1538  unsigned int addedPhiHits(0);
1539  for (const Cluster2D* phi_clus : phiClusters) {
1540  const Identifier& detElId = phi_clus->detElId;
1541 
1542  // check that detector element is not already added to segment
1543  if (detElOnSegments.count(detElId)) continue;
1544 
1545  MuonStationIndex::PhiIndex phiIndex = m_idHelperSvc->phiIndex(detElId);
1546  // skip clusters in detector layer
1547  if (phiIndices.count(phiIndex)) continue;
1548 
1549  // calculate local cluster position
1550  Amg::Vector3D locPos = gToStation * phi_clus->globalPos;
1551 
1552  // calculate intersect of segment with cluster
1553  TrkDriftCircleMath::Cluster cl(TrkDriftCircleMath::LocVec2D(locPos.y(), locPos.z()), 1.);
1554  double residual = resWithSegment.residual(cl);
1555  double segError = std::sqrt(resWithSegment.trackError2(cl));
1556  const MuonGM::RpcReadoutElement* detEl = dynamic_cast<const MuonGM::RpcReadoutElement*>(phi_clus->phiHit->detectorElement());
1557  if (!detEl) {
1558  ATH_MSG_WARNING("found RPC prd without RpcReadoutElement");
1559  continue;
1560  }
1561 
1562  // perform bound check
1563  double stripLength = detEl->StripLength(1);
1564  bool inBounds = std::abs(residual) < 0.5 * stripLength + 2. + segError;
1565  if (msgLvl(MSG::DEBUG)) {
1566  ATH_MSG_DEBUG(" Unassociated " << m_idHelperSvc->toString(phi_clus->phiHit->identify()) << " pos x " << cl.position().x()
1567  << " pos y " << cl.position().y() << " : residual " << residual << " strip half length "
1568  << 0.5 * stripLength << " segment error " << segError);
1569  if (inBounds)
1570  ATH_MSG_DEBUG(" inBounds");
1571  else
1572  ATH_MSG_DEBUG(" outBounds");
1573  }
1574  if (inBounds) {
1575  // can have multiple phi hits per cluster, loop over phi hits and add them
1576  std::list<const Trk::PrepRawData*>& cham_hits{phiClusterMap[detElId]};
1577  std::transform(phi_clus->phiHits.begin(), phi_clus->phiHits.end(), std::back_inserter(cham_hits),
1578  [](const MuonClusterOnTrack* clus){
1579  return clus->prepRawData();
1580  });
1581  }
1582  }
1583 
1584  // loop over detector elements and created competing ROTs
1585  for (const auto& [phi_id, prds] : phiClusterMap) {
1586  if (prds.empty()) {
1587  ATH_MSG_WARNING(" chamber without phi hits " << m_idHelperSvc->toString(phi_id));
1588  continue;
1589  }
1590 
1591  std::unique_ptr<const CompetingMuonClustersOnTrack> phiCompCluster = m_compClusterCreator->createBroadCluster(prds, 0.);
1592  if (!phiCompCluster) {
1593  ATH_MSG_DEBUG(" failed to create competing PHI ROT " << prds.size());
1594  } else {
1595  double dist = distanceToSegment(segment, phiCompCluster->globalPosition(), gToStation);
1596 
1597  if (std::abs(dist) > m_maxAssociateClusterDistance) {
1598 
1599  ATH_MSG_VERBOSE(" rejected unassociated cluster: " << m_idHelperSvc->toString(prds.front()->identify())
1600  << " distance to segment " << dist);
1601  continue;
1602  }
1603  phiHits.push_back(phiCompCluster.get());
1604  ++netaPhiHits.first.second;
1605  ++addedPhiHits;
1606  if (msgLvl(MSG::VERBOSE)) {
1607  ATH_MSG_VERBOSE(" selected unassociated cluster: " << m_idHelperSvc->toString(prds.front()->identify())
1608  << " distance to segment " << dist);
1609  for (unsigned int i = 0; i < phiCompCluster->containedROTs().size(); ++i) {
1611  " content: " << m_idHelperSvc->toString(phiCompCluster->containedROTs()[i]->identify()));
1612  }
1613  }
1614  rioDistVec.emplace_back(dist, std::move(phiCompCluster));
1615  }
1616  }
1617  ATH_MSG_VERBOSE("Added " << addedPhiHits << " unass phi hits out of " << spVecs.second.size()
1618  << " phi hits without eta hit and " << recoveredUnassociatedPhiHits << " with unassociated eta hit ");
1619  }
1620 
1621  // calculate distance between first and last phi trigger hit, refit if there is a good constraint on phi
1622  double phiDistanceMax = posLastPhiStation - posFirstPhiStation;
1623  if (isEndcap && phiDistanceMax < 1000.)
1624  refit = false;
1625  else if (phiDistanceMax < 400.)
1626  refit = false;
1627 
1628  netaPhiHits.second = refit;
1629  return netaPhiHits;
1630  }

◆ associateMDTsToSegment()

void Muon::DCMathSegmentMaker::associateMDTsToSegment ( const Amg::Vector3D gdir,
TrkDriftCircleMath::Segment segment,
const TrkDriftCircleMath::ChamberGeometry multiGeo,
const Amg::Transform3D gToStation,
const Amg::Transform3D amdbToGlobal,
std::set< Identifier > &  deltaVec,
std::set< Identifier > &  outoftimeVec,
std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &  rioDistVec,
double  beta = 1. 
) const
private

Definition at line 1149 of file DCMathSegmentMaker.cxx.

1153  {
1154  // clear result vectors
1155 
1156  // convert segment parameters + x position from road
1157  const TrkDriftCircleMath::Line& line = segment.line();
1160  if (segment.hasCurvatureParameters()) {
1161  // ml2 segment direction
1162  double ml2phi = line.phi() - segment.deltaAlpha();
1163  TrkDriftCircleMath::LocVec2D ml2dir(std::cos(ml2phi), std::sin(ml2phi));
1164  // ml2 segment position
1165  const TrkDriftCircleMath::LocVec2D ml1LocPos = multiGeo->tubePosition(0, multiGeo->nlay(), 0);
1166  const TrkDriftCircleMath::LocVec2D ml2LocPos = multiGeo->tubePosition(1, 1, 0);
1167  double chamberMidPtY = (ml1LocPos.y() + ml2LocPos.y()) / 2.0;
1168  TrkDriftCircleMath::LocVec2D ml2pos(segment.deltab(), chamberMidPtY);
1169  // construct the new ml2 segment line & transform
1170  const TrkDriftCircleMath::Line ml2line(ml2pos, ml2dir);
1171  TrkDriftCircleMath::TransformToLine tmptoLine(ml2line);
1172  // set the ml2 line
1173  toLineml2 = tmptoLine;
1174  }
1175 
1176  for (TrkDriftCircleMath::DCOnTrack& dcit : segment.dcs()) {
1177  if (dcit.state() == TrkDriftCircleMath::DCOnTrack::Delta) { deltaVec.insert(dcit.rot()->identify()); }
1178 
1179  if (dcit.state() == TrkDriftCircleMath::DCOnTrack::OutOfTime) { outoftimeVec.insert(dcit.rot()->identify()); }
1180 
1181  if (dcit.state() != TrkDriftCircleMath::DCOnTrack::OnTrack) continue;
1182 
1183  const MdtDriftCircleOnTrack* riodc{dcit.rot()};
1184 
1185  // choose which line to use (ml1 or ml2)
1186  TrkDriftCircleMath::TransformToLine toLine = toLineml1;
1187  if (m_idHelperSvc->mdtIdHelper().multilayer(riodc->identify()) == 2) toLine = toLineml2;
1188  // calculate position of hit in line frame
1189  TrkDriftCircleMath::LocVec2D pointOnHit = toLine.toLine(dcit.position());
1190 
1191  // calculate position of hit on line in line frame
1192  TrkDriftCircleMath::LocVec2D pointOnLine(pointOnHit.x(), 0.);
1193 
1194  // transform back to local AMDB coordinates
1195  TrkDriftCircleMath::LocVec2D pointOnLineAMDB = toLine.toLocal(pointOnLine);
1196 
1197  // get position along wire from ROT
1198  Amg::Vector3D posAlong = gToStation * riodc->globalPosition();
1199 
1200  // set yz components
1201  posAlong[1] = pointOnLineAMDB.x();
1202  posAlong[2] = pointOnLineAMDB.y();
1203 
1204  // back to global
1205  Amg::Vector3D mdtGP = amdbToGlobal * posAlong;
1206 
1207  const Trk::StraightLineSurface* surf = dynamic_cast<const Trk::StraightLineSurface*>(&riodc->associatedSurface());
1208  if (!surf) {
1209  ATH_MSG_WARNING(" dynamic cast to StraightLineSurface failed for mdt!!! ");
1210  continue;
1211  }
1212 
1213  // calculate Amg::Vector2D using surf to obtain sign
1215  if (!surf->globalToLocal(mdtGP, gdir, locPos)) ATH_MSG_WARNING(" globalToLocal failed ");
1216 
1217  // calculate side
1219 
1220  std::unique_ptr<MdtDriftCircleOnTrack> nonconstDC;
1221  bool hasT0 = segment.hasT0Shift();
1222  if (!hasT0 || m_mdtCreatorT0.empty()) {
1223  // ATH_MSG_VERBOSE(" recalibrate MDT hit");
1224  nonconstDC.reset(m_mdtCreator->createRIO_OnTrack(*riodc->prepRawData(), mdtGP, &gdir, 0., nullptr, beta, 0.));
1225  if (hasT0) ATH_MSG_WARNING("Attempted to change t0 without a properly configured MDT creator tool. ");
1226  } else {
1227  ATH_MSG_VERBOSE(" recalibrate MDT hit with shift " << segment.t0Shift()<<" "<<m_printer->print(*riodc));
1228  nonconstDC.reset(m_mdtCreatorT0->createRIO_OnTrack(*riodc->prepRawData(), mdtGP, &gdir, segment.t0Shift()));
1229  }
1230 
1231  if (!nonconstDC) {
1233  continue;
1234  }
1235  ATH_MSG_VERBOSE("Post calibrated hit "<<m_printer->print(*nonconstDC));
1236 
1237  // update the drift radius after recalibration, keep error
1238  TrkDriftCircleMath::DriftCircle new_dc(dcit.position(), std::abs(nonconstDC->driftRadius()), dcit.dr(), dcit.drPrecise(),
1239  dcit.driftState(), dcit.id(),
1240  nonconstDC.get());
1241  TrkDriftCircleMath::DCOnTrack new_dc_on_track(new_dc, dcit.residual(), dcit.errorTrack());
1242  dcit = std::move(new_dc_on_track);
1243 
1244  if (hasT0) {
1245  if (msgLvl(MSG::VERBOSE)) {
1246  double shift = riodc->driftTime() - nonconstDC->driftTime();
1247  ATH_MSG_VERBOSE(" t0 shift " << segment.t0Shift() << " from hit " << shift << " recal " << nonconstDC->driftRadius()
1248  << " t " << nonconstDC->driftTime() << " from fit " << dcit.r() << " old "
1249  << riodc->driftRadius() << " t " << riodc->driftTime());
1250  if (std::abs(std::abs(nonconstDC->driftRadius()) - std::abs(dcit.r())) > 0.1 && nonconstDC->driftRadius() < 19. &&
1251  nonconstDC->driftRadius() > 1.) {
1252  ATH_MSG_WARNING("Detected invalid recalibration after T0 shift");
1253  }
1254  }
1255  }
1256  m_mdtCreator->updateSign(*nonconstDC, side);
1257  double dist = pointOnHit.x();
1258  rioDistVec.emplace_back(dist, std::move(nonconstDC));
1259  }
1260  }

◆ calculateHoles()

std::vector< Identifier > Muon::DCMathSegmentMaker::calculateHoles ( const EventContext &  ctx,
Identifier  chid,
const Amg::Vector3D gpos,
const Amg::Vector3D gdir,
bool  hasMeasuredCoordinate,
std::set< Identifier > &  deltaVec,
std::set< Identifier > &  outoftimeVec,
const std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &  rioDistVec 
) const
private

Definition at line 1689 of file DCMathSegmentMaker.cxx.

1691  {
1692  // calculate crossed tubes
1694  if (!InterSectSvc.isValid()) {
1695  ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
1696  return {};
1697  }
1699  const MuonGM::MuonDetectorManager* MuonDetMgr = detMgr.cptr();
1700 
1701  const MuonStationIntersect intersect = InterSectSvc->tubesCrossedByTrack(MuonDetMgr, chid, gpos, gdir);
1702 
1703  // set to identify the hit on the segment
1704  std::set<Identifier> hitsOnSegment, chambersOnSegment;
1705  int firstLayer{-1}, lastLayer{-1};
1706  for (const std::pair<double, std::unique_ptr<const Trk::MeasurementBase>>& rdit : rioDistVec) {
1707  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(rdit.second.get());
1708  if (!mdt) continue;
1709  const Identifier id = mdt->identify();
1710  int layer = (m_idHelperSvc->mdtIdHelper().tubeLayer(id) - 1) + 4 * (m_idHelperSvc->mdtIdHelper().multilayer(id) - 1);
1711  if (firstLayer == -1)
1712  firstLayer = layer;
1713  else
1714  lastLayer = layer;
1715 
1716  hitsOnSegment.insert(id);
1717  chambersOnSegment.insert(m_idHelperSvc->chamberId(id));
1718  }
1719 
1720  // cross check for cosmic case
1721  if (firstLayer > lastLayer) { std::swap(firstLayer, lastLayer); }
1722  ATH_MSG_VERBOSE(" Tube layer ranges: " << firstLayer << " -- " << lastLayer << " crossed tubes "
1723  << intersect.tubeIntersects().size());
1724  // clear hole vector
1725  std::vector<Identifier> holeVec;
1726  for (const MuonTubeIntersect& tint : intersect.tubeIntersects()) {
1727  if (!chambersOnSegment.count(m_idHelperSvc->chamberId(tint.tubeId))) {
1728  ATH_MSG_VERBOSE(" chamber not on segment, not counting tube " << tint.rIntersect << " l " << tint.xIntersect << " "
1729  << m_idHelperSvc->toString(tint.tubeId));
1730  continue;
1731  }
1732 
1733  const Identifier& id = tint.tubeId;
1734  int layer = (m_idHelperSvc->mdtIdHelper().tubeLayer(id) - 1) + 4 * (m_idHelperSvc->mdtIdHelper().multilayer(id) - 1);
1735 
1736  bool notBetweenHits = layer < firstLayer || layer > lastLayer;
1737  double distanceCut = hasMeasuredCoordinate ? -20 : -200.;
1738  double innerRadius = MuonDetMgr->getMdtReadoutElement(id)->innerTubeRadius();
1739  if (notBetweenHits && (std::abs(tint.rIntersect) > innerRadius || (!m_allMdtHoles && tint.xIntersect > distanceCut))) {
1740  ATH_MSG_VERBOSE(" not counting tube: distance to wire " << tint.rIntersect << " dist to tube end " << tint.xIntersect
1741  << " " << m_idHelperSvc->toString(tint.tubeId));
1742  continue;
1743  }
1744  // check whether there is a hit in this tube
1745  if (hitsOnSegment.count(tint.tubeId)) {
1746  ATH_MSG_VERBOSE(" tube on segment: distance to wire " << tint.rIntersect << " dist to tube end " << tint.xIntersect
1747  << " " << m_idHelperSvc->toString(tint.tubeId));
1748  continue;
1749  }
1750  // check whether there is a delta electron in this tube
1751  if (m_removeDeltas) {
1752  if (deltaVec.count(tint.tubeId)) {
1753  ATH_MSG_VERBOSE(" removing delta, distance to wire " << tint.rIntersect << " dist to tube end " << tint.xIntersect
1754  << " " << m_idHelperSvc->toString(tint.tubeId));
1755  continue;
1756  }
1757 
1758  const MdtPrepData* prd = findMdt(ctx, id);
1759  if (prd && std::abs(prd->localPosition()[Trk::locR]) < std::abs(tint.rIntersect)) {
1760  ATH_MSG_VERBOSE(" found and removed delta, distance to wire " << tint.rIntersect << " dist to tube end "
1761  << tint.xIntersect << " "
1762  << m_idHelperSvc->toString(tint.tubeId));
1763  continue;
1764  }
1765  }
1766  ATH_MSG_VERBOSE((outoftimeVec.count(tint.tubeId) ? "Out-of-time" : "hole") << " distance to wire "
1767  << tint.rIntersect << " dist to tube end " << tint.xIntersect << " "
1768  << m_idHelperSvc->toString(tint.tubeId)<<(notBetweenHits ? "outside hits" : "between hits"));
1769 
1770  holeVec.push_back(tint.tubeId);
1771  }
1772  return holeVec;
1773  }

◆ checkBoundsInXZ()

bool Muon::DCMathSegmentMaker::checkBoundsInXZ ( double  xline,
double  zline,
double  dXdZ,
const std::vector< HitInXZ > &  hits 
) const
private

check whether all hits are in bounds in the XZ plane

Definition at line 1824 of file DCMathSegmentMaker.cxx.

1825  {
1826  bool ok = true;
1827 
1828  // look over hits and check whether all are in bounds
1829  for (const HitInXZ& hit : hits) {
1830  bool outBounds = false;
1831  double locExX = xline + dXdZ * (hit.z - zline);
1832  if (hit.isMdt && (locExX < hit.xmin - 1. || locExX > hit.xmax + 1.)) {
1833  ok = false;
1834  outBounds = true;
1835  if (!msgLvl(MSG::DEBUG)) break;
1836  }
1837 
1838  if (outBounds && msgLvl(MSG::DEBUG)) {
1839  ATH_MSG_DEBUG(" " << std::setw(65) << m_idHelperSvc->toString(hit.id) << " pos (" << std::setw(6) << (int)hit.x << ","
1840  << std::setw(6) << (int)hit.z << ") ex pos " << std::setw(6) << (int)locExX << " min " << std::setw(6)
1841  << (int)hit.xmin << " max " << std::setw(6) << (int)hit.xmax << " phimin " << std::setw(6)
1842  << hit.phimin << " phimax " << std::setw(6) << hit.phimax << " outBounds, cross-check");
1843  }
1844  }
1845  return ok;
1846  }

◆ checkPhiConsistency()

bool Muon::DCMathSegmentMaker::checkPhiConsistency ( double  phi,
double  phimin,
double  phimax 
) const
private

check whether phi is consistent with segment phi

Definition at line 2100 of file DCMathSegmentMaker.cxx.

2100  {
2101  // only if assuming pointing phi
2102  if (!m_assumePointingPhi) return true;
2103 
2104  bool phiOk = true;
2105  double offset = 0.05;
2106  if (phimin * phimax < 0.) {
2107  if (phi < 0.) {
2108  if (phi > -1.1) {
2109  if (phi < phimin - offset) phiOk = false;
2110  } else {
2111  if (phi > phimin + offset) phiOk = false;
2112  }
2113  } else {
2114  if (phi > 1.1) {
2115  if (phi < phimax - offset) phiOk = false;
2116  } else {
2117  if (phi > phimax + offset) phiOk = false;
2118  }
2119  }
2120  } else {
2121  if (phi < phimin - offset || phi > phimax + offset) phiOk = false;
2122  }
2123  return phiOk;
2124  }

◆ create1DClusters()

DCMathSegmentMaker::ClusterVecPair Muon::DCMathSegmentMaker::create1DClusters ( const std::vector< const MuonClusterOnTrack * > &  clusters) const
private

Definition at line 694 of file DCMathSegmentMaker.cxx.

694  {
695  // if empty return
696  if (clusters.empty()) return {};
697  // some useful typedefs...
698 
699  // create a vector to hold the clusters
700  ClusterVec clVec;
701  ClusterVec phiVec;
702  clVec.reserve(clusters.size());
703 
704  for (const MuonClusterOnTrack* clust : clusters) {
705  const Identifier id = clust->identify();
706  const Identifier gasGapId = m_idHelperSvc->gasGapId(id);
707 
708  if (m_idHelperSvc->measuresPhi(id)) {
709  phiVec.push_back(createSpacePoint(gasGapId, nullptr, clust));
710  if (phiVec.back().corrupt()) phiVec.pop_back();
711  } else {
712  clVec.push_back(createSpacePoint(gasGapId, clust, nullptr));
713  if (clVec.back().corrupt()) clVec.pop_back();
714  }
715  }
716 
717  return ClusterVecPair(clVec, phiVec);
718  }

◆ create2DClusters()

DCMathSegmentMaker::ClusterVecPair Muon::DCMathSegmentMaker::create2DClusters ( const std::vector< const MuonClusterOnTrack * > &  clusters) const
private

Definition at line 720 of file DCMathSegmentMaker.cxx.

720  {
721  // if empty return
722  if (clusters.empty()) return {};
723 
724  ChIdHitMap gasGapHitMap;
725  for (const MuonClusterOnTrack* clus: clusters) {
726  const Identifier id = clus->identify();
727  ATH_MSG_VERBOSE(" new trigger hit " << m_idHelperSvc->toString(id));
728 
729  const Identifier chId = m_idHelperSvc->chamberId(id);
730  const Identifier gasGapId = m_idHelperSvc->gasGapId(id);
731  // eta hits first than phi hits
732  if (!m_idHelperSvc->measuresPhi(id))
733  gasGapHitMap[chId][gasGapId].first.push_back(clus);
734  else
735  gasGapHitMap[chId][gasGapId].second.push_back(clus);
736  }
737 
738  return createSpacePoints(gasGapHitMap);
739  }

◆ createChamberGeometry()

TrkDriftCircleMath::MdtChamberGeometry Muon::DCMathSegmentMaker::createChamberGeometry ( const Identifier chid,
const Amg::Transform3D gToStation 
) const
private

Definition at line 1073 of file DCMathSegmentMaker.cxx.

1074  {
1075  /* calculate chamber geometry
1076  it takes as input:
1077  distance between the first and second tube in the chamber within a layer along the tube layer (tube distance)
1078  distance between the first tube in the first layer and the first tube in the second layer along the tube layer
1079  (tube stagering) distance between the first and second layer perpendicular to the tube layers (layer distance)
1080  position of the first hit in ml 0 and ml 1 (2D in plane)
1081  total number of multilayers
1082  total number of layers
1083  total number of tubes per layer for each multilayer
1084  an identifier uniquely identifying the chamber
1085  */
1086 
1087  Amg::Vector3D firstTubeMl0{Amg::Vector3D::Zero()};
1088  Amg::Vector3D firstTubeMl1{Amg::Vector3D::Zero()};
1089 
1090  // get id
1091  int eta = m_idHelperSvc->mdtIdHelper().stationEta(chid);
1092  int phi = m_idHelperSvc->mdtIdHelper().stationPhi(chid);
1093  int name = m_idHelperSvc->mdtIdHelper().stationName(chid);
1094 
1096  const MuonGM::MuonDetectorManager* MuonDetMgr{*DetectorManagerHandle};
1097  if (!MuonDetMgr) {
1098  ATH_MSG_ERROR("Null pointer to the read MuonDetectorManager conditions object");
1099  return {};
1100  }
1101 
1102  // get detEL for first ml (always there)
1103  const MuonGM::MdtReadoutElement* detEl1 =
1104  MuonDetMgr->getMdtReadoutElement(m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 1, 1, 1));
1105  const MuonGM::MdtReadoutElement* detEl2 = nullptr;
1106  int ntube2 = 0;
1107  // number of multilayers in chamber
1108  int nml = detEl1->nMDTinStation();
1109 
1110  // treament of chambers with two ml
1111  if (nml == 2) {
1112  Identifier firstIdml1 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 2, 1, 1);
1113  detEl2 = MuonDetMgr->getMdtReadoutElement(firstIdml1);
1114  firstTubeMl1 = gToStation * (detEl2->surface(firstIdml1).center());
1115  ntube2 = detEl2->getNtubesperlayer();
1116  }
1117 
1118  // number of layers and tubes
1119  int nlay = detEl1->getNLayers();
1120  int ntube1 = detEl1->getNtubesperlayer();
1121 
1122  // position first tube in ml 0
1123  Identifier firstIdml0 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 1, 1, 1);
1124  firstTubeMl0 = gToStation * (detEl1->surface(firstIdml0).center());
1125 
1126  // position second tube in ml 0
1127  Identifier secondIdml0 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 1, 1, 2);
1128  Amg::Vector3D secondTubeMl0 = gToStation * (detEl1->surface(secondIdml0).center());
1129 
1130  TrkDriftCircleMath::LocVec2D firstTube0(firstTubeMl0.y(), firstTubeMl0.z());
1131  TrkDriftCircleMath::LocVec2D firstTube1(firstTubeMl1.y(), firstTubeMl1.z());
1132 
1133  // position first tube ml 0 and 1
1134  Identifier firstIdml0lay1 = m_idHelperSvc->mdtIdHelper().channelID(name, eta, phi, 1, 2, 1);
1135  Amg::Vector3D firstTubeMl0lay1 = gToStation * (detEl1->surface(firstIdml0lay1).center());
1136 
1137  double tubeDist = (secondTubeMl0 - firstTubeMl0).y(); // distance between tube in a given layer
1138  double tubeStage = (firstTubeMl0lay1 - firstTubeMl0).y(); // tube stagering distance
1139  double layDist = (firstTubeMl0lay1 - firstTubeMl0).z(); // distance between layers
1140 
1141  TrkDriftCircleMath::MdtChamberGeometry mdtgeo(chid, m_idHelperSvc.get(), nml, nlay, ntube1, ntube2, firstTube0, firstTube1, tubeDist, tubeStage,
1142  layDist, detEl1->surface().center().theta());
1143 
1144  if (msgLvl(MSG::VERBOSE)) mdtgeo.print(msgStream());
1145 
1146  return mdtgeo;
1147  }

◆ createClusterVec()

TrkDriftCircleMath::CLVec Muon::DCMathSegmentMaker::createClusterVec ( const Identifier chid,
ClusterVec spVec,
const Amg::Transform3D gToStation 
) const
private

Definition at line 978 of file DCMathSegmentMaker.cxx.

979  {
981 
982  const int chPhi = m_idHelperSvc->mdtIdHelper().stationPhi(chid);
983 
984  // loop over clusters
985  int index{-1};
986  cls.reserve(spVec.size());
987  for (const Cluster2D& clust : spVec) {
988  ++index;
989  const MuonClusterOnTrack* meas = clust.etaHit ? clust.etaHit : clust.phiHit;
990  // construct cluster id
991  const Identifier id = meas->identify();
992  const int measuresPhi = m_idHelperSvc->measuresPhi(id);
993  const int eta = m_idHelperSvc->stationEta(id);
994  const int phi = m_idHelperSvc->stationPhi(id);
995  const int isTgc = m_idHelperSvc->isTgc(id);
996  const int name = isTgc ? m_idHelperSvc->tgcIdHelper().stationName(id) : m_idHelperSvc->rpcIdHelper().stationName(id);
997  if (!isTgc) {
998  if (chPhi != phi) {
999  ATH_MSG_VERBOSE(" Discarding cluster, wrong station phi " << m_idHelperSvc->toString(id));
1000  continue;
1001  }
1002  }
1003  TrkDriftCircleMath::ClusterId clid{name, eta, phi, isTgc, measuresPhi};
1004 
1005  // calculate local cluster position
1006  Amg::Vector3D locPos = gToStation * clust.globalPos;
1007  TrkDriftCircleMath::LocVec2D lp(locPos.y(), locPos.z());
1008 
1009  if (std::abs(lp.y()) > m_maxAssociateClusterDistance) {
1010  ATH_MSG_VERBOSE(" Discarding cluster with large distance from chamber " << m_idHelperSvc->toString(id));
1011  continue;
1012  }
1013  ATH_MSG_VERBOSE(" " << m_idHelperSvc->toString(id) << " clid: " << clid.id() << " central phi "
1014  << meas->detectorElement()->center().phi() << " index " << index);
1015  cls.emplace_back(lp, clust.error, clid, meas, index);
1016  }
1017  return cls;
1018  }

◆ createDCVec()

TrkDriftCircleMath::DCVec Muon::DCMathSegmentMaker::createDCVec ( const std::vector< const MdtDriftCircleOnTrack * > &  mdts,
double  errorScale,
std::set< Identifier > &  chamberSet,
double &  phimin,
double &  phimax,
TrkDriftCircleMath::DCStatistics dcStatistics,
const Amg::Transform3D gToStation,
const Amg::Transform3D amdbToGlobal 
) const
private

Definition at line 1020 of file DCMathSegmentMaker.cxx.

1023  {
1025  dcs.reserve(mdts.size());
1026  /* ******** Mdt hits ******** */
1027  bool firstMdt = true;
1028 
1029  for (const MdtDriftCircleOnTrack* rot : mdts) {
1030 
1031  Identifier id = rot->identify();
1032  Identifier elId = m_idHelperSvc->mdtIdHelper().elementID(id);
1033 
1034  // calculate local AMDB position
1035  Amg::Vector3D locPos = gToStation * rot->prepRawData()->globalPosition();
1036  TrkDriftCircleMath::LocVec2D lpos(locPos.y(), locPos.z());
1037 
1038  double r = rot->localParameters()[Trk::locR];
1039  double dr = Amg::error(rot->localCovariance(), Trk::locR) * errorScale;
1040 
1041  // create identifier
1042  TrkDriftCircleMath::MdtId mdtid(m_idHelperSvc->mdtIdHelper().isBarrel(id), m_idHelperSvc->mdtIdHelper().multilayer(id) - 1,
1043  m_idHelperSvc->mdtIdHelper().tubeLayer(id) - 1, m_idHelperSvc->mdtIdHelper().tube(id) - 1);
1044 
1045  //
1046  double preciseError = dr;
1047  if (m_usePreciseError) { preciseError = m_preciseErrorScale * (0.23 * std::exp(-std::abs(r) / 6.06) + 0.0362); }
1048  // create new DriftCircle
1049  TrkDriftCircleMath::DriftCircle dc(lpos, r, dr, preciseError, TrkDriftCircleMath::DriftCircle::InTime, mdtid, rot);
1050 
1051  TubeEnds tubeEnds = localTubeEnds(*rot, gToStation, amdbToGlobal);
1052  if (firstMdt) {
1053  phimin = tubeEnds.phimin;
1054  phimax = tubeEnds.phimax;
1055  firstMdt = false;
1056  } else {
1057  updatePhiRanges(tubeEnds.phimin, tubeEnds.phimax, phimin, phimax);
1058  }
1059 
1060  ATH_MSG_VERBOSE(" new MDT hit " << m_idHelperSvc->toString(id) << " x " << lpos.x() << " y " << lpos.y() << " time "
1061  << rot->driftTime() << " r " << r << " dr " << dr << " phi range " << tubeEnds.phimin << " "
1062  << tubeEnds.phimax<<" precise error "<<preciseError);
1063  dcs.push_back(std::move(dc));
1064 
1065  chamberSet.insert(elId);
1066 
1067  ++dcStatistics[rot->prepRawData()->detectorElement()];
1068  }
1069 
1070  return dcs;
1071  }

◆ createROTVec()

DataVector< const Trk::MeasurementBase > Muon::DCMathSegmentMaker::createROTVec ( std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &  rioDistVec)
staticprivate

Definition at line 1655 of file DCMathSegmentMaker.cxx.

1656  {
1657  // sort hits according to they distance to the segment position
1658  std::sort(rioDistVec.begin(), rioDistVec.end(), SortByDistanceToSegment());
1659 
1661  rioVec.reserve(rioDistVec.size());
1662  for (std::pair<double, std::unique_ptr<const Trk::MeasurementBase>>& rdit : rioDistVec) { rioVec.push_back(std::move(rdit.second)); }
1663  rioDistVec.clear();
1664  return rioVec;
1665  }

◆ createRpcSpacePoint()

DCMathSegmentMaker::Cluster2D Muon::DCMathSegmentMaker::createRpcSpacePoint ( const Identifier gasGapId,
const MuonClusterOnTrack etaHit,
const std::vector< const MuonClusterOnTrack * > &  phiHits 
) const
private

Definition at line 917 of file DCMathSegmentMaker.cxx.

918  {
919  // create vector to store phi hits after removal of duplicate hits
920  std::vector<const MuonClusterOnTrack*> cleanPhihits;
921  cleanPhihits.reserve(phiHits.size());
922 
923  double error{1.}, lpx{0.}, lpy{0.};
924  // case one hit missing. Take position and error of the available hit
925  if (!etaHit) {
926  lpx = phiHits.front()->localParameters()[Trk::locX];
927  error = Amg::error(phiHits.front()->localCovariance(), Trk::locX);
928  // loop over phi hits, remove duplicate phi hits
929  Identifier prevId;
930  for (const MuonClusterOnTrack* clus : phiHits) {
931  // remove duplicate phi hits
932  if (clus->identify() == prevId) continue;
933  prevId = clus->identify();
934  cleanPhihits.push_back(clus);
935  }
936  } else if (phiHits.empty()) {
937  lpx = etaHit->localParameters()[Trk::locX];
938  error = Amg::error(etaHit->localCovariance(), Trk::locX);
939  } else if (etaHit && !phiHits.empty()) {
940  lpx = etaHit->localParameters()[Trk::locX];
941  error = Amg::error(etaHit->localCovariance(), Trk::locX);
942 
943  ATH_MSG_DEBUG(" RPC space point: error " << error << " stripWith " << error * M_SQRT2 << std::endl
944  << " " << m_idHelperSvc->toString(etaHit->identify()));
945 
946  double minPos{1e9}, maxPos{-1e9};
947  Identifier prevId;
948 
949  // loop over phi hits, calculate average position + cluster width, remove duplicate phi hits
950  for (const MuonClusterOnTrack* phiHit : phiHits) {
951  // remove duplicate phi hits
952  if (phiHit->identify() == prevId) continue;
953  prevId = phiHit->identify();
954 
955  // calculate phi hit position in local eta hit reference frame
956  Amg::Vector2D phiLocPos{Amg::Vector2D::Zero()};
957  if (etaHit->associatedSurface().globalToLocal(phiHit->globalPosition(), phiHit->globalPosition(), phiLocPos)) {
958  lpy = phiLocPos[Trk::locY];
959  minPos = std::min(minPos, lpy);
960  maxPos = std::max(maxPos, lpy);
961  ATH_MSG_DEBUG(" " << m_idHelperSvc->toString(phiHit->identify()));
962  cleanPhihits.push_back(phiHit);
963  }
964  }
965  if (cleanPhihits.size() > 1)
966  ATH_MSG_DEBUG(" multiple phi hits: nhits " << cleanPhihits.size() << " cl width " << maxPos - minPos);
967  } else {
968  ATH_MSG_DEBUG(" ARRRGGG got two empty pointers!!! ");
969  }
970  Identifier detElId = m_idHelperSvc->detElId(gasGapId);
971  if (std::abs(error) < 0.001) {
972  ATH_MSG_WARNING(" Unphysical error assigned for gasgap " << m_idHelperSvc->toString(gasGapId));
973  error = 1.;
974  }
975  return Cluster2D(detElId, gasGapId, Amg::Vector2D(lpx, lpy), error, etaHit, !cleanPhihits.empty() ? cleanPhihits : phiHits);
976  }

◆ createSegment()

std::unique_ptr< MuonSegment > Muon::DCMathSegmentMaker::createSegment ( const EventContext &  ctx,
TrkDriftCircleMath::Segment segment,
const Identifier chid,
const Amg::Vector3D roadpos,
const Amg::Vector3D roaddir2,
const std::vector< const MdtDriftCircleOnTrack * > &  mdts,
bool  hasPhiMeasurements,
segmentCreationInfo sInfo,
double  beta = 1. 
) const
private

Use linearity of the sin at leading order to check that the angular differences are either 0 or PI

Copy hits into vector

recalculate global direction and position

Definition at line 227 of file DCMathSegmentMaker.cxx.

230  {
231  bool isEndcap = m_idHelperSvc->isEndcap(chid);
232  // find all curved segments
233  MuonStationIndex::ChIndex chIndex = m_idHelperSvc->chamberIndex(chid);
234 
235  static constexpr std::array<ChIndex ,4> statWithField{ChIndex::BIL, ChIndex::BML, ChIndex::BMS, ChIndex::BOL};
236  const bool isCurvedSegment = segment.hasCurvatureParameters() &&
237  std::ranges::find(statWithField, chIndex) != statWithField.end();
238 
239  // remove segments with too few hits
240  if (segment.hitsOnTrack() < 3) return nullptr;
241 
242  // convert segment parameters + x position from road
243  const TrkDriftCircleMath::Line& line = segment.line();
244 
245  ATH_MSG_DEBUG("New segment: chi2 " << segment.chi2() << " ndof " << segment.ndof() << " line " << line.position().x() << ","
246  << line.position().y() << " phi " << line.phi() << " associated clusters "
247  << segment.clusters().size());
248 
249  // local position along x from road
250  Amg::Vector3D lroadpos = sInfo.globalTrans * roadpos;
251  Amg::Vector3D lroaddir = sInfo.globalTrans.linear() * roaddir2;
252 
253  // local x position of first tube used if no phi measurement is present
254  double lxroad = 0.;
255 
256  if (hasPhiMeasurements) {
257  // calculate local position of segment along tube using the road
258  // calculate intersect pattern measurement plane
259  double sphi = 0.;
260  double cphi = lroaddir.x();
261  // swap local y and z in the endcaps
262  if (isEndcap) {
263  sphi = lroaddir.y();
264  lxroad = lroadpos.x() + (-lroadpos.y() + line.position().x()) * cphi / absmax(sphi, std::numeric_limits<double>::min());
265  } else {
266  sphi = lroaddir.z();
267  lxroad = lroadpos.x() + (-lroadpos.z() + line.position().y()) * cphi / absmax(sphi, std::numeric_limits<double>::min());
268  }
269 
270  double shortestTubeLen = 1e9;
271  // loop over hits and get the shortest tube on the segment
272  for (const TrkDriftCircleMath::DCOnTrack& driftCircle : segment.dcs()) {
273  if (driftCircle.state() != TrkDriftCircleMath::DCOnTrack::OnTrack) continue;
274 
275  const MdtDriftCircleOnTrack* riodc{driftCircle.rot()};
276  int lay = m_idHelperSvc->mdtIdHelper().tubeLayer(riodc->identify());
277  int tube = m_idHelperSvc->mdtIdHelper().tube(riodc->identify());
278  double tubelen = 0.5 * riodc->prepRawData()->detectorElement()->getActiveTubeLength(lay, tube);
279  if (tubelen < shortestTubeLen) shortestTubeLen = tubelen;
280  }
281  // if the predicted position lies outside the chamber move it back inside
282  if (std::abs(lxroad) > shortestTubeLen) {
283  ATH_MSG_DEBUG("coordinates far outside chamber! using global position of first hit ");
284  if (lxroad < 0.) shortestTubeLen *= -1.;
285  lxroad = shortestTubeLen;
286  }
287  } else {
288  lxroad = (sInfo.globalTrans * mdts[0]->prepRawData()->detectorElement()->surface(mdts[0]->identify()).center()).x();
289  }
290 
291  // calculate local direction vector
292  Amg::Vector3D lpos(lxroad, line.position().x(), line.position().y());
293 
294  // global position segment
295  Amg::Vector3D gpos = sInfo.amdbTrans * lpos;
296 
297  // create new surface
298  Amg::Transform3D surfaceTransform(sInfo.amdbTrans.rotation());
299  surfaceTransform.pretranslate(gpos);
300  double surfDim = 500.;
301  std::unique_ptr<Trk::PlaneSurface> surf = std::make_unique<Trk::PlaneSurface>(surfaceTransform, surfDim, surfDim);
302 
303  // measurements
304  Amg::Vector2D segLocPos{Amg::Vector2D::Zero()};
305  double linephi = line.phi();
306 
307  // now update the global direction using the local precision angle of the segment and the global phi angle of the
308  // road.
309  Amg::Vector3D gdir = updateDirection(linephi, *surf, roaddir2, isCurvedSegment);
310 
311  // extract RIO_OnTracks
312  std::vector<std::pair<double, std::unique_ptr<const Trk::MeasurementBase>> > rioDistVec; // vector to store the distance of a ROT to the segment
313 
314  // associate MDT hits to segment
315  std::set<Identifier> deltaVec;
316  std::set<Identifier> outoftimeVec;
317 
318  associateMDTsToSegment(gdir, segment, sInfo.geom, sInfo.globalTrans, sInfo.amdbTrans, deltaVec, outoftimeVec, rioDistVec, beta);
319  std::vector<std::pair<double, std::unique_ptr<const Trk::MeasurementBase>>> garbage_collector;
320 
322 
323  if (m_redo2DFit && !isCurvedSegment) {
324  // refit segment after recalibration
325  TrkDriftCircleMath::DCSLFitter defaultFitter;
327  bool goodFit = defaultFitter.fit(result, line, segment.dcs(), hitSelector.selectHitsOnTrack(segment.dcs()));
328  if (goodFit) {
329  if (std::abs(xAOD::P4Helpers::deltaPhi(segment.line().phi(), result.line().phi())) > 0.01 ||
330  std::abs(segment.line().x0() - result.line().x0()) > 0.01 ||
331  std::abs(segment.line().y0() - result.line().y0()) > 0.01) {
332  // update local position and global
333  linephi = result.line().phi();
334  lpos[1] = result.line().position().x();
335  lpos[2] = result.line().position().y();
336  gpos = sInfo.amdbTrans * lpos;
337 
338  // recreate surface
339  surfaceTransform = Amg::Transform3D(sInfo.amdbTrans.rotation());
340  surfaceTransform.pretranslate(gpos);
341  surf = std::make_unique<Trk::PlaneSurface>(surfaceTransform, surfDim, surfDim);
342 
343  // finally update global direction
344  gdir = updateDirection(linephi, *surf, roaddir2, isCurvedSegment);
345  }
346  }
347  }
348 
349  // create local segment direction
350  Trk::LocalDirection segLocDir;
351  surf->globalToLocalDirection(gdir, segLocDir);
352  if (segLocDir.angleYZ() == 0 && segLocDir.angleXZ() == 0) {
353  ATH_MSG_DEBUG("invalid local direction");
354  return nullptr;
355  }
356 
357  // sanity checks
358  const double diff_phi = xAOD::P4Helpers::deltaPhi(roaddir2.phi(), gdir.phi());
359  const double diff_prec = xAOD::P4Helpers::deltaPhi(linephi, segLocDir.angleYZ());
361  if (std::min(std::abs(diff_phi), std::abs( std::abs(diff_phi) - M_PI)) > 1.e-3 ||
362  std::min(std::abs(diff_prec), std::abs(std::abs(diff_prec) - M_PI)) > 1.e-3) {
363  ATH_MSG_WARNING(" ALARM updated angles wrong: diff phi " << diff_phi << " prec " << diff_prec << " phi rdir " << roaddir2.phi()
364  << " gdir " << gdir.phi() << " lphi " << linephi << " seg "
365  << segLocDir.angleYZ());
366  }
367 
368  // associate Clusters to segment, uses spVecs to get clusters
369  std::pair<std::pair<int, int>, bool> netaPhiHits =
370  associateClustersToSegment(segment, chid, sInfo.globalTrans, sInfo.clusters, sInfo.phimin, sInfo.phimax, rioDistVec);
371 
372  if (rioDistVec.empty()){
373  ATH_MSG_VERBOSE("No measurements were collected.");
374  return nullptr;
375 
376  }
378  auto meas_for_fit = [&rioDistVec] () {
379  std::vector<const Trk::MeasurementBase*> out{};
380  out.reserve(rioDistVec.size());
381  std::sort(rioDistVec.begin(), rioDistVec.end(), SortByDistanceToSegment());
382  for (const std::pair<double, std::unique_ptr<const Trk::MeasurementBase>>& ele : rioDistVec) out.push_back(ele.second.get());
383  return out;
384  };
385 
386 
387  double dlocx{1000.}, dangleXZ{1000.}, qoverp{-99999.}, dqoverp{-99999.};
388  bool hasMeasuredCoordinate = false;
389  if (m_refitParameters && netaPhiHits.second) {
390  ATH_MSG_DEBUG(" distance between first and last phi hit sufficient to perform 4D fit: phi " << gdir.phi() << " theta "
391  << gdir.theta());
392 
393  std::unique_ptr<Trk::Track> track{m_segmentFitter->fit(gpos, gdir, *surf, meas_for_fit())};
394 
395  if (track) {
396  if (isCurvedSegment && track->perigeeParameters() && track->perigeeParameters()->covariance()) {
397  qoverp = track->perigeeParameters()->parameters()[Trk::qOverP];
398  dqoverp = Amg::error(*track->perigeeParameters()->covariance(), Trk::qOverP);
399  }
400  hasMeasuredCoordinate = true;
401  // hack to update the second coordinate errors
402  Amg::MatrixX updatedCov(5, 5);
403  updatedCov.setZero();
404  m_segmentFitter->updateSegmentParameters(*track, *surf, segLocPos, segLocDir, updatedCov);
405  if (Amg::error(updatedCov, Trk::locX) > 0 && Amg::error(updatedCov, Trk::phi) > 0.) {
406  dlocx = Amg::error(updatedCov, Trk::locX);
407  dangleXZ = Amg::error(updatedCov, Trk::phi); // hack (2): phi not always angleXZ
408  } else {
409  ATH_MSG_WARNING(" Corrupt error matrix returned from fitter " << Amg::toString(updatedCov));
410  }
411 
413  surf->localToGlobal(segLocPos, gdir, gpos);
414  surf->localToGlobalDirection(segLocDir, gdir);
415 
416  if (track->measurementsOnTrack() && rioDistVec.size() != track->measurementsOnTrack()->size()) {
417  if (track->measurementsOnTrack()->empty()) {
418  ATH_MSG_DEBUG("No measurements survived");
419  return nullptr;
420  }
421  ATH_MSG_DEBUG(" ROT vector size changed after fit, updating ");
422  garbage_collector = std::move(rioDistVec);
423  rioDistVec.reserve(track->measurementsOnTrack()->size());
424  const Trk::TrackParameters* firstPars = nullptr;
425  for (const Trk::TrackStateOnSurface* tsit : *track->trackStateOnSurfaces()) {
426  const Trk::TrackParameters* pars = tsit->trackParameters();
427  if (!pars) continue;
428  if (!firstPars) firstPars = pars;
429 
430  // check whether state is a measurement, skip outliers if they are not MDT
431  const Trk::MeasurementBase* meas = tsit->measurementOnTrack();
432  if (!meas) continue;
433  if (tsit->type(Trk::TrackStateOnSurface::Outlier) && !dynamic_cast<const MdtDriftCircleOnTrack*>(meas)) continue;
434  double dist = (pars->position() - firstPars->position()).dot(firstPars->momentum().unit());
435  rioDistVec.emplace_back(dist, meas->uniqueClone());
436  }
437  }
438  } else {
439  ATH_MSG_DEBUG(" refit of segment failed!! ");
440  netaPhiHits.second = false;
441  }
442  }
443 
444  // optional update of phi position and direction, only performed if the segment was not refitted and there are phi
445  // hits
446  if (m_updatePhiUsingPhiHits && !netaPhiHits.second) {
447  if (updateSegmentPhi(gpos, gdir, segLocPos, segLocDir, *surf, meas_for_fit(), sInfo.phimin, sInfo.phimax)) {
448  surf->localToGlobal(segLocPos, gpos, gpos);
449  surf->localToGlobalDirection(segLocDir, gdir);
450  hasMeasuredCoordinate = true;
451  dlocx = 100.;
452  dangleXZ = 0.1;
453  }
454  }
455 
456  if (msgLvl(MSG::DEBUG)) {
457  std::vector<const Trk::MeasurementBase*> debug_meas = meas_for_fit();
458  ATH_MSG_DEBUG(" number of hits " << debug_meas.size() << " of which trigger " << netaPhiHits.first.first << " eta and "
459  << netaPhiHits.first.second << " phi ");
460  for (const Trk::MeasurementBase* mit : debug_meas) {
461  const Trk::RIO_OnTrack* rot = dynamic_cast<const Trk::RIO_OnTrack*>(mit);
462  if (rot) {
463  ATH_MSG_DEBUG(m_idHelperSvc->toString(rot->identify()));
464  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(rot);
465  if (mdt)
466  ATH_MSG_DEBUG(std::setprecision(4)
467  << " radius " << std::setw(6) << mdt->driftRadius() << " time " << std::setw(6) << mdt->driftTime());
468  continue;
469  }
470  const CompetingMuonClustersOnTrack* crot = dynamic_cast<const CompetingMuonClustersOnTrack*>(mit);
471  if (crot) {
472  ATH_MSG_DEBUG(m_idHelperSvc->toString(crot->rioOnTrack(0).identify())
473  << " comp rot with hits " << crot->containedROTs().size());
474  continue;
475  }
476  ATH_MSG_WARNING("failed to dynamic_cast to ROT ");
477  }
478  }
479  // recalculate holes
480  std::vector<Identifier> holeVec = calculateHoles(ctx, chid, gpos, gdir, hasMeasuredCoordinate, deltaVec, outoftimeVec, rioDistVec);
481 
482  // currently not taking into account masked channels
483  if (!outoftimeVec.empty()) holeVec.insert(holeVec.end(), std::make_move_iterator(outoftimeVec.begin()),
484  std::make_move_iterator(outoftimeVec.end()));
485  MuonSegmentQuality* quality = new MuonSegmentQuality(segment.chi2(), segment.ndof(), holeVec);
486 
487  const TrkDriftCircleMath::DCSLFitter* dcslFitter = m_dcslFitProvider->getFitter();
489  if (dcslFitter && !segment.hasT0Shift() && m_outputFittedT0) {
490  if (!dcslFitter->fit(result, segment.line(), segment.dcs(), hitSelector.selectHitsOnTrack(segment.dcs()))) {
491  ATH_MSG_DEBUG(" T0 refit failed ");
492  } else {
493  ATH_MSG_DEBUG(" Fitted T0 " << result.t0Shift()<<" is valid "<<result.hasT0Shift());
494  }
495  }
496  bool hasFittedT0 = false;
497  double fittedT0{0}, errorFittedT0{1.};
498  if (m_outputFittedT0 && (segment.hasT0Shift() || (dcslFitter && result.hasT0Shift()))) {
499  hasFittedT0 = true;
500  if (segment.hasT0Shift()) {
501  fittedT0 = segment.t0Shift();
502  errorFittedT0 = segment.t0Error();
503  } else if (dcslFitter && result.hasT0Shift()) {
504  fittedT0 = result.t0Shift();
505  errorFittedT0 = result.t0Error();
506  } else {
507  ATH_MSG_WARNING(" Failed to access fitted t0 ");
508  hasFittedT0 = false;
509  }
510  }
511  // create new segment
512  std::unique_ptr<MuonSegment> msegment;
513  if (isCurvedSegment) { // curved segments
514  if (qoverp == -99999.) {
515  double charge = gpos.z() * std::tan(gdir.theta());
516  charge = charge / std::abs(charge);
517  // if the curved segment was not refit, then use a momentum estimate
518  constexpr double BILALPHA(28.4366), BMLALPHA(62.8267), BMSALPHA(53.1259), BOLALPHA(29.7554);
519  if (chIndex == ChIndex::BIL) {
520  qoverp = (charge * segment.deltaAlpha()) / BILALPHA;
521  dqoverp = M_SQRT2 * segment.dtheta() / BILALPHA;
522  } else if (chIndex == ChIndex::BML) {
523  qoverp = (charge * segment.deltaAlpha()) / BMLALPHA;
524  dqoverp = M_SQRT2 * segment.dtheta() / BMLALPHA;
525  } else if (chIndex == ChIndex::BMS) {
526  qoverp = (charge * segment.deltaAlpha()) / BMSALPHA;
527  dqoverp = M_SQRT2 * segment.dtheta() / BMSALPHA;
528  } else if (chIndex == ChIndex::BOL) {
529  qoverp = (charge * segment.deltaAlpha()) / BOLALPHA;
530  dqoverp = M_SQRT2 * segment.dtheta() / BOLALPHA;
531  }
532  }
533  Amg::MatrixX covMatrix(5, 5);
534  covMatrix.setIdentity();
535  covMatrix(0, 0) = dlocx * dlocx;
536  covMatrix(1, 1) = segment.dy0() * segment.dy0();
537  covMatrix(2, 2) = dangleXZ * dangleXZ;
538  covMatrix(3, 3) = segment.dtheta() * segment.dtheta();
539  covMatrix(4, 4) = dqoverp * dqoverp;
540 
541  std::vector<Trk::DefinedParameter> defPars;
542  defPars.emplace_back(segLocPos[Trk::loc1], Trk::loc1);
543  defPars.emplace_back(segLocPos[Trk::loc2], Trk::loc2);
544  defPars.emplace_back(gdir.phi(), Trk::phi);
545  defPars.emplace_back(gdir.theta(), Trk::theta);
546  defPars.emplace_back(qoverp, Trk::qOverP);
547  Trk::LocalParameters segLocPar(defPars);
548  msegment = std::make_unique<MuonSegment>(
549  std::move(segLocPar),
550  std::move(covMatrix),
551  surf.release(),
552  createROTVec(rioDistVec),
553  quality,
555  } else { // straight segments
556  // errors (for now no correlations)
557  Amg::MatrixX covMatrix(4, 4);
558  covMatrix.setIdentity();
559  covMatrix(0, 0) = dlocx * dlocx;
560  covMatrix(1, 1) = segment.dy0() * segment.dy0();
561  covMatrix(2, 2) = dangleXZ * dangleXZ;
562  covMatrix(3, 3) = segment.dtheta() * segment.dtheta();
563  msegment =
564  std::make_unique<MuonSegment>(segLocPos,
565  segLocDir,
566  std::move(covMatrix),
567  surf.release(),
568  createROTVec(rioDistVec),
569  quality,
571  }
572 
573  if (hasFittedT0) msegment->setT0Error(fittedT0, errorFittedT0);
574 
575  // check whether segment satisfies minimum quality criteria
576  int segmentQuality = m_segmentSelectionTool->quality(*msegment);
577 
578  if (msgLvl(MSG::DEBUG)) {
579  ATH_MSG_DEBUG(m_printer->print(*msegment) << " quality " << segmentQuality);
580  if (segmentQuality < 0) ATH_MSG_DEBUG(" BAD segment ");
581  if (hasFittedT0) ATH_MSG_DEBUG(" T0 " << fittedT0);
582  if (isCurvedSegment) ATH_MSG_DEBUG(" Curved " << fittedT0);
583  }
584  if (segmentQuality < 0) { return nullptr; }
585  return msegment;
586  }

◆ createSpacePoint()

DCMathSegmentMaker::Cluster2D Muon::DCMathSegmentMaker::createSpacePoint ( const Identifier gasGapId,
const MuonClusterOnTrack etaHit,
const MuonClusterOnTrack phiHit 
) const
private

Definition at line 844 of file DCMathSegmentMaker.cxx.

845  {
846  bool isEndcap = m_idHelperSvc->isEndcap(gasGapId);
847  double error{1.}, lpx{0.}, lpy{0.};
848  // case one hit missing. Take position and error of the available hit
849  if (!etaHit) {
850  if (!phiHit) {
851  ATH_MSG_WARNING("Both eta and phi hits missing");
852  error = 0;
853  } else {
854  lpx = phiHit->localParameters()[Trk::locX];
855  error = Amg::error(phiHit->localCovariance(), Trk::locX);
856  }
857  } else if (!phiHit) {
858  lpx = etaHit->localParameters()[Trk::locX];
859  error = Amg::error(etaHit->localCovariance(), Trk::locX);
860  } else if (etaHit && phiHit) {
861  if (isEndcap) {
862  return createTgcSpacePoint(gasGapId, etaHit, phiHit);
863  } else {
864  std::vector<const MuonClusterOnTrack*> phiVec{phiHit};
865  return createRpcSpacePoint(gasGapId, etaHit, phiVec);
866  }
867  }
868  Identifier detElId = m_idHelperSvc->detElId(gasGapId);
869  if (std::abs(error) < 0.001) {
870  ATH_MSG_WARNING(" Unphysical error assigned for gasgap " << m_idHelperSvc->toString(gasGapId));
871  error = 0.;
872  }
873  return Cluster2D(detElId, gasGapId, Amg::Vector2D(lpx, lpy), error, etaHit, phiHit);
874  }

◆ createSpacePoints() [1/2]

DCMathSegmentMaker::ClusterVecPair Muon::DCMathSegmentMaker::createSpacePoints ( const ChIdHitMap chIdHitMap) const
private

Definition at line 741 of file DCMathSegmentMaker.cxx.

741  {
742  // vector to store output
743  ClusterVec spacePoints{}, phiVec{};
744  spacePoints.reserve(20);
745  phiVec.reserve(20);
746  // loop over chambers
747  for ( const auto& [id, gasGapHits] : chIdHitMap) {
748  // create clusters per chamber and copy them in to result vector
749  ClusterVecPair cls = createSpacePoints(gasGapHits);
750  std::copy(std::make_move_iterator(cls.first.begin()),
751  std::make_move_iterator(cls.first.end()), std::back_inserter(spacePoints));
752  std::copy(std::make_move_iterator(cls.second.begin()),
753  std::make_move_iterator(cls.second.end()), std::back_inserter(phiVec));
754  }
755 
756  return std::make_pair(std::move(spacePoints), std::move(phiVec));
757  }

◆ createSpacePoints() [2/2]

DCMathSegmentMaker::ClusterVecPair Muon::DCMathSegmentMaker::createSpacePoints ( const IdHitMap gasGapHitMap) const
private

Definition at line 759 of file DCMathSegmentMaker.cxx.

759  {
760  ClusterVec spacePoints{}, phiVec{};
761  bool isEndcap = m_idHelperSvc->isEndcap((*(gasGapHitMap.begin())).first);
762 
763  ATH_MSG_VERBOSE(" creating Space points for " << gasGapHitMap.size() << " gas gaps ");
764 
765  for (const auto& [gasGapId, etaPhiHits] : gasGapHitMap) {
766  // flag whether phi hits are matched with a eta hit
767  std::vector<bool> flagPhihit(etaPhiHits.second.size(), 0);
768 
769  // store Identifier of previous hit to remove duplicates
770  Identifier prevEtaId;
771 
772  ATH_MSG_VERBOSE(" New gasgap " << m_idHelperSvc->toString(gasGapId) << " neta " << etaPhiHits.first.size() << " nphi "
773  << etaPhiHits.second.size());
774 
775  for (const MuonClusterOnTrack* etaHit : etaPhiHits.first) {
776  // check whether we are not dealing with a duplicate hit
777  if (etaHit->identify() == prevEtaId) continue;
778  prevEtaId = etaHit->identify();
779 
780  ATH_MSG_VERBOSE(" Eta hit " << m_idHelperSvc->toString(etaHit->identify()));
781 
782  if (isEndcap) {
783  // check whether match with phi hits was found
784  bool foundSP = false;
785  Identifier prevPhiId;
786  int phi_idx{-1};
787  for (const MuonClusterOnTrack* phiHit : etaPhiHits.second) {
788  // check for duplicate phi hits
789  ++phi_idx;
790  if (phiHit->identify() == prevPhiId) continue;
791  prevPhiId = phiHit->identify();
792 
793  ATH_MSG_VERBOSE(" Phi hit " << m_idHelperSvc->toString(phiHit->identify()));
794 
795  Cluster2D sp = createTgcSpacePoint(gasGapId, etaHit, phiHit);
796  if (sp.corrupt()) continue;
797  spacePoints.push_back(std::move(sp));
798  // mark as used
799  foundSP = true;
800  flagPhihit[phi_idx] = true;
801  }
802 
803  // add single eta hit if not matching phi hit was found
804  if (!foundSP) {
805  Cluster2D sp = createSpacePoint(gasGapId, etaHit, nullptr);
806  if (sp.corrupt()) continue;
807  spacePoints.push_back(std::move(sp));
808  }
809  } else {
810  Cluster2D sp = createRpcSpacePoint(gasGapId, etaHit, etaPhiHits.second);
811  if (sp.corrupt()) continue;
812  // flag all phi hits, not very elegant, but works
813  flagPhihit = std::vector<bool>(etaPhiHits.second.size(), 1);
814  spacePoints.push_back(std::move(sp));
815  }
816  }
817  if (isEndcap) {
818  // loop over flag vector and add unmatched phi hits to phiVec;
819  Identifier prevPhiId;
820  for (unsigned int i = 0; i < flagPhihit.size(); ++i) {
821  if (flagPhihit[i]) continue;
822 
823  // check for duplicate phi hits
824  if (etaPhiHits.second[i]->identify() == prevPhiId) continue;
825  prevPhiId = etaPhiHits.second[i]->identify();
826 
827  Cluster2D sp = createTgcSpacePoint(gasGapId, nullptr, etaPhiHits.second[i]);
828  if (sp.corrupt()) continue;
829  phiVec.push_back(std::move(sp));
830  }
831  } else if (etaPhiHits.first.empty() && !etaPhiHits.second.empty()) {
832  // if there were no eta hits create one phi spacePoint of all phi hits in gasgap
833  Cluster2D sp = createRpcSpacePoint(gasGapId, nullptr, etaPhiHits.second);
834  if (sp.corrupt()) continue;
835  phiVec.push_back(std::move(sp));
836  }
837  }
838 
839  ATH_MSG_VERBOSE(" Creating space points, number of gas-gaps " << gasGapHitMap.size() << " space points " << spacePoints.size());
840 
841  return std::make_pair(std::move(spacePoints), std::move(phiVec));
842  }

◆ createTgcSpacePoint()

DCMathSegmentMaker::Cluster2D Muon::DCMathSegmentMaker::createTgcSpacePoint ( const Identifier gasGapId,
const MuonClusterOnTrack etaHit,
const MuonClusterOnTrack phiHit 
) const
private

Definition at line 876 of file DCMathSegmentMaker.cxx.

878  {
879  double error{1.}, lpx{0.}, lpy{0.};
880  Identifier detElId = m_idHelperSvc->detElId(gasGapId);
881  // case one hit missing. Take position and error of the available hit
882  if (!etaHit) {
883  lpx = phiHit->localParameters()[Trk::locX];
884  error = Amg::error(phiHit->localCovariance(), Trk::locX);
885  } else if (!phiHit) {
886  lpx = etaHit->localParameters()[Trk::locX];
887  error = Amg::error(etaHit->localCovariance(), Trk::locX);
888  } else if (etaHit && phiHit) {
889  // get orientation angle of strip to rotate back from local frame to strip
890  // copy code from ROT creator
891  const MuonGM::TgcReadoutElement* detEl = dynamic_cast<const MuonGM::TgcReadoutElement*>(etaHit->detectorElement());
892  const Amg::Vector3D lSpacePoint = Amg::getRotateZ3D(-90 * Gaudi::Units::deg) * detEl->localSpacePoint(phiHit->identify(),
893  etaHit->globalPosition(),
894  phiHit->globalPosition());
895 
896 
897  lpx = lSpacePoint.x();
898  lpy = lSpacePoint.y();
899  error = Amg::error(etaHit->localCovariance(), Trk::locX);
900  if (error <= std::numeric_limits<double>::epsilon()) {
901  ATH_MSG_WARNING(" Unphysical error assigned for " << m_idHelperSvc->toString(etaHit->identify()));
902  if (etaHit->prepRawData())
903  ATH_MSG_WARNING(" PRD error " << Amg::error(etaHit->prepRawData()->localCovariance(), Trk::locX));
904  }
905  ATH_MSG_DEBUG(" TGC space point: error " << error << " stripWith " << error * M_SQRT2 << std::endl
906  << " " << m_idHelperSvc->toString(etaHit->identify()) << std::endl
907  << " " << m_idHelperSvc->toString(phiHit->identify()));
908  }
909  if (std::abs(error) < 0.001) {
910  ATH_MSG_WARNING(" Unphysical error assigned for gasgap " << m_idHelperSvc->toString(gasGapId));
911  error = 1.;
912  }
913  ATH_MSG_VERBOSE("New space point for "<<m_idHelperSvc->toStringGasGap(gasGapId)<<" at ("<<lpx<<","<<lpy<<")");
914  return Cluster2D(detElId, gasGapId, Amg::Vector2D(lpx, lpy), error, etaHit, phiHit);
915  }

◆ distanceToSegment()

double Muon::DCMathSegmentMaker::distanceToSegment ( const TrkDriftCircleMath::Segment segment,
const Amg::Vector3D hitPos,
const Amg::Transform3D gToStation 
)
staticprivate

Definition at line 1632 of file DCMathSegmentMaker.cxx.

1633  {
1634  const TrkDriftCircleMath::Line& line = segment.line();
1636  double cos_sinLine = cot(line.phi());
1637 
1638  // calculate local AMDB position
1639  Amg::Vector3D locPos = gToStation * hitPos;
1640 
1641  TrkDriftCircleMath::LocVec2D lpos(locPos.y(), locPos.z());
1642 
1643  // calculate distance of segment to measurement surface
1644  double delta_y = lpos.y() - line.position().y();
1645 
1646  // calculate position of hit in line frame
1647  TrkDriftCircleMath::LocVec2D lineSurfaceIntersect(delta_y * cos_sinLine + line.position().x(), lpos.y());
1648 
1649  // calculate position of hit in line frame
1650  TrkDriftCircleMath::LocVec2D pointOnHit = toLine.toLine(lineSurfaceIntersect);
1651 
1652  return pointOnHit.x();
1653  }

◆ errorScaleFactor()

double Muon::DCMathSegmentMaker::errorScaleFactor ( const Identifier id,
double  curvature,
bool  hasPhiMeasurements 
) const
private

calculate error scaling factor

Definition at line 643 of file DCMathSegmentMaker.cxx.

643  {
644  double scale = 1.;
645  if (!m_curvedErrorScaling) return scale;
646 
647  if (!errorScalingRegion(id)) return scale;
648 
649  double scaleMax = 5.;
650  if (m_curvedErrorScaling && curvature > 2) {
651  scale = std::min(scaleMax, 1. + curvature / 10000);
652  ATH_MSG_DEBUG(" rescaled errors " << scale << " curvature " << curvature);
653  }
654  scale *= 2;
655 
656  // rescale errors is no phi measurement was found
657  if (!hasPhiMeasurements) {
658  double phiScale = 1.;
659  // rescale errors
660  int stRegion = m_idHelperSvc->mdtIdHelper().stationRegion(id);
661  if (stRegion == 0)
662  phiScale = 2.; // inner
663  else if (stRegion == 1)
664  phiScale = 2.5; // extended
665  else if (stRegion == 2)
666  phiScale = 2.5; // middle
667  else
668  phiScale = 3.; // outer
669  scale = std::sqrt(scale*scale + phiScale*phiScale);
670  ATH_MSG_DEBUG(" rescaled error for missing phi road " << scale);
671  }
672 
673  return scale;
674  }

◆ errorScalingRegion()

bool Muon::DCMathSegmentMaker::errorScalingRegion ( const Identifier id) const
private

apply error scaling for low mometum tracks

Definition at line 676 of file DCMathSegmentMaker.cxx.

678  {
679  // simple division of MuonSpectrometer in regions using barrel/endcap seperation plus
680  // inner/middle/outer seperation
681 
682  bool isEndcap = m_idHelperSvc->isEndcap(id);
683 
684  if (isEndcap) {
685  std::string stName = m_idHelperSvc->mdtIdHelper().stationNameString(m_idHelperSvc->mdtIdHelper().stationName(id));
686  if (stName[1] == 'I') return true;
687 
688  } else {
689  return true;
690  }
691  return false;
692  }

◆ find() [1/5]

void Muon::DCMathSegmentMaker::find ( const Amg::Vector3D gpos,
const Amg::Vector3D gdir,
const std::vector< const MdtDriftCircleOnTrack * > &  mdts,
const std::vector< const MuonClusterOnTrack * > &  clusters,
bool  hasPhiMeasurements = false,
Trk::SegmentCollection segColl = nullptr,
double  momentum = 1e9,
double  sinAngleCut = 0,
double  beta = 1. 
) const

find segments starting from:

  • an estimate of the global position and direction of the particle in the chamber
  • a list of MdtDriftCircleOnTrack
  • a list of MuonClusterOnTrack
  • a boolean to indicate whether the external prediction should be used to set the \( \phi \)-direction of the segment
  • an estimate of the momentum of the particle

The global direction is used to perform a seeded search for segments.

Definition at line 84 of file DCMathSegmentMaker.cxx.

87  {
88  const EventContext& ctx = Gaudi::Hive::currentContext();
89  if (m_doTimeOutChecks && Athena::Timeout::instance().reached()) {
90  ATH_MSG_DEBUG("Timeout reached. Aborting sequence.");
91  return;
92  }
93 
94  ATH_MSG_DEBUG("In find, passed " << mdts.size() << " MDTs & "<<clusters.size()<<" clusters");
95 
96  if (mdts.size() < 3) return;
97 
98  const MdtDriftCircleOnTrack* firstRot = findFirstRotInChamberWithMostHits(mdts);
99 
100  if (!firstRot) { return; }
101 
102  const MuonGM::MdtReadoutElement* detEl = firstRot->detectorElement();
103 
104  if (!detEl) {
105  ATH_MSG_WARNING(" no MdtReadoutElement found, returning 0 ");
106  return;
107  }
108 
109  // identifier
110  Identifier chid = firstRot->identify();
111 
112  // endcap or barrel
113  bool isEndcap = m_idHelperSvc->mdtIdHelper().isEndcap(chid);
114 
115  // global to local transformation for chamber
116  Amg::Transform3D gToStation = detEl->GlobalToAmdbLRSTransform();
117 
118  // define axis of chamber in global coordinates
119  Amg::Transform3D amdbToGlobal = detEl->AmdbLRSToGlobalTransform();
120 
121  // transform nominal pointing chamber position into surface frame
122  Amg::Vector3D globalDirCh{detEl->center()};
123  Amg::Vector3D dirCh(gToStation.linear() * globalDirCh);
124  double chamber_angleYZ = std::atan2(dirCh.z(), dirCh.y());
125 
126  Amg::Vector3D roaddir2 = roaddir;
127  double dotprod = globalDirCh.perp() * std::sin(roaddir2.theta()) + globalDirCh.z() * std::cos(roaddir2.theta());
128  if (dotprod < 0) roaddir2 = -roaddir2;
129 
130  // transform the global direction into the surface frame
131  Amg::Vector3D d(gToStation.linear() * roaddir2);
132  // calculate the local road angles in the surface frame
133  double road_angleXZ = std::atan2(d.z(), d.x());
134  double road_angleYZ = std::atan2(d.z(), d.y());
135 
136  if (!hasPhiMeasurements) road_angleXZ = M_PI; // if no phi, take phi perpendicular to plane
137  ATH_MSG_VERBOSE("global road pos "<<Amg::toString(roadpos)<<", global road dir " << Amg::toString(roaddir2) << " XZ " << road_angleXZ << " YZ " << road_angleYZ << " isEndcap "
138  << isEndcap << " central phi " << detEl->center().phi() << " r " << detEl->center().perp()
139  << " z " << detEl->center().z());
140 
141  // rescale errors for low momentum
142  double errorScale = errorScaleFactor(chid, momentum, hasPhiMeasurements);
143 
144  /* ***** create cluster hits ******** */
145  ATH_MSG_DEBUG(" adding clusters " << clusters.size());
146  ClusterVecPair spVecs;
147  if (m_doSpacePoints)
148  spVecs = create2DClusters(clusters);
149  else
150  spVecs = create1DClusters(clusters);
151  TrkDriftCircleMath::CLVec cls = createClusterVec(chid, spVecs.first, gToStation);
152 
153  /* ***** create MDT hits ************ */
154  if (msgLvl(MSG::VERBOSE)) {
155  std::stringstream sstr{};
156  for (const MdtDriftCircleOnTrack* mdt : mdts)
157  sstr<<m_printer->print(*mdt)<<std::endl;
158  ATH_MSG_VERBOSE(" adding mdts " << mdts.size()<<std::endl<<sstr.str());
159  }
160 
161  // set to get Identifiers of chambers with hits
162  std::set<Identifier> chamberSet;
163  double phimin{-9999}, phimax{9999};
164  TrkDriftCircleMath::DCStatistics dcStatistics; // statistics on chamber occupancy
165  TrkDriftCircleMath::DCVec dcs = createDCVec(mdts, errorScale, chamberSet, phimin, phimax, dcStatistics, gToStation, amdbToGlobal);
166 
167  // create geometry
168  std::shared_ptr<const TrkDriftCircleMath::ChamberGeometry> multiGeo;
169  if (m_doGeometry) {
170  ATH_MSG_VERBOSE(" using chamber geometry with #chambers " << chamberSet.size());
171  // vector to store chamber geometries
172  std::vector<TrkDriftCircleMath::MdtChamberGeometry> geos{};
173 
174  // loop over chambers
175  geos.reserve(chamberSet.size());
176  for (const Identifier& id : chamberSet) {
177  ATH_MSG_VERBOSE("Chamber: "<<m_idHelperSvc->toStringChamber(id));
178  geos.push_back(createChamberGeometry(id, gToStation));
179  }
180  // create new geometry
181  multiGeo = std::make_unique<TrkDriftCircleMath::MdtMultiChamberGeometry>(geos);
182 
183 
184  }
185 
186  double angle = m_sinAngleCut;
187  if (sinAngleCut > 0) angle = sinAngleCut;
188  TrkDriftCircleMath::Road road(TrkDriftCircleMath::LocVec2D{0.,0.}, road_angleYZ, chamber_angleYZ, angle);
189 
190  // call segment finder
191  TrkDriftCircleMath::SegVec segs = m_segmentFinder->findSegments(dcs, cls, road, dcStatistics, multiGeo.get());
192 
193  if (msgLvl(MSG::VERBOSE)) {
194  std::stringstream sstr{};
195  unsigned int seg_n{0};
196  for (const TrkDriftCircleMath::Segment& seg: segs) {
197  constexpr double toDeg = 1./Gaudi::Units::degree;
198  sstr<<"Segment number "<<seg_n<<" is at ("<<seg.line().x0()<<","<<seg.line().y0()<<") pointing to "<<seg.line().phi()*toDeg<<" chi2: "<<
199  (seg.chi2()/seg.ndof())<<"("<<seg.ndof()<<")"<<std::endl;
200  sstr<<"Mdt measurements: "<<seg.dcs().size()<<std::endl;
201  for (const TrkDriftCircleMath::DCOnTrack & mdt_meas : seg.dcs()){
202  sstr<<" **** "<<m_printer->print(*mdt_meas.rot());
203  sstr<<" ("<<mdt_meas.state()<<")"<<std::endl;
204  }
205  sstr<<"Cluster measurements "<<seg.clusters().size()<<std::endl;
206  for (const TrkDriftCircleMath::Cluster& clus: seg.clusters()) {
207  sstr<<" ---- "<<m_printer->print(*clus.rot())<<std::endl;
208  }
209  sstr<<std::endl;
210  ++seg_n;
211  }
212  ATH_MSG_VERBOSE("Found " << segs.size() << " segments "<<std::endl<<sstr.str());
213  }
214 
215  // return
216  if (segs.empty()) { return; }
217 
218  // loop over segments
219  segmentCreationInfo sInfo(spVecs, multiGeo.get(), gToStation, amdbToGlobal, phimin, phimax);
220  for (TrkDriftCircleMath::Segment& seg : segs) {
221  std::unique_ptr<MuonSegment> segment = createSegment(ctx, seg, chid, roadpos, roaddir2, mdts, hasPhiMeasurements, sInfo, beta);
222  if (segment) segColl->push_back(segment.release());
223  }
224  ATH_MSG_DEBUG(" Done ");
225  }

◆ find() [2/5]

void Muon::DCMathSegmentMaker::find ( const std::vector< const MdtDriftCircleOnTrack * > &  mdts,
const std::vector< const MuonClusterOnTrack * > &  clusters,
Trk::SegmentCollection segColl = nullptr 
) const

find segments starting from:

Implementation of IMuonSegmentMaker interface routine

Will call:

std::vector<const MuonSegment*>* find( const Amg::Vector3D& gpos, const Amg::Vector3D& gdir, const std::vector<const MdtDriftCircleOnTrack*>& mdts, const std::vector<const MuonClusterOnTrack*>& clusters, bool hasPhiMeasurements, double momentum );

Definition at line 607 of file DCMathSegmentMaker.cxx.

608  {
609  if (mdts.empty()) return;
610 
611  const MdtDriftCircleOnTrack* mdt = mdts.front();
612  if (!mdt) return;
613 
614  bool hasPhiMeasurements = false;
615  Amg::Vector3D gpos = mdt->globalPosition();
616  Amg::Vector3D gdir = gpos.unit();
617  find(gpos, gdir, mdts, clusters, hasPhiMeasurements, segColl);
618  }

◆ find() [3/5]

void Muon::DCMathSegmentMaker::find ( const std::vector< const Trk::RIO_OnTrack * > &  rios,
Trk::SegmentCollection segColl = nullptr 
) const

find segments starting from a list of RIO_OnTrack objects, implementation of IMuonSegmentMaker interface routine.

Will call:

std::vector<const MuonSegment*>* find( const Amg::Vector3D& gpos, const Amg::Vector3D& gdir, const std::vector<const MdtDriftCircleOnTrack*>& mdts, const std::vector<const MuonClusterOnTrack*>& clusters, bool hasPhiMeasurements);

Definition at line 588 of file DCMathSegmentMaker.cxx.

588  {
589  std::vector<const MdtDriftCircleOnTrack*> mdts;
590  std::vector<const MuonClusterOnTrack*> clusters;
591 
592  for (const Trk::RIO_OnTrack* it : rios) {
593  Identifier id = it->identify();
594  if (m_idHelperSvc->isMdt(id)) {
595  const MdtDriftCircleOnTrack* mdt = dynamic_cast<const MdtDriftCircleOnTrack*>(it);
596  if (!mdt) { ATH_MSG_WARNING("failed dynamic_cast, not a MDT but hit has MDT id!!!"); }
597  mdts.push_back(mdt);
598  } else if (m_idHelperSvc->isTrigger(id)) {
599  const MuonClusterOnTrack* clus = dynamic_cast<const MuonClusterOnTrack*>(it);
600  if (!clus) { ATH_MSG_WARNING("failed dynamic_cast, not a cluster but hit has RPC/TGC id!!!"); }
601  clusters.push_back(clus);
602  }
603  }
604  find(mdts, clusters, segColl);
605  }

◆ find() [4/5]

void Muon::DCMathSegmentMaker::find ( const std::vector< const Trk::RIO_OnTrack * > &  rios1,
const std::vector< const Trk::RIO_OnTrack * > &  rios2 
) const

find segments starting from a list of RIO_OnTrack objects in multiple chambers, implementation of IMuonSegmentMaker interface routine Will call:

std::vector<const MuonSegment*>* find( const Amg::Vector3D& gpos, const Amg::Vector3D& gdir, const std::vector<const MdtDriftCircleOnTrack*>& mdts, const std::vector<const MuonClusterOnTrack*>& clusters, bool hasPhiMeasurements);

Definition at line 620 of file DCMathSegmentMaker.cxx.

621  {
622  std::vector<const Trk::RIO_OnTrack*> rios = rios1;
623  rios.insert(rios.end(), rios2.begin(), rios2.end());
624  find(rios);
625  }

◆ find() [5/5]

void Muon::DCMathSegmentMaker::find ( const Trk::TrackRoad road,
const std::vector< std::vector< const MdtDriftCircleOnTrack * > > &  mdts,
const std::vector< std::vector< const MuonClusterOnTrack * > > &  clusters,
Trk::SegmentCollection segColl,
bool  hasPhiMeasurements = false,
double  momentum = 1e9 
) const

find segments starting from:

Implementation of IMuonSegmentMaker interface routine

Will call:

std::vector<const MuonSegment*>* find( const Amg::Vector3D& gpos, const Amg::Vector3D& gdir, const std::vector<const MdtDriftCircleOnTrack*>& mdts, const std::vector<const MuonClusterOnTrack*>& clusters, bool hasPhiMeasurements, double momentum );

Definition at line 627 of file DCMathSegmentMaker.cxx.

629  {
630  // copy all mdt hits into one vector
631  std::vector<const MdtDriftCircleOnTrack*> all_mdts;
632  for (const std::vector<const MdtDriftCircleOnTrack*>& circle_vec : mdts) { std::copy(circle_vec.begin(), circle_vec.end(), std::back_inserter(all_mdts)); }
633 
634  // copy all clusters into one vector
635  std::vector<const MuonClusterOnTrack*> all_clus;
636  for ( const std::vector<const MuonClusterOnTrack*>& clus_vec : clusters) { std::copy(clus_vec.begin(), clus_vec.end(), std::back_inserter(all_clus)); }
637 
638  const Amg::Vector3D& gpos = road.globalPosition();
639  const Amg::Vector3D& gdir = road.globalDirection();
640  find(gpos, gdir, all_mdts, all_clus, hasPhiMeasurements, segColl, momentum, road.deltaEta());
641  }

◆ findFirstRotInChamberWithMostHits()

const MdtDriftCircleOnTrack * Muon::DCMathSegmentMaker::findFirstRotInChamberWithMostHits ( const std::vector< const MdtDriftCircleOnTrack * > &  mdts) const
private

Definition at line 1794 of file DCMathSegmentMaker.cxx.

1795  {
1796  int hitsInChamberWithMostHits = 0;
1797  std::map<Identifier, int> hitsPerChamber;
1798  int currentSector = -1;
1799  const MdtDriftCircleOnTrack* rotInChamberWithMostHits = nullptr;
1800 
1801  // loop over all MDTs and count number of MDTs per chamber
1802  for (const MdtDriftCircleOnTrack* rot : mdts) {
1803  if (!rot) {
1804  ATH_MSG_WARNING(" rot not a MdtDriftCircleOnTrack ");
1805  continue;
1806  }
1807  Identifier chId = m_idHelperSvc->chamberId(rot->identify());
1808  int sector = m_idHelperSvc->sector(chId);
1809  if (currentSector == -1) {
1810  currentSector = sector;
1811  } else if (sector != currentSector) {
1812  return nullptr;
1813  }
1814  int& hitsInCh = hitsPerChamber[chId];
1815  ++hitsInCh;
1816  if (hitsInCh > hitsInChamberWithMostHits) {
1817  hitsInChamberWithMostHits = hitsInCh;
1818  rotInChamberWithMostHits = rot;
1819  }
1820  }
1821  return rotInChamberWithMostHits;
1822  }

◆ findMdt()

const MdtPrepData * Muon::DCMathSegmentMaker::findMdt ( const EventContext &  ctx,
const Identifier id 
) const
private

Definition at line 1775 of file DCMathSegmentMaker.cxx.

1775  {
1776  IdentifierHash colHash;
1777  if (m_idHelperSvc->mdtIdHelper().get_module_hash(m_idHelperSvc->chamberId(id), colHash)){
1778  ATH_MSG_VERBOSE("Invalid Mdt identifier "<<m_idHelperSvc->toString(id));
1779  return nullptr;
1780  }
1782  if (!MdtCont.isValid()) {
1783  ATH_MSG_WARNING("Cannot retrieve MdtPrepDataContainer ");
1784  return nullptr;
1785  }
1786  const MdtPrepDataCollection* collptr = MdtCont->indexFindPtr(colHash);
1787  if (!collptr) return nullptr;
1788  for (const MdtPrepData* prd : *collptr) {
1789  if (prd->identify() == id) return prd;
1790  }
1791  return nullptr;
1792  }

◆ initialize()

StatusCode Muon::DCMathSegmentMaker::initialize ( )
virtual

Definition at line 63 of file DCMathSegmentMaker.cxx.

63  {
64  ATH_CHECK(m_mdtKey.initialize(m_removeDeltas && !m_mdtKey.empty()));
65  // retrieve MuonDetectorManager
67  ATH_CHECK(m_mdtCreator.retrieve());
68  ATH_CHECK(m_mdtCreatorT0.retrieve(DisableTool{m_mdtCreatorT0.empty()}));
69  ATH_CHECK(m_clusterCreator.retrieve());
70  ATH_CHECK(m_compClusterCreator.retrieve());
71  ATH_CHECK(m_idHelperSvc.retrieve());
72  ATH_CHECK(m_printer.retrieve());
73  ATH_CHECK(m_edmHelperSvc.retrieve());
74  ATH_CHECK(m_segmentFinder.retrieve());
76  ATH_CHECK(m_segmentFitter.retrieve(DisableTool{!m_refitParameters}));
77  ATH_CHECK(m_dcslFitProvider.retrieve(DisableTool{m_dcslFitProvider.empty()}));
78 
79  // initialise for data handles
81  return StatusCode::SUCCESS;
82  }

◆ localTubeEnds()

DCMathSegmentMaker::TubeEnds Muon::DCMathSegmentMaker::localTubeEnds ( const MdtDriftCircleOnTrack mdt,
const Amg::Transform3D gToSegment,
const Amg::Transform3D segmentToG 
) const
private

calculate positions of tube ends

Definition at line 2048 of file DCMathSegmentMaker.cxx.

2049  {
2050  TubeEnds tubeEnds;
2051  const Identifier& id = mdt.identify();
2052  Amg::Vector3D lpos = gToSegment * mdt.prepRawData()->globalPosition();
2053 
2054  // use readout and hv side as the surface frame is not that of the chamber
2055  Amg::Vector3D lropos = gToSegment * mdt.prepRawData()->detectorElement()->ROPos(id);
2056  Amg::Vector3D lhvpos = lpos + (lpos - lropos);
2057 
2058  // rescale to correctly take into account active tube length
2059  double tubeLen = (lropos - lhvpos).mag();
2060  double activeTubeLen =
2061  mdt.detectorElement()->getActiveTubeLength(m_idHelperSvc->mdtIdHelper().tubeLayer(id), m_idHelperSvc->mdtIdHelper().tube(id));
2062  double scaleFactor = activeTubeLen / tubeLen;
2063  lropos[0] = scaleFactor * lropos.x();
2064  lhvpos[0] = scaleFactor * lhvpos.x();
2065 
2066  tubeEnds.lxmin = std::min(lropos.x(), lhvpos.x());
2067  tubeEnds.lxmax = std::max(lropos.x(), lhvpos.x());
2068 
2069  Amg::Vector3D ropos = segmentToG * lropos;
2070  Amg::Vector3D hvpos = segmentToG * lhvpos;
2071  const double phiRO = ropos.phi();
2072  const double phiHV = hvpos.phi();
2073  tubeEnds.phimin = std::min(phiRO, phiHV);
2074  tubeEnds.phimax = std::max(phiRO, phiHV);
2075  return tubeEnds;
2076  }

◆ residualAndPullWithSegment()

std::pair< double, double > Muon::DCMathSegmentMaker::residualAndPullWithSegment ( const TrkDriftCircleMath::Segment segment,
const Cluster2D spacePoint,
const Amg::Transform3D gToStation 
)
staticprivate

Definition at line 1667 of file DCMathSegmentMaker.cxx.

1669  {
1670  const TrkDriftCircleMath::Line& line = segment.line();
1671  double cos_sinLine = cot(line.phi());
1672 
1673  // calculate sp postion in AMDB reference frame
1674  Amg::Vector3D locPos = gToStation * spacePoint.globalPos;
1675  TrkDriftCircleMath::LocVec2D lpos(locPos.y(), locPos.z());
1676 
1677  // calculate distance of segment to measurement surface
1678  double delta_y = lpos.y() - line.position().y();
1679 
1680  // calculate position of hit in line frame
1681  TrkDriftCircleMath::LocVec2D lineSurfaceIntersect(delta_y * cos_sinLine + line.position().x(), lpos.y());
1682 
1683  // calculate position of hit in line frame
1684  double residual = lpos.x() - lineSurfaceIntersect.x();
1685  double pull = residual / spacePoint.error;
1686  return std::make_pair(residual, pull);
1687  }

◆ updateDirection()

Amg::Vector3D Muon::DCMathSegmentMaker::updateDirection ( double  linephi,
const Trk::PlaneSurface surf,
const Amg::Vector3D roaddir,
bool  isCurvedSegment 
) const
private

update the global direction, keeping the phi of the input road direction but using the local angle YZ

Definition at line 2126 of file DCMathSegmentMaker.cxx.

2127  {
2128  // Local direction along precision measurement (0, dy, dz)
2129  Trk::LocalDirection segLocDirs(M_PI_2, linephi);
2130  Amg::Vector3D gdirs;
2131  surf.localToGlobalDirection(segLocDirs, gdirs);
2132  // Local direction in plane (1,0,0)
2133  Trk::LocalDirection segLocDiro(0., M_PI_2);
2134  Amg::Vector3D gdiro;
2135  surf.localToGlobalDirection(segLocDiro, gdiro);
2136 
2137  // recalculate the value of the local XZ angle for the give YZ angle of the segment such that the global phi
2138  // direction remains unchanged
2139  double dx = std::sin(gdirs.theta()) * std::cos(gdirs.phi());
2140  double dy = std::sin(gdirs.theta()) * std::sin(gdirs.phi());
2141  double dz = std::cos(gdirs.theta());
2142 
2143  // vector gdiro
2144 
2145  double dxo = std::sin(gdiro.theta()) * std::cos(gdiro.phi());
2146  double dyo = std::sin(gdiro.theta()) * std::sin(gdiro.phi());
2147  double dzo = std::cos(gdiro.theta());
2148 
2149  // solve system real direction = A * gdir + B * gdiro
2150  // phi global constraint: (1)*sin(phi road) - (2)*cos(phi road) = 0
2151  // ( A * dx + B * dxo ) sin (phi ) - (A * dy + B *dyo ) cos (phi) = 0
2152  // A ( dx sin - dy cos ) + B (dx0 sin -dy0 cos) = A * a0 + B * b0 = 0
2153  // psi = atan (-b0 , a0)
2154 
2155  double a0 = dx * std::sin(roaddir.phi()) - dy * std::cos(roaddir.phi());
2156  double b0 = dxo * std::sin(roaddir.phi()) - dyo * std::cos(roaddir.phi());
2157  if (b0 < 1e-8 && b0 > 0) b0 = 1e-8;
2158  if (b0 > -1e-8 && b0 < 0) b0 = -1e-8;
2159  double dxn = dx - a0 * dxo / b0;
2160  double dyn = dy - a0 * dyo / b0;
2161  double dzn = dz - a0 * dzo / b0;
2162  double norm = std::sqrt(dxn * dxn + dyn * dyn + dzn * dzn);
2163 
2164  // flip the sign if the direction NOT parallel to road
2165  if (m_assumePointingPhi) {
2166  if (dxn * roaddir.x() + dyn * roaddir.y() + dzn * roaddir.z() < 0.) { norm = -norm; }
2167  } else {
2168  if (dxn * roaddir.x() + dyn * roaddir.y() < 0.) { norm = -norm; }
2169  }
2170 
2171  if (isCurvedSegment) norm = norm / 2.;
2172 
2173  //
2174  // Follow segment fit direction
2175  //
2176  dxn = dxn / norm;
2177  dyn = dyn / norm;
2178  dzn = dzn / norm;
2179 
2180  return Amg::Vector3D(dxn, dyn, dzn);
2181  }

◆ updatePhiRanges()

void Muon::DCMathSegmentMaker::updatePhiRanges ( double  phiminNew,
double  phimaxNew,
double &  phiminRef,
double &  phimaxRef 
)
staticprivate

update phi ranges

Definition at line 2078 of file DCMathSegmentMaker.cxx.

2078  {
2079  // check whether we are at the boundary where phi changes sign
2080  if (phiminRef * phimaxRef < 0.) {
2081  if (phiminRef < -1.1) {
2082  if (phiminRef > phiminNew) phiminRef = phiminNew;
2083  if (phimaxRef < phimaxNew) phimaxRef = phimaxNew;
2084  } else {
2085  if (phiminRef < phiminNew) phiminRef = phiminNew;
2086  if (phimaxRef > phimaxNew) phimaxRef = phimaxNew;
2087  }
2088  } else {
2089  // if not life is 'easy'
2090  if (phiminRef < 0.) {
2091  if (phiminRef < phiminNew) phiminRef = phiminNew;
2092  if (phimaxRef > phimaxNew) phimaxRef = phimaxNew;
2093  } else {
2094  if (phiminRef > phiminNew) phiminRef = phiminNew;
2095  if (phimaxRef < phimaxNew) phimaxRef = phimaxNew;
2096  }
2097  }
2098  }

◆ updateSegmentPhi()

bool Muon::DCMathSegmentMaker::updateSegmentPhi ( const Amg::Vector3D gpos,
const Amg::Vector3D gdir,
Amg::Vector2D segLocPos,
Trk::LocalDirection segLocDir,
Trk::PlaneSurface surf,
const std::vector< const Trk::MeasurementBase * > &  rots,
double  phimin,
double  phimax 
) const
private

Definition at line 1848 of file DCMathSegmentMaker.cxx.

1851  {
1852  bool hasUpdated = false;
1853 
1854  const Amg::Transform3D& segmentToGlobal = surf.transform();
1855  Amg::Transform3D gToSegment = surf.transform().inverse();
1856  Amg::Vector3D ldir = gToSegment * gdir;
1857 
1858  // ensure that we can extrapolate
1859  if (ldir.z() < 0.0001) return false;
1860 
1861  double dXdZ = ldir.x() / ldir.z();
1862  Amg::Vector3D lsegPos = gToSegment * gpos;
1863  double xline = lsegPos.x();
1864  double zline = lsegPos.z();
1865  ATH_MSG_VERBOSE(" Associated hits " << rots.size() << " angleXZ " << 90. * segLocDir.angleXZ() / (M_PI_2) << " dXdZ " << dXdZ
1866  << " seg Pos (" << xline << " " << zline << ") " << segLocPos);
1867 
1868  std::vector<HitInXZ> hits;
1869  hits.reserve(rots.size());
1870 
1871  unsigned int nphiHits(0);
1872  const HitInXZ* firstPhiHit{nullptr}, *lastPhiHit{nullptr};
1873 
1874  for (const Trk::MeasurementBase* meas : rots) {
1875  Identifier id = m_edmHelperSvc->getIdentifier(*meas);
1876  if (!id.is_valid()) continue;
1878  double lxmin{0}, lxmax{0}, phimin{0}, phimax{0};
1879  bool isMdt = m_idHelperSvc->isMdt(id);
1880  bool measuresPhi = m_idHelperSvc->measuresPhi(id);
1881  if (isMdt) {
1882  lpos.setZero();
1883  const MdtDriftCircleOnTrack* mdt = static_cast<const MdtDriftCircleOnTrack*>(meas);
1884  TubeEnds tubeEnds = localTubeEnds(*mdt, gToSegment, segmentToGlobal);
1885 
1886  lxmin = tubeEnds.lxmin;
1887  lxmax = tubeEnds.lxmax;
1888  phimin = tubeEnds.phimin;
1889  phimax = tubeEnds.phimax;
1890  } else {
1891  lpos = gToSegment * meas->globalPosition();
1892  lxmin = lpos.x() - 5 * Amg::error(meas->localCovariance(), Trk::locX);
1893  lxmax = lpos.x() + 5 * Amg::error(meas->localCovariance(), Trk::locX);
1894 
1895  const CompetingMuonClustersOnTrack* crot = dynamic_cast<const CompetingMuonClustersOnTrack*>(meas);
1896  if (!measuresPhi) {
1897  if (crot) {
1898  const MuonGM::RpcReadoutElement* detEl =
1899  dynamic_cast<const MuonGM::RpcReadoutElement*>(crot->containedROTs().front()->prepRawData()->detectorElement());
1900  if (detEl) {
1901  // perform bound check
1902  double stripLength = detEl->StripLength(0);
1903  lxmin = lpos.x() - 0.5 * stripLength;
1904  lxmax = lpos.x() + 0.5 * stripLength;
1905  }
1906  }
1907  Amg::Vector3D locPosition = lpos;
1908  locPosition[0] = lxmin;
1909  Amg::Vector3D globalPos = segmentToGlobal * locPosition;
1910  double phi1 = globalPos.phi();
1911 
1912  locPosition[0] = lxmax;
1913  globalPos = segmentToGlobal * locPosition;
1914  double phi2 = globalPos.phi();
1915  phimin = std::min(phi1, phi2);
1916  phimax = std::max(phi1, phi2);
1917 
1918  } else {
1919  if (m_idHelperSvc->isTgc(id)) {
1920  // need some special tricks for TGC phi hits as their reference plane can be rotated
1921  // with respect to the MDT frame
1922 
1923  // get orientation angle of strip to rotate back from local frame to strip
1924  // copy code from ROT creator
1925  int stripNo = m_idHelperSvc->tgcIdHelper().channel(id);
1926  int gasGap = m_idHelperSvc->tgcIdHelper().gasGap(id);
1927  if (!crot) {
1928  ATH_MSG_WARNING("dynamic cast failed for CompetingMuonClustersOnTrack");
1929  continue;
1930  }
1931  auto detEl = dynamic_cast<const MuonGM::TgcReadoutElement*>(crot->containedROTs().front()->prepRawData()->detectorElement());
1932 
1933  // transform the two points inth
1934  const Amg::Vector3D segFrame_StripDir = gToSegment.linear()* detEl->stripDir(gasGap, stripNo);
1935  const Amg::Vector3D segFrame_stripPos = gToSegment * detEl->channelPos(id);
1936 
1937  lpos = segFrame_stripPos +
1938  Amg::intersect<3>(lsegPos, ldir, segFrame_stripPos, segFrame_StripDir).value_or(0) * segFrame_StripDir;
1939 
1940  ATH_MSG_VERBOSE(" In seg frame: phi pos " << Amg::toString(lsegPos)
1941  << " shifted pos " << Amg::toString(segFrame_StripDir)
1942  << " intersect with segment " << Amg::toString(lpos));
1943  }
1944  Amg::Vector3D globalPos = segmentToGlobal * lpos;
1945  phimin = globalPos.phi();
1946  phimax = phimin;
1947 
1948  // check whether phi is consistent with segment phi range
1949  bool phiOk = checkPhiConsistency(phimin, seg_phimin, seg_phimax);
1950  if (!phiOk) {
1951  ATH_MSG_DEBUG(" Inconsistent phi " << phimin << " range " << seg_phimin << " " << seg_phimax);
1952  }
1953  }
1954  }
1955 
1956  hits.emplace_back(id, isMdt, measuresPhi, lpos.x(), lpos.z(), lxmin, lxmax, phimin, phimax);
1957  if (measuresPhi) {
1958  ++nphiHits;
1959  if (!firstPhiHit)
1960  firstPhiHit = &hits.back();
1961  else {
1962  double distPhiHits = std::abs(firstPhiHit->z - hits.back().z);
1963  if (distPhiHits > 500.) {
1964  lastPhiHit = &hits.back();
1965  } else {
1966  // not count this phi hit
1967  --nphiHits;
1968  ATH_MSG_DEBUG(" close phi hits, distance " << distPhiHits);
1969  }
1970  }
1971  }
1972  if (msgLvl(MSG::VERBOSE)) {
1973  double locExX = xline + dXdZ * (lpos.z() - zline);
1974  ATH_MSG_VERBOSE(" " << std::setw(65) << m_idHelperSvc->toString(id) << " pos (" << std::setw(6) << (int)lpos.x() << ","
1975  << std::setw(6) << (int)lpos.z() << ") ex pos " << std::setw(6) << (int)locExX << " min "
1976  << std::setw(6) << (int)lxmin << " max " << std::setw(6) << (int)lxmax << " phimin " << std::setw(6)
1977  << phimin << " phimax " << std::setw(6) << phimax);
1978  if (lpos.x() < lxmin || lpos.x() > lxmax) ATH_MSG_VERBOSE(" outBounds");
1979  }
1980  }
1981 
1982  if (nphiHits == 1) {
1983  if (!firstPhiHit) {
1984  ATH_MSG_WARNING(" Pointer to first phi hit not set, this should not happen! ");
1985  } else {
1986  if (xline != firstPhiHit->x) {
1987  hasUpdated = true;
1988 
1989  // use phi position of the phi hit
1990  xline = firstPhiHit->x;
1991  zline = firstPhiHit->z;
1992 
1993  if (m_assumePointingPhi) {
1994  Amg::Vector3D ipLocPos = gToSegment.translation();
1995  ATH_MSG_VERBOSE(" IP position in local frame " << ipLocPos);
1996 
1997  double dz = ipLocPos.z() - zline;
1998  if (std::abs(dz) > 0.001) {
1999  ATH_MSG_VERBOSE(" hit (" << xline << "," << zline << ") IP (" << ipLocPos.x() << "," << ipLocPos.z()
2000  << ") dXdZ " << (ipLocPos.x() - xline) / dz << " old " << dXdZ);
2001  dXdZ = (ipLocPos.x() - xline) / dz;
2002  }
2003  }
2004  }
2005  }
2006  } else if (nphiHits == 2) {
2007  if (!firstPhiHit || !lastPhiHit) {
2008  ATH_MSG_WARNING(" Pointer to one of the two phi hit not set, this should not happen! ");
2009  } else {
2010  double dz = lastPhiHit->z - firstPhiHit->z;
2011  // use phi position of the first hit
2012  xline = firstPhiHit->x;
2013  zline = firstPhiHit->z;
2014  if (std::abs(dz) > 300.) {
2015  double dx = lastPhiHit->x - firstPhiHit->x;
2016  hasUpdated = true;
2017 
2018  // if the two hits are far enough apart, also use the direction of the line connecting the two hits.
2019  dXdZ = dx / dz;
2020  }
2021  }
2022  } else {
2023  // in all other cases just rotate until the MDTs are ok
2024  }
2025 
2026  if (hasUpdated) {
2027  // move segment to position of phi hit
2028  double segX = xline - dXdZ * zline;
2029 
2030  // finally check whether now everything is in bounds
2031  bool ok = checkBoundsInXZ(segX, 0., dXdZ, hits);
2032  if (!ok) {
2033  // give WARNING and give up for now
2034  ATH_MSG_DEBUG("still several out of bounds hits after rotation: posx(" << segX << ") dXdZ " << dXdZ
2035  << " keeping old result ");
2036  }
2037 
2038  // update segment parameters
2039  double alphaYZ = segLocDir.angleYZ();
2040  double alphaXZ = std::atan2(1, dXdZ);
2041 
2042  segLocPos[Trk::locX] = segX;
2043  segLocDir = Trk::LocalDirection(alphaXZ, alphaYZ);
2044  }
2045  return hasUpdated;
2046  }

Member Data Documentation

◆ m_addUnassociatedPhiHits

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_addUnassociatedPhiHits {this, "AddUnassociatedPhiHits", false}
private

Definition at line 409 of file DCMathSegmentMaker.h.

◆ m_allMdtHoles

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_allMdtHoles {this, "AllMdtHoles", false}
private

Definition at line 414 of file DCMathSegmentMaker.h.

◆ m_assumePointingPhi

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_assumePointingPhi {this, "AssumePointingPhi", false }
private

Definition at line 424 of file DCMathSegmentMaker.h.

◆ m_chamberGeoKey

SG::ReadCondHandleKey<Muon::MuonIntersectGeoData> Muon::DCMathSegmentMaker::m_chamberGeoKey {this, "ChamberGeoKey", "MuonStationIntersects", "Pointer to hole search service"}
private

Definition at line 430 of file DCMathSegmentMaker.h.

◆ m_clusterCreator

ToolHandle<IMuonClusterOnTrackCreator> Muon::DCMathSegmentMaker::m_clusterCreator
private
Initial value:
{
this,
"MuonClusterCreator",
"Muon::MuonClusterOnTrackCreator/MuonClusterOnTrackCreator",
}

Definition at line 366 of file DCMathSegmentMaker.h.

◆ m_compClusterCreator

ToolHandle<IMuonCompetingClustersOnTrackCreator> Muon::DCMathSegmentMaker::m_compClusterCreator
private
Initial value:
{
this,
"MuonCompetingClustersCreator",
"Muon::TriggerChamberClusterOnTrackCreator/TriggerChamberClusterOnTrackCreator",
}

Definition at line 371 of file DCMathSegmentMaker.h.

◆ m_createCompetingROTsEta

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_createCompetingROTsEta {this, "CreateCompetingROTsEta", true}
private

Definition at line 406 of file DCMathSegmentMaker.h.

◆ m_createCompetingROTsPhi

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_createCompetingROTsPhi {this, "CreateCompetingROTsPhi", true}
private

Definition at line 407 of file DCMathSegmentMaker.h.

◆ m_curvedErrorScaling

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_curvedErrorScaling {this, "CurvedErrorScaling", true}
private

Definition at line 404 of file DCMathSegmentMaker.h.

◆ m_dcslFitProvider

ToolHandle<IDCSLFitProvider> Muon::DCMathSegmentMaker::m_dcslFitProvider
private
Initial value:
{
this,
"DCFitProvider",
"",
}

Definition at line 396 of file DCMathSegmentMaker.h.

◆ m_DetectorManagerKey

SG::ReadCondHandleKey<MuonGM::MuonDetectorManager> Muon::DCMathSegmentMaker::m_DetectorManagerKey
private
Initial value:
{
this,
"DetectorManagerKey",
"MuonDetectorManager",
"Key of input MuonDetectorManager condition data",
}

pointers to IdHelpers

Definition at line 337 of file DCMathSegmentMaker.h.

◆ m_doGeometry

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_doGeometry {this, "DoGeometry", true}
private

Definition at line 403 of file DCMathSegmentMaker.h.

◆ m_doSpacePoints

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_doSpacePoints {this, "UseTriggerSpacePoints", true}
private

Definition at line 405 of file DCMathSegmentMaker.h.

◆ m_doTimeOutChecks

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_doTimeOutChecks {this, "UseTimeOutGard", false}
private

Definition at line 420 of file DCMathSegmentMaker.h.

◆ m_edmHelperSvc

ServiceHandle<IMuonEDMHelperSvc> Muon::DCMathSegmentMaker::m_edmHelperSvc
private
Initial value:
{
this,
"edmHelper",
"Muon::MuonEDMHelperSvc/MuonEDMHelperSvc",
"Handle to the service providing the IMuonEDMHelperSvc interface",
}

Definition at line 349 of file DCMathSegmentMaker.h.

◆ m_idHelperSvc

ServiceHandle<Muon::IMuonIdHelperSvc> Muon::DCMathSegmentMaker::m_idHelperSvc
private
Initial value:
{
this,
"MuonIdHelperSvc",
"Muon::MuonIdHelperSvc/MuonIdHelperSvc",
}

Definition at line 344 of file DCMathSegmentMaker.h.

◆ m_maxAssociateClusterDistance

Gaudi::Property<double> Muon::DCMathSegmentMaker::m_maxAssociateClusterDistance {this, "MaxAssociateClusterDistance", 3000.}
private

Definition at line 412 of file DCMathSegmentMaker.h.

◆ m_mdtCreator

ToolHandle<IMdtDriftCircleOnTrackCreator> Muon::DCMathSegmentMaker::m_mdtCreator
private
Initial value:
{
this,
"MdtCreator",
"Muon::MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator",
}

Definition at line 356 of file DCMathSegmentMaker.h.

◆ m_mdtCreatorT0

ToolHandle<IMdtDriftCircleOnTrackCreator> Muon::DCMathSegmentMaker::m_mdtCreatorT0
private
Initial value:
{
this,
"MdtCreatorT0",
"Muon::MdtDriftCircleOnTrackCreator/MdtDriftCircleOnTrackCreator",
}

Definition at line 361 of file DCMathSegmentMaker.h.

◆ m_mdtKey

SG::ReadHandleKey<Muon::MdtPrepDataContainer> Muon::DCMathSegmentMaker::m_mdtKey {this, "MdtPrepDataContainer", "MDT_DriftCircles"}
private

Definition at line 428 of file DCMathSegmentMaker.h.

◆ m_outputFittedT0

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_outputFittedT0 {this, "OutputFittedT0", false}
private

Definition at line 418 of file DCMathSegmentMaker.h.

◆ m_preciseErrorScale

Gaudi::Property<double> Muon::DCMathSegmentMaker::m_preciseErrorScale {this, "PreciseErrorScale", 2.}
private

Definition at line 419 of file DCMathSegmentMaker.h.

◆ m_printer

PublicToolHandle<MuonEDMPrinterTool> Muon::DCMathSegmentMaker::m_printer
private
Initial value:
{
this,
"EDMPrinter",
"Muon::MuonEDMPrinterTool/MuonEDMPrinterTool",
}

Definition at line 376 of file DCMathSegmentMaker.h.

◆ m_recoverBadRpcCabling

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_recoverBadRpcCabling {this, "RecoverBadRpcCabling", false}
private

Definition at line 422 of file DCMathSegmentMaker.h.

◆ m_redo2DFit

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_redo2DFit {this, "Redo2DFit", true}
private

Definition at line 425 of file DCMathSegmentMaker.h.

◆ m_refitParameters

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_refitParameters {this, "RefitSegment", false}
private

Definition at line 408 of file DCMathSegmentMaker.h.

◆ m_reject1DTgcSpacePoints

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_reject1DTgcSpacePoints {this,"Reject1DTgcSpacePoints", true }
private

Definition at line 416 of file DCMathSegmentMaker.h.

◆ m_removeDeltas

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_removeDeltas {this, "RemoveDeltasFromSegmentQuality", true}
private

Definition at line 415 of file DCMathSegmentMaker.h.

◆ m_segmentFinder

ToolHandle<IMdtSegmentFinder> Muon::DCMathSegmentMaker::m_segmentFinder
private
Initial value:
{
this,
"MdtSegmentFinder",
"Muon::MdtMathSegmentFinder/MdtMathSegmentFinder",
}

Definition at line 381 of file DCMathSegmentMaker.h.

◆ m_segmentFitter

ToolHandle<IMuonSegmentFittingTool> Muon::DCMathSegmentMaker::m_segmentFitter
private
Initial value:
{
this,
"SegmentFitter",
"Muon::MuonSegmentFittingTool/MuonSegmentFittingTool",
}

Definition at line 386 of file DCMathSegmentMaker.h.

◆ m_segmentSelectionTool

ToolHandle<IMuonSegmentSelectionTool> Muon::DCMathSegmentMaker::m_segmentSelectionTool
private
Initial value:
{
this,
"SegmentSelector",
"Muon::MuonSegmentSelectionTool/MuonSegmentSelectionTool",
}

Definition at line 391 of file DCMathSegmentMaker.h.

◆ m_sinAngleCut

Gaudi::Property<double> Muon::DCMathSegmentMaker::m_sinAngleCut {this, "SinAngleCut", 0.2}
private

Definition at line 402 of file DCMathSegmentMaker.h.

◆ m_strictRoadDirectionConsistencyCheck

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_strictRoadDirectionConsistencyCheck {this, "StrictRoadDirectionConsistencyCheck", true}
private

Definition at line 410 of file DCMathSegmentMaker.h.

◆ m_updatePhiUsingPhiHits

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_updatePhiUsingPhiHits {this, "UpdatePhiUsingPhiHits", false}
private

Definition at line 423 of file DCMathSegmentMaker.h.

◆ m_usePreciseError

Gaudi::Property<bool> Muon::DCMathSegmentMaker::m_usePreciseError {this, "UsePreciseError", false}
private

Definition at line 417 of file DCMathSegmentMaker.h.


The documentation for this class was generated from the following files:
Muon::DCMathSegmentMaker::m_reject1DTgcSpacePoints
Gaudi::Property< bool > m_reject1DTgcSpacePoints
Definition: DCMathSegmentMaker.h:416
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
make_hlt_rep.pars
pars
Definition: make_hlt_rep.py:90
Muon::DCMathSegmentMaker::residualAndPullWithSegment
static std::pair< double, double > residualAndPullWithSegment(const TrkDriftCircleMath::Segment &segment, const Cluster2D &spacePoint, const Amg::Transform3D &gToStation)
Definition: DCMathSegmentMaker.cxx:1667
beamspotman.r
def r
Definition: beamspotman.py:674
Trk::LocalParameters
Definition: LocalParameters.h:98
Muon::DCMathSegmentMaker::errorScaleFactor
double errorScaleFactor(const Identifier &id, double curvature, bool hasPhiMeasurements) const
calculate error scaling factor
Definition: DCMathSegmentMaker.cxx:643
Muon::DCMathSegmentMaker::m_addUnassociatedPhiHits
Gaudi::Property< bool > m_addUnassociatedPhiHits
Definition: DCMathSegmentMaker.h:409
Trk::PlaneSurface::localToGlobalDirection
void localToGlobalDirection(const Trk::LocalDirection &locdir, Amg::Vector3D &globdir) const
This method transforms a local direction wrt the plane to a global direction.
Definition: PlaneSurface.cxx:238
test_pyathena.eta
eta
Definition: test_pyathena.py:10
Trk::PrepRawDataType::MdtPrepData
@ MdtPrepData
Muon::DCMathSegmentMaker::m_createCompetingROTsEta
Gaudi::Property< bool > m_createCompetingROTsEta
Definition: DCMathSegmentMaker.h:406
xAOD::identify
const Identifier & identify(const UncalibratedMeasurement *meas)
Returns the associated identifier from the muon measurement.
Definition: MuonSpectrometer/MuonPhaseII/Event/xAOD/xAODMuonPrepData/Root/UtilFunctions.cxx:82
Muon::DCMathSegmentMaker::ClusterVec
std::vector< Cluster2D > ClusterVec
Definition: DCMathSegmentMaker.h:158
Trk::Segment::DCMathSegmentMaker
@ DCMathSegmentMaker
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:68
dumpTgcDigiDeadChambers.gasGap
list gasGap
Definition: dumpTgcDigiDeadChambers.py:33
PlotCalibFromCool.norm
norm
Definition: PlotCalibFromCool.py:100
Muon::DCMathSegmentMaker::associateClustersToSegment
std::pair< std::pair< int, int >, bool > associateClustersToSegment(const TrkDriftCircleMath::Segment &segment, const Identifier &chid, const Amg::Transform3D &gToStation, ClusterVecPair &spVecs, double phimin, double phimax, std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec) const
Definition: DCMathSegmentMaker.cxx:1284
MuonGM::MdtReadoutElement::getNLayers
int getNLayers() const
Returns the number of tube layers inside the multilayer.
MuonGM::MuonReadoutElement::AmdbLRSToGlobalTransform
virtual Amg::Transform3D AmdbLRSToGlobalTransform() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonReadoutElement.cxx:146
Muon::DCMathSegmentMaker::ClusterVecPair
std::pair< ClusterVec, ClusterVec > ClusterVecPair
Definition: DCMathSegmentMaker.h:159
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:27
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
get_generator_info.result
result
Definition: get_generator_info.py:21
TrkDriftCircleMath::DCOnTrackVec
std::vector< DCOnTrack > DCOnTrackVec
Definition: DCOnTrack.h:59
MuonGM::RpcReadoutElement::StripLength
double StripLength(bool measphi) const
returns the strip length for the phi or eta plane
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Trk::locX
@ locX
Definition: ParamDefs.h:37
find
std::string find(const std::string &s)
return a remapped string
Definition: hcg.cxx:135
TrkDriftCircleMath::MdtId
Definition: MdtId.h:14
TrkDriftCircleMath::DCOnTrack::Delta
@ Delta
used in fit
Definition: DCOnTrack.h:21
TrkDriftCircleMath::ClusterId
Definition: ClusterId.h:12
Trk::locY
@ locY
local cartesian
Definition: ParamDefs.h:38
MuonGM::MdtReadoutElement::center
virtual const Amg::Vector3D & center(const Identifier &) const override final
Return the center of the surface associated with this identifier In the case of silicon it returns th...
Muon::DCMathSegmentMaker::m_segmentSelectionTool
ToolHandle< IMuonSegmentSelectionTool > m_segmentSelectionTool
Definition: DCMathSegmentMaker.h:391
MuonGM::MdtReadoutElement::innerTubeRadius
double innerTubeRadius() const
Returns the inner tube radius excluding the aluminium walls.
perp
Scalar perp() const
perp method - perpenticular length
Definition: AmgMatrixBasePlugin.h:44
Muon::DCMathSegmentMaker::create1DClusters
ClusterVecPair create1DClusters(const std::vector< const MuonClusterOnTrack * > &clusters) const
Definition: DCMathSegmentMaker.cxx:694
ClusterSeg::residual
@ residual
Definition: ClusterNtuple.h:20
TrkDriftCircleMath::DCSLFitter::fit
virtual bool fit(Segment &result, const Line &line, const DCOnTrackVec &dcs, double t0Seed=-99999.) const
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:38
calibdata.chamber
chamber
Definition: calibdata.py:31
Trk::ParametersBase::position
const Amg::Vector3D & position() const
Access method for the position.
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
SG::ReadHandle
Definition: StoreGate/StoreGate/ReadHandle.h:67
index
Definition: index.py:1
Muon::DCMathSegmentMaker::find
void find(const std::vector< const Trk::RIO_OnTrack * > &rios, Trk::SegmentCollection *segColl=nullptr) const
find segments starting from a list of RIO_OnTrack objects, implementation of IMuonSegmentMaker interf...
Definition: DCMathSegmentMaker.cxx:588
hist_file_dump.d
d
Definition: hist_file_dump.py:142
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
TrkDriftCircleMath::CLVec
std::vector< Cluster > CLVec
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/Cluster.h:70
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
Muon::MuonStationIndex::ChIndex::BIL
@ BIL
Muon::DCMathSegmentMaker::m_removeDeltas
Gaudi::Property< bool > m_removeDeltas
Definition: DCMathSegmentMaker.h:415
Muon::MuonStationIndex::stName
const std::string & stName(StIndex index)
convert StIndex into a string
Definition: MuonStationIndex.cxx:104
MuonGM::MuonReadoutElement::GlobalToAmdbLRSTransform
virtual Amg::Transform3D GlobalToAmdbLRSTransform() const
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonReadoutElement.cxx:154
Muon::DCMathSegmentMaker::createDCVec
TrkDriftCircleMath::DCVec createDCVec(const std::vector< const MdtDriftCircleOnTrack * > &mdts, double errorScale, std::set< Identifier > &chamberSet, double &phimin, double &phimax, TrkDriftCircleMath::DCStatistics &dcStatistics, const Amg::Transform3D &gToStation, const Amg::Transform3D &amdbToGlobal) const
Definition: DCMathSegmentMaker.cxx:1020
Muon::DCMathSegmentMaker::m_printer
PublicToolHandle< MuonEDMPrinterTool > m_printer
Definition: DCMathSegmentMaker.h:376
skel.it
it
Definition: skel.GENtoEVGEN.py:407
Muon::MdtPrepDataCollection
MuonPrepDataCollection< MdtPrepData > MdtPrepDataCollection
Definition: MuonPrepDataCollection.h:106
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:70
TrkDriftCircleMath::DCSLFitter
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/DCSLFitter.h:17
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Muon::DCMathSegmentMaker::m_segmentFinder
ToolHandle< IMdtSegmentFinder > m_segmentFinder
Definition: DCMathSegmentMaker.h:381
CaloClusterListBadChannel.cls
cls
Definition: CaloClusterListBadChannel.py:8
deg
#define deg
Definition: SbPolyhedron.cxx:17
Muon::DCMathSegmentMaker::ChIdHitMap
std::map< Identifier, IdHitMap > ChIdHitMap
Definition: DCMathSegmentMaker.h:102
xAOD::P4Helpers::deltaPhi
double deltaPhi(double phiA, double phiB)
delta Phi in range [-pi,pi[
Definition: xAODP4Helpers.h:69
MuonGM::RpcReadoutElement
An RpcReadoutElement corresponds to a single RPC module; therefore typicaly a barrel muon station con...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/RpcReadoutElement.h:55
Trk::loc2
@ loc2
generic first and second local coordinate
Definition: ParamDefs.h:35
GasGapData
Definition: RPCDQUtils.h:98
Trk::RIO_OnTrack
Definition: RIO_OnTrack.h:70
TrkDriftCircleMath::LocVec2D::x
double x() const
Returns the x coordinate of the vector.
Definition: LocVec2D.h:27
python.TurnDataReader.dr
dr
Definition: TurnDataReader.py:111
TrkDriftCircleMath::DCOnTrack::OutOfTime
@ OutOfTime
delta electron
Definition: DCOnTrack.h:22
Muon::DCMathSegmentMaker::updateSegmentPhi
bool updateSegmentPhi(const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, Amg::Vector2D &segLocPos, Trk::LocalDirection &segLocDir, Trk::PlaneSurface &surf, const std::vector< const Trk::MeasurementBase * > &rots, double phimin, double phimax) const
Definition: DCMathSegmentMaker.cxx:1848
Trk::locR
@ locR
Definition: ParamDefs.h:44
TrkDriftCircleMath::DriftCircle
This class represents a drift time measurement.
Definition: DriftCircle.h:22
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon::DCMathSegmentMaker::createSegment
std::unique_ptr< MuonSegment > createSegment(const EventContext &ctx, TrkDriftCircleMath::Segment &segment, const Identifier &chid, const Amg::Vector3D &roadpos, const Amg::Vector3D &roaddir2, const std::vector< const MdtDriftCircleOnTrack * > &mdts, bool hasPhiMeasurements, segmentCreationInfo &sInfo, double beta=1.) const
Definition: DCMathSegmentMaker.cxx:227
Trk::Surface::center
const Amg::Vector3D & center() const
Returns the center position of the Surface.
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
yodamerge_tmp.scale
scale
Definition: yodamerge_tmp.py:138
Muon::DCMathSegmentMaker::updatePhiRanges
static void updatePhiRanges(double phiminNew, double phimaxNew, double &phiminRef, double &phimaxRef)
update phi ranges
Definition: DCMathSegmentMaker.cxx:2078
x
#define x
Muon::DCMathSegmentMaker::m_DetectorManagerKey
SG::ReadCondHandleKey< MuonGM::MuonDetectorManager > m_DetectorManagerKey
pointers to IdHelpers
Definition: DCMathSegmentMaker.h:337
dq_defect_bulk_create_defects.line
line
Definition: dq_defect_bulk_create_defects.py:27
TrkDriftCircleMath::TransformToLine
Definition: TransformToLine.h:15
Muon::DCMathSegmentMaker::createSpacePoints
ClusterVecPair createSpacePoints(const ChIdHitMap &chIdHitMap) const
Definition: DCMathSegmentMaker.cxx:741
Muon::DCMathSegmentMaker::checkBoundsInXZ
bool checkBoundsInXZ(double xline, double zline, double dXdZ, const std::vector< HitInXZ > &hits) const
check whether all hits are in bounds in the XZ plane
Definition: DCMathSegmentMaker.cxx:1824
TrkDriftCircleMath::Segment
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/Segment.h:18
TrkDriftCircleMath::LocVec2D
Implementation of 2 dimensional vector class.
Definition: LocVec2D.h:16
TrkDriftCircleMath::DCVec
std::vector< DriftCircle > DCVec
Definition: DriftCircle.h:117
Muon::DCMathSegmentMaker::m_curvedErrorScaling
Gaudi::Property< bool > m_curvedErrorScaling
Definition: DCMathSegmentMaker.h:404
Amg::getRotateZ3D
Amg::Transform3D getRotateZ3D(double angle)
get a rotation transformation around Z-axis
Definition: GeoPrimitivesHelpers.h:270
Trk::LocalDirection::angleYZ
double angleYZ() const
access method for angle of local YZ projection
Definition: LocalDirection.h:106
Muon::DCMathSegmentMaker::m_mdtCreator
ToolHandle< IMdtDriftCircleOnTrackCreator > m_mdtCreator
Definition: DCMathSegmentMaker.h:356
Trk::TrackStateOnSurface::Outlier
@ Outlier
This TSoS contains an outlier, that is, it contains a MeasurementBase/RIO_OnTrack which was not used ...
Definition: TrackStateOnSurface.h:122
TRT::Hit::side
@ side
Definition: HitInfo.h:83
xAOD::phi
setEt phi
Definition: TrigEMCluster_v1.cxx:29
Trk::StraightLineSurface::globalToLocal
virtual bool globalToLocal(const Amg::Vector3D &glob, const Amg::Vector3D &mom, Amg::Vector2D &loc) const override final
Specified for StraightLineSurface: GlobalToLocal method without dynamic memory allocation This method...
Definition: StraightLineSurface.cxx:164
TrkDriftCircleMath::Line
Definition: Line.h:17
python.setupRTTAlg.size
int size
Definition: setupRTTAlg.py:39
TrkDriftCircleMath::Road
TrkDriftCircleMath::Road - encodes the road given to the segment finder in station coordinates.
Definition: Road.h:15
Trk::TrackRoad::globalDirection
const Amg::Vector3D & globalDirection() const
Get the global direction of the road.
Definition: TrackRoad.h:143
Muon::DCMathSegmentMaker::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: DCMathSegmentMaker.h:344
Muon::DCMathSegmentMaker::m_compClusterCreator
ToolHandle< IMuonCompetingClustersOnTrackCreator > m_compClusterCreator
Definition: DCMathSegmentMaker.h:371
Muon::DCMathSegmentMaker::createROTVec
static DataVector< const Trk::MeasurementBase > createROTVec(std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec)
Definition: DCMathSegmentMaker.cxx:1655
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Muon::DCMathSegmentMaker::createClusterVec
TrkDriftCircleMath::CLVec createClusterVec(const Identifier &chid, ClusterVec &spVec, const Amg::Transform3D &gToStation) const
Definition: DCMathSegmentMaker.cxx:978
Muon::DCMathSegmentMaker::m_usePreciseError
Gaudi::Property< bool > m_usePreciseError
Definition: DCMathSegmentMaker.h:417
MuonGM::MuonDetectorManager::getMdtReadoutElement
const MdtReadoutElement * getMdtReadoutElement(const Identifier &id) const
access via extended identifier (requires unpacking)
Definition: MuonDetDescr/MuonReadoutGeometry/src/MuonDetectorManager.cxx:206
ParticleGun_EoverP_Config.momentum
momentum
Definition: ParticleGun_EoverP_Config.py:63
MuonGM::MdtReadoutElement
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MdtReadoutElement.h:51
lumiFormat.i
int i
Definition: lumiFormat.py:85
SG::OWN_ELEMENTS
@ OWN_ELEMENTS
this data object owns its elements
Definition: OwnershipPolicy.h:17
z
#define z
Muon::DCMathSegmentMaker::errorScalingRegion
bool errorScalingRegion(const Identifier &id) const
apply error scaling for low mometum tracks
Definition: DCMathSegmentMaker.cxx:676
Trk::TrackRoad::globalPosition
const Amg::Vector3D & globalPosition() const
Get the global position of the road.
Definition: TrackRoad.h:137
TrkDriftCircleMath::DCSLHitSelector
Definition: DCSLHitSelector.h:13
Muon::MuonStationIndex::chIndex
ChIndex chIndex(const std::string &index)
convert ChIndex name string to enum
Definition: MuonStationIndex.cxx:11
Muon::DCMathSegmentMaker::m_segmentFitter
ToolHandle< IMuonSegmentFittingTool > m_segmentFitter
Definition: DCMathSegmentMaker.h:386
Trk::theta
@ theta
Definition: ParamDefs.h:66
Trk::MeasurementBase::uniqueClone
std::unique_ptr< MeasurementBase > uniqueClone() const
NVI Clone giving up unique pointer.
Definition: MeasurementBase.h:77
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
TrkDriftCircleMath::ChamberGeometry::nlay
virtual unsigned int nlay() const =0
angle
double angle(const GeoTrf::Vector2D &a, const GeoTrf::Vector2D &b)
Definition: TRTDetectorFactory_Full.cxx:68
xAOD::covMatrix
covMatrix
Definition: TrackMeasurement_v1.cxx:19
TRT::Hit::layer
@ layer
Definition: HitInfo.h:79
Trk::driftRadius
@ driftRadius
trt, straws
Definition: ParamDefs.h:53
TrkDriftCircleMath::MdtChamberGeometry
Definition: MdtChamberGeometry.h:18
Muon::DCMathSegmentMaker::m_edmHelperSvc
ServiceHandle< IMuonEDMHelperSvc > m_edmHelperSvc
Definition: DCMathSegmentMaker.h:349
Amg::Transform3D
Eigen::Affine3d Transform3D
Definition: GeoPrimitives.h:46
Trk::RIGHT
@ RIGHT
the drift radius is positive (see Trk::AtaStraightLine)
Definition: DriftCircleSide.h:22
Amg::transform
Amg::Vector3D transform(Amg::Vector3D &v, Amg::Transform3D &tr)
Transform a point from a Trasformation3D.
Definition: GeoPrimitivesHelpers.h:156
Muon::DCMathSegmentMaker::m_chamberGeoKey
SG::ReadCondHandleKey< Muon::MuonIntersectGeoData > m_chamberGeoKey
Definition: DCMathSegmentMaker.h:430
MuonGM::TgcReadoutElement
A TgcReadoutElement corresponds to a single TGC chamber; therefore typically a TGC station contains s...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/TgcReadoutElement.h:42
Muon::MuonStationIndex::ChIndex::BML
@ BML
TrkDriftCircleMath::LocVec2D::y
double y() const
Returns the y coordinate of the vector.
Definition: LocVec2D.h:29
python.StandardJetMods.pull
pull
Definition: StandardJetMods.py:305
Muon::DCMathSegmentMaker::createSpacePoint
Cluster2D createSpacePoint(const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const MuonClusterOnTrack *phiHit) const
Definition: DCMathSegmentMaker.cxx:844
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
MuonGM::TgcReadoutElement::localSpacePoint
Amg::Vector3D localSpacePoint(const Identifier &stripId, const Amg::Vector3D &etaHitPos, const Amg::Vector3D &phiHitPos) const
Definition: MuonDetDescr/MuonReadoutGeometry/src/TgcReadoutElement.cxx:321
MuonGM::MdtReadoutElement::nMDTinStation
unsigned int nMDTinStation() const
How many MDT chambers are in the station.
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MdtReadoutElement.h:62
Muon::DCMathSegmentMaker::m_refitParameters
Gaudi::Property< bool > m_refitParameters
Definition: DCMathSegmentMaker.h:408
Trk::PlaneSurface::globalToLocalDirection
void globalToLocalDirection(const Amg::Vector3D &glodir, Trk::LocalDirection &locdir) const
This method transforms the global direction to a local direction wrt the plane.
Definition: PlaneSurface.cxx:256
Muon::DCMathSegmentMaker::m_allMdtHoles
Gaudi::Property< bool > m_allMdtHoles
Definition: DCMathSegmentMaker.h:414
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
Trk::ParametersBase
Definition: ParametersBase.h:55
Muon::DCMathSegmentMaker::m_createCompetingROTsPhi
Gaudi::Property< bool > m_createCompetingROTsPhi
Definition: DCMathSegmentMaker.h:407
Muon::DCMathSegmentMaker::m_recoverBadRpcCabling
Gaudi::Property< bool > m_recoverBadRpcCabling
Definition: DCMathSegmentMaker.h:422
Athena::Timeout::instance
static Timeout & instance()
Get reference to Timeout singleton.
Definition: Timeout.h:64
a0
double a0
Definition: globals.cxx:27
F600IntegrationConfig.spacePoints
spacePoints
Definition: F600IntegrationConfig.py:122
TrkDriftCircleMath::TransformToLine::toLocal
LocVec2D toLocal(const LocVec2D &pos) const
Definition: TransformToLine.h:26
DataVector< const Trk::MeasurementBase >
Trk::LocalDirection
represents the three-dimensional global direction with respect to a planar surface frame.
Definition: LocalDirection.h:81
WriteCalibToCool.swap
swap
Definition: WriteCalibToCool.py:94
TrkDriftCircleMath::DCOnTrack::OnTrack
@ OnTrack
Definition: DCOnTrack.h:20
dot.dot
def dot(G, fn, nodesToHighlight=[])
Definition: dot.py:5
Trk::Segment::DCMathSegmentMakerCurved
@ DCMathSegmentMakerCurved
Definition: Tracking/TrkEvent/TrkSegment/TrkSegment/Segment.h:75
Muon::DCMathSegmentMaker::localTubeEnds
TubeEnds localTubeEnds(const MdtDriftCircleOnTrack &mdt, const Amg::Transform3D &gToSegment, const Amg::Transform3D &segmentToG) const
calculate positions of tube ends
Definition: DCMathSegmentMaker.cxx:2048
Trk::MeasurementBase
Definition: MeasurementBase.h:58
Muon::MuonStationIndex::ChIndex::BMS
@ BMS
TrkDriftCircleMath::TransformToLine::toLine
LocVec2D toLine(const LocVec2D &pos) const
Definition: TransformToLine.h:20
Trk::TrackStateOnSurface
represents the track state (measurement, material, fit parameters and quality) at a surface.
Definition: TrackStateOnSurface.h:71
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:240
Muon::DCMathSegmentMaker::calculateHoles
std::vector< Identifier > calculateHoles(const EventContext &ctx, Identifier chid, const Amg::Vector3D &gpos, const Amg::Vector3D &gdir, bool hasMeasuredCoordinate, std::set< Identifier > &deltaVec, std::set< Identifier > &outoftimeVec, const std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec) const
Definition: DCMathSegmentMaker.cxx:1689
Muon::DCMathSegmentMaker::m_mdtKey
SG::ReadHandleKey< Muon::MdtPrepDataContainer > m_mdtKey
Definition: DCMathSegmentMaker.h:428
TrkDriftCircleMath::Cluster
class representing a cluster meaurement
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/Cluster.h:22
Muon::DCMathSegmentMaker::create2DClusters
ClusterVecPair create2DClusters(const std::vector< const MuonClusterOnTrack * > &clusters) const
Definition: DCMathSegmentMaker.cxx:720
Amg::error
double error(const Amg::MatrixX &mat, int index)
return diagonal error of the matrix caller should ensure the matrix is symmetric and the index is in ...
Definition: EventPrimitivesHelpers.h:40
charge
double charge(const T &p)
Definition: AtlasPID.h:986
Muon::DCMathSegmentMaker::findFirstRotInChamberWithMostHits
const MdtDriftCircleOnTrack * findFirstRotInChamberWithMostHits(const std::vector< const MdtDriftCircleOnTrack * > &mdts) const
Definition: DCMathSegmentMaker.cxx:1794
DataVector::push_back
value_type push_back(value_type pElem)
Add an element to the end of the collection.
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
TrkDriftCircleMath::ResidualWithSegment
class to calculate residual of a hit with a segment and calculate the local track errors
Definition: ResidualWithSegment.h:20
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
Muon::MuonStationIndex::PhiIndex
PhiIndex
enum to classify the different phi layers in the muon spectrometer
Definition: MuonStationIndex.h:31
TrkDriftCircleMath::ChamberGeometry::tubePosition
virtual LocVec2D tubePosition(unsigned int ml, unsigned int lay, unsigned int tube) const =0
Muon::DCMathSegmentMaker::m_dcslFitProvider
ToolHandle< IDCSLFitProvider > m_dcslFitProvider
Definition: DCMathSegmentMaker.h:396
Muon::DCMathSegmentMaker::m_doSpacePoints
Gaudi::Property< bool > m_doSpacePoints
Definition: DCMathSegmentMaker.h:405
Trk::DriftCircleSide
DriftCircleSide
Enumerates the 'side' of the wire on which the tracks passed (i.e.
Definition: DriftCircleSide.h:16
eflowRec::phiIndex
unsigned int phiIndex(float phi, float binsize)
calculate phi index for a given phi
Definition: EtaPhiLUT.cxx:23
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
Muon::DCMathSegmentMaker::createTgcSpacePoint
Cluster2D createTgcSpacePoint(const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const MuonClusterOnTrack *phiHit) const
Definition: DCMathSegmentMaker.cxx:876
Trk::ParametersBase::momentum
const Amg::Vector3D & momentum() const
Access method for the momentum.
DeMoScan.index
string index
Definition: DeMoScan.py:362
Muon::DCMathSegmentMaker::m_doTimeOutChecks
Gaudi::Property< bool > m_doTimeOutChecks
Definition: DCMathSegmentMaker.h:420
Muon::DCMathSegmentMaker::m_maxAssociateClusterDistance
Gaudi::Property< double > m_maxAssociateClusterDistance
Definition: DCMathSegmentMaker.h:412
y
#define y
Muon::DCMathSegmentMaker::m_sinAngleCut
Gaudi::Property< double > m_sinAngleCut
Definition: DCMathSegmentMaker.h:402
Muon::DCMathSegmentMaker::m_redo2DFit
Gaudi::Property< bool > m_redo2DFit
Definition: DCMathSegmentMaker.h:425
Muon::DCMathSegmentMaker::m_doGeometry
Gaudi::Property< bool > m_doGeometry
Definition: DCMathSegmentMaker.h:403
Amg::intersect
std::optional< double > intersect(const AmgVector(N)&posA, const AmgVector(N)&dirA, const AmgVector(N)&posB, const AmgVector(N)&dirB)
Calculates the point B' along the line B that's closest to a second line A.
Definition: GeoPrimitivesHelpers.h:347
MuonGM::MuonDetectorManager
The MuonDetectorManager stores the transient representation of the Muon Spectrometer geometry and pro...
Definition: MuonDetDescr/MuonReadoutGeometry/MuonReadoutGeometry/MuonDetectorManager.h:51
std::sort
void sort(typename std::reverse_iterator< DataModel_detail::iterator< DVL > > beg, typename std::reverse_iterator< DataModel_detail::iterator< DVL > > end, const Compare &comp)
Specialization of sort for DataVector/List.
Definition: DVL_algorithms.h:623
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
TrkDriftCircleMath::DCSLHitSelector::selectHitsOnTrack
const HitSelection selectHitsOnTrack(const DCOnTrackVec &dcs) const
Definition: DCSLHitSelector.h:20
Muon::DCMathSegmentMaker::findMdt
const MdtPrepData * findMdt(const EventContext &ctx, const Identifier &id) const
Definition: DCMathSegmentMaker.cxx:1775
Muon::DCMathSegmentMaker::m_assumePointingPhi
Gaudi::Property< bool > m_assumePointingPhi
Definition: DCMathSegmentMaker.h:424
Trk::RIO_OnTrack::identify
Identifier identify() const
return the identifier -extends MeasurementBase
Definition: RIO_OnTrack.h:152
DEBUG
#define DEBUG
Definition: page_access.h:11
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
python.TrackLeptonConfig.quality
quality
Definition: TrackLeptonConfig.py:16
Trk::qOverP
@ qOverP
perigee
Definition: ParamDefs.h:67
Muon::DCMathSegmentMaker::associateMDTsToSegment
void associateMDTsToSegment(const Amg::Vector3D &gdir, TrkDriftCircleMath::Segment &segment, const TrkDriftCircleMath::ChamberGeometry *multiGeo, const Amg::Transform3D &gToStation, const Amg::Transform3D &amdbToGlobal, std::set< Identifier > &deltaVec, std::set< Identifier > &outoftimeVec, std::vector< std::pair< double, std::unique_ptr< const Trk::MeasurementBase >> > &rioDistVec, double beta=1.) const
Definition: DCMathSegmentMaker.cxx:1149
RunTileMonitoring.clusters
clusters
Definition: RunTileMonitoring.py:133
MuonGM::MdtReadoutElement::surface
virtual const Trk::Surface & surface() const override final
Return surface associated with this detector element.
Definition: MuonDetDescr/MuonReadoutGeometry/src/MdtReadoutElement.cxx:885
convertTimingResiduals.offset
offset
Definition: convertTimingResiduals.py:71
Muon::DCMathSegmentMaker::m_updatePhiUsingPhiHits
Gaudi::Property< bool > m_updatePhiUsingPhiHits
Definition: DCMathSegmentMaker.h:423
TrkDriftCircleMath::DCOnTrack
class representing a drift circle meaurement on segment
Definition: DCOnTrack.h:16
TrkDriftCircleMath::SegVec
std::vector< Segment > SegVec
Definition: Tracking/TrkUtilityPackages/TrkDriftCircleMath/TrkDriftCircleMath/Segment.h:122
Muon::DCMathSegmentMaker::m_clusterCreator
ToolHandle< IMuonClusterOnTrackCreator > m_clusterCreator
Definition: DCMathSegmentMaker.h:366
Muon::DCMathSegmentMaker::distanceToSegment
static double distanceToSegment(const TrkDriftCircleMath::Segment &segment, const Amg::Vector3D &hitPos, const Amg::Transform3D &gToStation)
Definition: DCMathSegmentMaker.cxx:1632
Muon::DCMathSegmentMaker::createRpcSpacePoint
Cluster2D createRpcSpacePoint(const Identifier &gasGapId, const MuonClusterOnTrack *etaHit, const std::vector< const MuonClusterOnTrack * > &phiHits) const
Definition: DCMathSegmentMaker.cxx:917
Muon::DCMathSegmentMaker::updateDirection
Amg::Vector3D updateDirection(double linephi, const Trk::PlaneSurface &surf, const Amg::Vector3D &roaddir, bool isCurvedSegment) const
update the global direction, keeping the phi of the input road direction but using the local angle YZ
Definition: DCMathSegmentMaker.cxx:2126
Trk::LEFT
@ LEFT
the drift radius is negative (see Trk::AtaStraightLine)
Definition: DriftCircleSide.h:20
Trk::phi
@ phi
Definition: ParamDefs.h:75
Muon::MuonStationIndex::ChIndex
ChIndex
enum to classify the different chamber layers in the muon spectrometer
Definition: MuonStationIndex.h:15
xAOD::track
@ track
Definition: TrackingPrimitives.h:513
calibdata.copy
bool copy
Definition: calibdata.py:26
Muon::DCMathSegmentMaker::m_outputFittedT0
Gaudi::Property< bool > m_outputFittedT0
Definition: DCMathSegmentMaker.h:418
python.Constants.VERBOSE
int VERBOSE
Definition: Control/AthenaCommon/python/Constants.py:13
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::LocalDirection::angleXZ
double angleXZ() const
access method for angle of local XZ projection
Definition: LocalDirection.h:103
IdentifierHash
This is a "hash" representation of an Identifier. This encodes a 32 bit index which can be used to lo...
Definition: IdentifierHash.h:25
Trk::PlaneSurface::localToGlobal
virtual void localToGlobal(const Amg::Vector2D &locp, const Amg::Vector3D &mom, Amg::Vector3D &glob) const override final
Specified for PlaneSurface: LocalToGlobal method without dynamic memory allocation.
Definition: PlaneSurface.cxx:198
MuonParameters::beta
@ beta
Definition: MuonParamDefs.h:144
MuonGM::MdtReadoutElement::getNtubesperlayer
int getNtubesperlayer() const
Returns the number of tubes in each tube layer.
Trk::loc1
@ loc1
Definition: ParamDefs.h:34
Muon::DCMathSegmentMaker::m_mdtCreatorT0
ToolHandle< IMdtDriftCircleOnTrackCreator > m_mdtCreatorT0
Definition: DCMathSegmentMaker.h:361
error
Definition: IImpactPoint3dEstimator.h:70
Trk::Surface::transform
const Amg::Transform3D & transform() const
Returns HepGeom::Transform3D by reference.
dq_make_web_display.cl
cl
print [x.__class__ for x in toList(dqregion.getSubRegions()) ]
Definition: dq_make_web_display.py:25
mag
Scalar mag() const
mag method
Definition: AmgMatrixBasePlugin.h:26
calibdata.tube
tube
Definition: calibdata.py:30
python.SystemOfUnits.degree
tuple degree
Definition: SystemOfUnits.py:121
Trk::driftCircle
@ driftCircle
Definition: MeasurementType.h:25
Muon::DCMathSegmentMaker::createChamberGeometry
TrkDriftCircleMath::MdtChamberGeometry createChamberGeometry(const Identifier &chid, const Amg::Transform3D &gToStation) const
Definition: DCMathSegmentMaker.cxx:1073
Muon::DCMathSegmentMaker::checkPhiConsistency
bool checkPhiConsistency(double phi, double phimin, double phimax) const
check whether phi is consistent with segment phi
Definition: DCMathSegmentMaker.cxx:2100
Muon::DCMathSegmentMaker::m_preciseErrorScale
Gaudi::Property< double > m_preciseErrorScale
Definition: DCMathSegmentMaker.h:419
Trk::StraightLineSurface
Definition: StraightLineSurface.h:51
Muon::MuonClusterOnTrack
Base class for Muon cluster RIO_OnTracks.
Definition: MuonClusterOnTrack.h:34
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
NSWL1::PadTriggerAdapter::segment
Muon::NSW_PadTriggerSegment segment(const NSWL1::PadTrigger &data)
Definition: PadTriggerAdapter.cxx:5
TrkDriftCircleMath::DriftCircle::InTime
@ InTime
drift time too small to be compatible with drift spectrum
Definition: DriftCircle.h:27
Trk::TrackRoad::deltaEta
double deltaEta() const
Get the width of the road in the eta direction.
Definition: TrackRoad.h:149
TrkDriftCircleMath::DCStatistics
This class offers no functionality, but to define a standard device for the maker to transfer to the ...
Definition: DCStatistics.h:19
Muon::MuonStationIndex::ChIndex::BOL
@ BOL
Identifier
Definition: IdentifierFieldParser.cxx:14