ATLAS Offline Software
SimpleMMClusterBuilderTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
8 
9 #define DEFINE_VECTOR(dType, varName, nEles) \
10  std::vector<dType> varName{}; \
11  varName.reserve(nEles);
12 
13 namespace Muon{
14 
16 SimpleMMClusterBuilderTool::SimpleMMClusterBuilderTool(const std::string& t, const std::string& n, const IInterface* p) :
17  AthAlgTool(t, n, p) {
18  declareInterface<IMMClusterBuilderTool>(this);
19 }
20 
22  ATH_CHECK(m_idHelperSvc.retrieve());
24  return StatusCode::SUCCESS;
25 }
26 
28  std::vector<MMPrepData>&& MMprds,
29  std::vector<std::unique_ptr<MMPrepData>>& clustersVect) const {
30  ATH_MSG_DEBUG("Size of the input vector: " << MMprds.size());
31  ATH_MSG_DEBUG("Size of the output vector: " << clustersVect.size());
32 
33  if (MMprds.empty()) {
34  ATH_MSG_DEBUG("Empty PRD collection: no clusterization");
35  return StatusCode::SUCCESS;
36  }
37  const MmIdHelper& idHelper{m_idHelperSvc->mmIdHelper()};
38  std::sort(MMprds.begin(), MMprds.end(),
39  [&](const MMPrepData& a, const MMPrepData& b){
40  const Identifier ida = a.identify(), idb = b.identify();
41  const int mla = idHelper.multilayer(ida);
42  const int mlb = idHelper.multilayer(idb);
43  if (mla!=mlb) return mla<mlb;
44  const int gga = idHelper.gasGap(ida);
45  const int ggb = idHelper.gasGap(idb);
46  if (gga!=ggb) return gga<ggb;
47  return idHelper.channel(ida) < idHelper.channel(idb);
48  });
49 
50 
51  const IdentifierHash hash = MMprds.at(0).collectionHash();
52  const unsigned int n_input_prds = MMprds.size();
53  for (unsigned int mergeI = 0; mergeI < n_input_prds; ) {
54  const MMPrepData& primary_prd = MMprds[mergeI];
55  const Identifier id_prd = primary_prd.identify();
56  const Identifier gasGapId = m_idHelperSvc->gasGapId(id_prd);
57 
58  ATH_MSG_VERBOSE(" PrepData "<<m_idHelperSvc->toString(id_prd)<<" index: "<<mergeI<< " / " << n_input_prds
59  << " z " << primary_prd.globalPosition().z());
61  unsigned mergeJ{mergeI+1};
62 
63  while (mergeJ < n_input_prds &&
64  gasGapId == m_idHelperSvc->gasGapId(MMprds[mergeJ].identify()) &&
65  std::abs(idHelper.channel(MMprds[mergeJ].identify()) -
66  idHelper.channel(MMprds[mergeJ -1].identify()) ) <= static_cast<int>(m_maxHoleSize) + 1) {
67  ++mergeJ;
68  }
69  unsigned int clustSize = mergeJ - mergeI;
70  if (clustSize > m_maxClusSize) {
71  mergeI = mergeJ;
72  continue;
73  }
74  DEFINE_VECTOR(uint16_t, mergeStrips, clustSize);
75  DEFINE_VECTOR(Identifier, rdoList, clustSize);
76  DEFINE_VECTOR(short int, mergeStripsTime, clustSize);
77  DEFINE_VECTOR(int, mergeStripsCharge, clustSize);
78  DEFINE_VECTOR(float, mergeStripsDriftDists, clustSize);
79  DEFINE_VECTOR(AmgVector(2), mergeStripsDriftDistErrors, clustSize);
80  double totalCharge{0.0};
82  for (unsigned int mergeMe = mergeI; mergeMe < mergeJ; ++mergeMe) {
83  const MMPrepData& mergePrd = MMprds[mergeMe];
84  const Identifier mergedId = mergePrd.identify();
85  rdoList.push_back(mergedId);
86  mergeStrips.push_back(idHelper.channel(mergedId));
87  mergeStripsTime.push_back(mergePrd.time());
88  mergeStripsCharge.push_back(mergePrd.charge());
89  mergeStripsDriftDists.push_back(mergePrd.driftDist());
90  const Amg::MatrixX& cov{mergePrd.localCovariance()};
91  mergeStripsDriftDistErrors.emplace_back(cov(0,0), cov(1,1));
92 
93  totalCharge += mergePrd.charge();
94  }
95 
96  ATH_MSG_VERBOSE(" add merged MMprds nmerge " << clustSize );
97 
98 
99 
100  // start off from strip in the middle
101  unsigned int stripSum = 0;
102  for (unsigned short strip : mergeStrips) stripSum += strip;
103  stripSum /= mergeStrips.size();
104 
105  unsigned int centralIdx{mergeI};
106  for (unsigned int k = 0; k < mergeStrips.size(); ++k) {
107  ++centralIdx;
108  if (mergeStrips[k] == stripSum) break;
109  }
110  const Identifier clusterId = MMprds[centralIdx < mergeJ ? centralIdx : mergeI].identify();
111  ATH_MSG_VERBOSE(" Look for strip nr " << stripSum << " found at index " << centralIdx);
112 
116 
117  DEFINE_VECTOR(MMPrepData, stripsVec, clustSize);
118 
119  stripsVec.insert(stripsVec.begin(),std::make_move_iterator(MMprds.begin() + mergeI),
120  std::make_move_iterator(MMprds.begin() + mergeJ));
121 
123  mergeI = mergeJ;
124  Amg::MatrixX covMatrix(1,1);
125  Amg::Vector2D clusterLocalPosition{Amg::Vector2D::Zero()};
126  ATH_CHECK(getClusterPosition(ctx, clusterId, stripsVec, clusterLocalPosition, covMatrix));
127 
131  if (!m_writeStripProperties) mergeStrips.clear();
132  std::unique_ptr<MMPrepData> prdN = std::make_unique<MMPrepData>(clusterId,
133  hash,
134  std::move(clusterLocalPosition),
135  std::move(rdoList),
136  std::move(covMatrix),
137  stripsVec.front().detectorElement(),
138  0,
139  totalCharge,
140  0.f,
141  std::move(mergeStrips),
142  std::move(mergeStripsTime),
143  std::move(mergeStripsCharge));
144 
145  prdN->setDriftDist(std::move(mergeStripsDriftDists), std::move(mergeStripsDriftDistErrors));
147  clustersVect.push_back(std::move(prdN));
148  } // end loop MMprds[i]
149  return StatusCode::SUCCESS;
150 }
151 
154  const Identifier& clustId,
155  std::vector<MMPrepData>& stripsVec,
156  Amg::Vector2D& clusterLocalPosition,
157  Amg::MatrixX& covMatrix) const {
158 
160  if (!errorCalibDB.isValid()) {
161  ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
162  return StatusCode::FAILURE;
163  }
164  covMatrix.setIdentity();
165  double weightedPosX{0.}, posY{0.}, totalCharge{0.};
167 
169  posY = stripsVec[0].localPosition().y();
170  for (const MMPrepData& strip : stripsVec) {
171  const double posX = strip.localPosition().x();
172  const double charge = strip.charge();
173  weightedPosX += posX * charge;
174  totalCharge += charge;
175  const Amg::Vector3D lDir{NswClustering::toLocal(strip)};
176  clusDir+= charge * lDir;
177  const Amg::Vector3D& globPos{strip.globalPosition()};
178  ATH_MSG_VERBOSE("Adding a strip to the centroid calculation "<<m_idHelperSvc->toString(strip.identify())
179  <<", charge=" << charge<<" global position: "<<Amg::toString(globPos, 2)
180  <<", theta: "<<globPos.theta()<<", eta: "<<globPos.eta()<<", phi: "<<globPos.phi()
181  <<" -- local direction theta: "<<lDir.theta()<<", eta: "<<lDir.eta()
182  <<", phi: "<<lDir.phi());
183  }
184  weightedPosX = weightedPosX / totalCharge;
185  clusterLocalPosition = Amg::Vector2D(weightedPosX, posY);
186 
187  NswErrorCalibData::Input errorCalibIn{};
188  errorCalibIn.stripId = clustId;
189  errorCalibIn.clusterAuthor = static_cast<unsigned>(MMPrepData::Author::SimpleClusterBuilder);
190  errorCalibIn.locPhi = clusDir.phi();
191  errorCalibIn.locTheta = clusDir.theta();
192  errorCalibIn.localPos = clusterLocalPosition;
193  errorCalibIn.clusterSize = stripsVec.size();
194 
195  ATH_MSG_VERBOSE(m_idHelperSvc->toString(clustId)<< " - local track direction: "<<errorCalibIn.locTheta);
196 
197  const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
198  covMatrix(0, 0) = localUncertainty * localUncertainty;
199  return StatusCode::SUCCESS;
200 }
201 
203  const std::vector<NSWCalib::CalibratedStrip>& calibratedStrips,
204  const Amg::Vector3D& dirEstimate,
205  Amg::Vector2D& clusterLocalPosition,
206  Amg::MatrixX& covMatrix) const {
208  double xPosCalib{0.}, totalCharge{0.};
209  for (const NSWCalib::CalibratedStrip& it : calibratedStrips) {
210  xPosCalib += it.charge * it.dx;
211  totalCharge += it.charge;
212  }
213  if (std::abs(totalCharge) < std::numeric_limits<float>::epsilon()) {
214  return RIO_Author::unKnownAuthor;
215  }
216 
217  xPosCalib /= totalCharge;
218 
219  ATH_MSG_DEBUG("position before calibration and correction: " << clusterLocalPosition[Trk::locX] << " " << xPosCalib);
220 
221  clusterLocalPosition[Trk::locX] = clusterLocalPosition[Trk::locX] + xPosCalib;
223  if (!errorCalibDB.isValid()) {
224  ATH_MSG_FATAL("Failed to retrieve the parameterized errors "<<m_uncertCalibKey.fullKey());
225  return RIO_Author::unKnownAuthor;
226  }
227 
228  NswErrorCalibData::Input errorCalibIn{};
229  errorCalibIn.clusterSize = calibratedStrips.size();
230  errorCalibIn.clusterAuthor = RIO_Author::SimpleClusterBuilder;
231  errorCalibIn.locPhi = dirEstimate.phi();
232  errorCalibIn.locTheta = dirEstimate.theta();
233  errorCalibIn.localPos = clusterLocalPosition;
234  errorCalibIn.stripId = calibratedStrips[errorCalibIn.clusterSize/2].identifier;
235 
236  const double localUncertainty = errorCalibDB->clusterUncertainty(errorCalibIn);
237 
238  covMatrix(0, 0) = localUncertainty * localUncertainty;
239 
240 
241  return RIO_Author::SimpleClusterBuilder;
242 }
243 }
244 #undef DEFINE_VECTOR
Muon::SimpleMMClusterBuilderTool::initialize
StatusCode initialize() override
Definition: SimpleMMClusterBuilderTool.cxx:21
Muon::MMPrepData::driftDist
float driftDist() const
Returns the Drift Distance.
Definition: MMPrepData.h:232
ATH_MSG_FATAL
#define ATH_MSG_FATAL(x)
Definition: AthMsgStreamMacros.h:34
Muon::MMPrepData
Class to represent MM measurements.
Definition: MMPrepData.h:22
Amg::MatrixX
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic > MatrixX
Dynamic Matrix - dynamic allocation.
Definition: EventPrimitives.h:29
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
Muon::MMPrepData::globalPosition
virtual const Amg::Vector3D & globalPosition() const override final
Returns the global position.
Definition: MMPrepData.h:211
DEFINE_VECTOR
#define DEFINE_VECTOR(dType, varName, nEles)
Definition: SimpleMMClusterBuilderTool.cxx:9
SG::ReadCondHandle
Definition: ReadCondHandle.h:44
Trk::locX
@ locX
Definition: ParamDefs.h:43
Amg::Vector2D
Eigen::Matrix< double, 2, 1 > Vector2D
Definition: GeoPrimitives.h:48
Muon::SimpleMMClusterBuilderTool::m_uncertCalibKey
SG::ReadCondHandleKey< NswErrorCalibData > m_uncertCalibKey
Definition: SimpleMMClusterBuilderTool.h:49
Trk::PrepRawData::localCovariance
const Amg::MatrixX & localCovariance() const
return const ref to the error matrix
Muon::SimpleMMClusterBuilderTool::getClusterPosition
StatusCode getClusterPosition(const EventContext &ctx, const Identifier &clustId, std::vector< Muon::MMPrepData > &stripsVect, Amg::Vector2D &clusterLocalPosition, Amg::MatrixX &covMatrix) const
get cluster local position and covariance matrix
Definition: SimpleMMClusterBuilderTool.cxx:153
skel.it
it
Definition: skel.GENtoEVGEN.py:423
plotBeamSpotVxVal.cov
cov
Definition: plotBeamSpotVxVal.py:201
Muon::RIO_Author
IMMClusterBuilderTool::RIO_Author RIO_Author
Definition: ClusterTimeProjectionMMClusterBuilderTool.cxx:21
beamspotman.posX
posX
Definition: beamspotman.py:1624
NswErrorCalibData::Input::clusterSize
unsigned int clusterSize
Cluster size.
Definition: NswErrorCalibData.h:37
read_hist_ntuple.t
t
Definition: read_hist_ntuple.py:5
ATH_MSG_VERBOSE
#define ATH_MSG_VERBOSE(x)
Definition: AthMsgStreamMacros.h:28
Muon
This class provides conversion from CSC RDO data to CSC Digits.
Definition: TrackSystemController.h:49
ReadCondHandle.h
Muon::IMMClusterBuilderTool::RIO_Author
MMClusterOnTrack::Author RIO_Author
Refinement of the cluster position after the cluster calibration loop is ran with a complete external...
Definition: IMMClusterBuilderTool.h:48
SimpleMMClusterBuilderTool.h
Muon::SimpleMMClusterBuilderTool::getCalibratedClusterPosition
RIO_Author getCalibratedClusterPosition(const EventContext &ctx, const std::vector< NSWCalib::CalibratedStrip > &calibratedStrips, const Amg::Vector3D &directionEstimate, Amg::Vector2D &clusterLocalPosition, Amg::MatrixX &covMatrix) const override
Definition: SimpleMMClusterBuilderTool.cxx:202
Muon::SimpleMMClusterBuilderTool::getClusters
StatusCode getClusters(const EventContext &ctx, std::vector< Muon::MMPrepData > &&stripsVect, std::vector< std::unique_ptr< Muon::MMPrepData >> &clustersVect) const override
Standard Interface to produce Micromega clusters from raw Input hits without external contstaint.
Definition: SimpleMMClusterBuilderTool.cxx:27
Amg::toString
std::string toString(const Translation3D &translation, int precision=4)
GeoPrimitvesToStringConverter.
Definition: GeoPrimitivesToStringConverter.h:40
xAOD::uint16_t
setWord1 uint16_t
Definition: eFexEMRoI_v1.cxx:88
Identifier
Definition: DetectorDescription/Identifier/Identifier/Identifier.h:32
beamspotman.n
n
Definition: beamspotman.py:731
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
xAOD::covMatrix
covMatrix
Definition: TrackMeasurement_v1.cxx:19
AmgVector
AmgVector(4) T2BSTrackFilterTool
Definition: T2BSTrackFilterTool.cxx:114
Muon::SimpleMMClusterBuilderTool::m_maxHoleSize
Gaudi::Property< uint > m_maxHoleSize
Definition: SimpleMMClusterBuilderTool.h:54
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
NSWCalib::CalibratedStrip
Definition: INSWCalibTool.h:20
NswErrorCalibData::Input::stripId
Identifier stripId
Identifier of the strip.
Definition: NswErrorCalibData.h:27
Trk::PrepRawData::identify
Identifier identify() const
return the identifier
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
charge
double charge(const T &p)
Definition: AtlasPID.h:494
Muon::MMPrepData::time
short int time() const
Returns the time (in ns)
Definition: MMPrepData.h:222
SG::CondHandleKey::initialize
StatusCode initialize(bool used=true)
Amg::Vector3D
Eigen::Matrix< double, 3, 1 > Vector3D
Definition: GeoPrimitives.h:47
beamspotman.posY
posY
Definition: beamspotman.py:1624
a
TList * a
Definition: liststreamerinfos.cxx:10
MmIdHelper
Definition: MmIdHelper.h:54
CaloCondBlobAlgs_fillNoiseFromASCII.hash
dictionary hash
Definition: CaloCondBlobAlgs_fillNoiseFromASCII.py:109
Muon::SimpleMMClusterBuilderTool::m_writeStripProperties
Gaudi::Property< bool > m_writeStripProperties
Definition: SimpleMMClusterBuilderTool.h:53
GeoPrimitivesHelpers.h
Muon::NswClustering::toLocal
Amg::Vector3D toLocal(const Trk::Surface &surf, const Amg::Vector3D &dir)
Rotates a direction vector into a local frame: x-axis : Parallell to the radial direction of the dete...
Definition: NswClusteringUtils.h:21
Muon::MMPrepData::Author::SimpleClusterBuilder
@ SimpleClusterBuilder
GeoPrimitivesToStringConverter.h
NswErrorCalibData::Input
Helper struct to be parsed to the object to derive the specific error of the cluster.
Definition: NswErrorCalibData.h:25
AthAlgTool
Definition: AthAlgTool.h:26
IdentifierHash
Definition: IdentifierHash.h:38
Muon::MMClusterOnTrack::Author
Author
Definition: MMClusterOnTrack.h:89
Muon::MMPrepData::charge
int charge() const
Returns the AD.
Definition: MMPrepData.h:227
Muon::SimpleMMClusterBuilderTool::m_maxClusSize
Gaudi::Property< unsigned int > m_maxClusSize
Definition: SimpleMMClusterBuilderTool.h:55
Muon::SimpleMMClusterBuilderTool::SimpleMMClusterBuilderTool
SimpleMMClusterBuilderTool(const std::string &, const std::string &, const IInterface *)
Definition: SimpleMMClusterBuilderTool.cxx:16
fitman.k
k
Definition: fitman.py:528
generate::Zero
void Zero(TH1D *hin)
Definition: generate.cxx:32
Muon::SimpleMMClusterBuilderTool::m_idHelperSvc
ServiceHandle< Muon::IMuonIdHelperSvc > m_idHelperSvc
Definition: SimpleMMClusterBuilderTool.h:46