ATLAS Offline Software
Loading...
Searching...
No Matches
MuonHoughTransformer_rz.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
6
7MuonHoughTransformer_rz::MuonHoughTransformer_rz(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle,
8 double threshold_histo, int number_of_sectors) :
9 MuonHoughTransformer("MuonHoughTransformer_rz", nbins, nbins_angle, detectorsize, detectorsize_angle, threshold_histo, number_of_sectors),
10 m_use_residu_grad(false) {
11 m_add_weight_radius = false;
13 m_add_weight_angle = false;
14}
15
16void MuonHoughTransformer_rz::fillHit(const std::shared_ptr<MuonHoughHit>& hit, double weight) {
17 const double hitz = hit->getHitz();
18
19 if (m_ip_setting) // niels and peter alg, butterfly to be added, and to be looked into the method
20 {
21 const int sectorhit = sector(hit);
22 const double perp = hit->getRadius();
23 const double radius = hit->getAbs();
24
25 double dotprod = 0;
26 MuonHoughHisto2D* histo = m_histos.getHisto(sectorhit);
27 for (double rz0 = histo->getXmin() + m_stepsize / 2.; rz0 < histo->getXmax(); rz0 += m_stepsize) {
28 if (std::abs(rz0) > radius) continue;
29
30 double height = std::sqrt(radius * radius - rz0 * rz0);
31 double theta = std::atan2(perp, hitz) + std::atan2(rz0, height);
32 double theta_in_grad = (theta / M_PI) * 180.;
33
34 dotprod = perp * std::sin(theta) + hitz * std::cos(theta);
35
36 if (theta_in_grad > 180.) continue; // to keep the angle physical
37 if (theta_in_grad < 0.) continue; // idem
38
39 if (dotprod >= 0) { fillHisto(rz0, theta_in_grad, weight, sectorhit); }
40 }
41 } else {
42 int sectorhit = 0;
43 const double radius = hit->getRadius();
44
46 double theta_in_rad = M_PI * theta / 180.;
47 double rz0 = hitz * std::sin(theta_in_rad) - radius * std::cos(theta_in_rad);
48 double dotprod = 0;
49
50 dotprod = radius * std::sin(theta_in_rad) + hitz * std::cos(theta_in_rad);
51 if (dotprod >= 0) { fillHisto(rz0, theta, weight, sectorhit); } // dotprod
52 }
53 } // m_atlas_setting
54}
55
56int MuonHoughTransformer_rz::fillHisto(double rz0, double theta_in_grad, double weight, int sector) {
57 MuonHoughHisto2D* histo = m_histos.getHisto(sector);
58
59 double binwidthx = histo->getBinWidthX();
60 double binwidthy = histo->getBinWidthY();
61
62 int filled_binnumber = histo->fill(rz0, theta_in_grad, weight);
63 // butterfly:
64
65 // nearby sectors:
66 if (m_number_of_sectors >= 3) {
67 double third_weight = weight / 3.;
68 if (sector != 0 && sector != m_number_of_sectors - 1) {
69 m_histos.getHisto(sector + 1)->fill(rz0, theta_in_grad, third_weight);
70 m_histos.getHisto(sector - 1)->fill(rz0, theta_in_grad, third_weight);
71 } else if (sector == 0) {
72 m_histos.getHisto(sector + 1)->fill(rz0, theta_in_grad, third_weight);
73 m_histos.getHisto(m_number_of_sectors - 1)->fill(rz0, theta_in_grad, third_weight);
74 } else {
75 m_histos.getHisto(sector - 1)->fill(rz0, theta_in_grad, third_weight);
76 m_histos.getHisto(0)->fill(rz0, theta_in_grad, third_weight);
77 }
78 }
79
80 double half_weight = 0.5 * weight;
81
82 if (theta_in_grad - binwidthy < 0) {
83 histo->fill(rz0 + binwidthx, theta_in_grad + binwidthy, half_weight);
84 if (m_use_negative_weights) { histo->fill(rz0 - binwidthx, theta_in_grad + binwidthy, -half_weight); }
85
86 } else if (theta_in_grad + binwidthy > 180.) {
87 histo->fill(rz0 - binwidthx, theta_in_grad - binwidthy, half_weight);
88 if (m_use_negative_weights) { histo->fill(rz0 + binwidthx, theta_in_grad - binwidthy, -half_weight); }
89 } else {
90 histo->fill(rz0 + binwidthx, theta_in_grad + binwidthy, half_weight);
91 histo->fill(rz0 - binwidthx, theta_in_grad - binwidthy, half_weight);
93 histo->fill(rz0 - binwidthx, theta_in_grad + binwidthy, -half_weight);
94 histo->fill(rz0 + binwidthx, theta_in_grad - binwidthy, -half_weight);
95 }
96 }
97 return filled_binnumber;
98}
99
100double MuonHoughTransformer_rz::calculateAngle(double hitx, double hity, double hitz, double z0) {
101 // z0 is cartesian coordinate where track goes through z axis
102
103 // analog to xyz:
104 double theta = 0;
105 double r = std::sqrt(hitx * hitx + hity * hity);
106
107 theta = std::atan2(r, hitz - z0);
108
109 return theta;
110}
111
113 std::pair<double, double> coordsmaximum, double maximum_residu_mm,
114 double maximum_residu_angle, int maxsector) const {
115
116 std::unique_ptr<MuonHoughPattern> houghpattern = std::make_unique<MuonHoughPattern>(MuonHough::hough_rz);
117
118 double theta{0.}, residu_distance{0.}, maximum_residu{0.};
119 double eradius{0.}, etheta{0.}, sin_theta{0.}, cos_theta{0.}, sin_phi{0.}, cos_phi{0.}, phi{0.}, ephi{0.};
120 double coordsmaximumsecondinrad = m_muonhoughmathutils.angleFromGradToRadial(coordsmaximum.second);
121 double rz0 = coordsmaximum.first;
122
123 ATH_MSG_VERBOSE("MuonHoughTransformer_rz::hookAssociateHitsToMaximum() -- sector: " << maxsector
124 << "coordsmaximumfirst: " << rz0 << "coordsmaximumsecond: " << coordsmaximum.second
125 << " coordsmaximumsecondinrad: " << coordsmaximumsecondinrad
126 <<" size of event: " << event.size());
127
128 for (unsigned int i = 0; i < event.size(); i++) {
129 double dotprod = 0;
130 double hitx = event.getHitx(i);
131 double hity = event.getHity(i);
132 int sectorhit = sector(event.getHit(i));
133 int maxsecmax = maxsector + 1;
134 int maxsecmin = maxsector - 1;
135 if (maxsecmin < 0) maxsecmin = m_number_of_sectors - 1;
136 if (maxsecmax > m_number_of_sectors - 1) maxsecmax = 0;
137 // select which hits could be in maximum:
138 if (sectorhit == maxsector || sectorhit == maxsecmin || sectorhit == maxsecmax) {
139 double hitz = event.getHitz(i);
140 double radius = std::hypot(hitx, hity);
141
142 dotprod = radius * std::sin(coordsmaximumsecondinrad) + hitz * std::cos(coordsmaximumsecondinrad);
143
144 if (dotprod >= 0) {
145 double residu_distance_mm = MuonHoughMathUtils::signedDistanceToLine(hitz, radius, rz0, coordsmaximumsecondinrad);
146
147 // Use this code for rz scan and theta
148 //
149 double radius3 = std::hypot(hitx, hity, hitz);
150 double height{0.};
151 if (std::abs(rz0) < radius3) {
152 height = std::sqrt(radius3 * radius3 - rz0 * rz0);
153 } else {
154 height = std::sqrt(rz0 * rz0 - radius3 * radius3);
155 }
156
157 theta = std::atan2(radius, hitz) + std::atan2(rz0, height);
158 ATH_MSG_VERBOSE("theta: " << theta << " height: " << height << " radius3: " << radius3
159 << " std::atan2(radius,hitz): " << std::atan2(radius, hitz)
160 << " +std::atan2(rz0,height): " << std::atan2(rz0, height) << " rz0: ");
161 if (m_use_residu_grad == 1) {
162 double residu_distance_grad = std::abs(std::sin(theta - coordsmaximumsecondinrad));
163 residu_distance = residu_distance_grad;
164 maximum_residu = maximum_residu_angle;
165 } else {
166 residu_distance = residu_distance_mm;
167 maximum_residu = maximum_residu_mm;
168 }
169
170 ATH_MSG_VERBOSE("hitx: " << hitx << " hity: " << hity << " hitz: " << hitz
171 << ", residu_distance: " << residu_distance);
172 bool inmax = false;
173 if (std::abs(theta * 180. / M_PI - coordsmaximum.second) < 1.1) inmax = true;
174
175 if (std::abs(residu_distance) < maximum_residu) // here no circular effect
176 {
177 ATH_MSG_VERBOSE(" hit added to houghpattern! -- sector number hit " << sectorhit << " max " << maxsector
178 << " detector: " << event.getHit(i)->getWhichDetector() <<
179 (inmax ? " MuonHoughTransformer_rz:: in maximum " : " OUTSIDE maximum" )<< " theta hit " << theta * 180. / M_PI << " max Hough theta "
180 << coordsmaximum.second );
181 houghpattern->addHit(event.getHit(i));
182
183 event.getHit(i)->setAssociated(true);
184
185 double rz0hit = residu_distance_mm + rz0;
186 eradius += rz0hit;
187 ATH_MSG_VERBOSE(__FILE__<<":"<<__LINE__<<" calculateAngle: " << theta << " calculateradius: " << rz0hit
188 << " R Z hit added to hough pattern theta hit "
189 << atan2(std::hypot(event.getHitx(i) ,event.getHity(i)), event.getHitz(i))
190 << " theta all " << coordsmaximumsecondinrad);
191 sin_theta += std::sin(theta);
192 cos_theta += std::cos(theta);
193
194 phi = std::atan2(hity, hitx);
195
196 sin_phi += std::sin(phi);
197 cos_phi += std::cos(phi);
198 //}
199 } else if (inmax)
200 ATH_MSG_WARNING("LOST hit in maximum distance " );
201 } // dotprod
202 } // sector constraint
203 } // hitno
204
205 etheta = std::atan2(sin_theta, cos_theta);
206 ephi = std::atan2(sin_phi, cos_phi);
207 houghpattern->setEPhi(ephi);
208
209 eradius = eradius / (houghpattern->size() + 0.0001);
210
211 ATH_MSG_VERBOSE("Etheta : " << etheta << " Size houghpattern " << houghpattern->size() << " ephi "
212 << ephi );
213 houghpattern->setETheta(etheta);
214 houghpattern->setERTheta(eradius);
215 houghpattern->setECurvature(1.);
216
217 if (houghpattern->empty()) {
218 ATH_MSG_VERBOSE("no hits found on pattern");
219 }
220
221 else if (std::abs(eradius - rz0) > 500. || std::sin(etheta - coordsmaximumsecondinrad) > 0.05) {
222 ATH_MSG_VERBOSE("WARNING Eradius or Etheta calc. WRONG -- rz0: " << rz0
223 << " etheta: " << coordsmaximumsecondinrad<< " eradius: " << eradius << " etheta: " << etheta );
224 houghpattern->setETheta(coordsmaximumsecondinrad); // coordsmaximumsecondinrad
225 houghpattern->setERTheta(rz0);
226 }
227
228 return houghpattern;
229}
230
233 return 1. / (std::abs(r0 / (m_weight_constant_radius + 1.)));
234 } else {
235 return 1;
236 } // weight function, to give more importance to patterns close to origin
237}
238
239float MuonHoughTransformer_rz::weightHoughTransform(double r0, double theta) const // theta in grad
240{
241 if (!m_add_weight_angle) {
242 return weightHoughTransform(r0);
243 } else {
245 double theta_rad = m_muonhoughmathutils.angleFromGradToRadial(theta);
246
247 float r_theta_weight = std::abs(std::sin(theta_rad)) / (1. + std::abs((r0 / 6000.)));
248
249 return r_theta_weight;
250 }
251
252 else {
253 return 1;
254 } // weight function, to give more importance to patterns close to origin
255 }
256}
#define M_PI
Scalar perp() const
perp method - perpendicular length
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
Histogram class, similar to Root's TH2D.
static double signedDistanceToLine(double x0, double y0, double r0, double phi)
distance from (x0,y0) to the line (r0,phi), phi in rad
static double calculateAngle(double hitx, double hity, double hitz, double z0)
virtual int fillHisto(double rz0, double theta, double weight, int sector) override final
fill histogram with certain coordinate
MuonHoughTransformer_rz(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle, double threshold_histo, int number_of_sectors=1)
virtual float weightHoughTransform(double r0) const override final
weight houghtransform, give more importance to houghtransforms close to origin
std::unique_ptr< MuonHoughPattern > hookAssociateHitsToMaximum(const MuonHoughHitContainer &event, std::pair< double, double > coordsmaximum, double residu_mm, double residu_grad, int sector) const override final
pure virtual method for derived class implementation of associateHitsToMaximum method
virtual void fillHit(const std::shared_ptr< MuonHoughHit > &hit, double weight=1.) override final
fill histograms with hit
int sector(const std::shared_ptr< MuonHoughHit > &hit) const override final
returns sector for coords
const double m_detectorsize_angle
range of angle coordinate
MuonHoughHisto2DContainer m_histos
histogram container
bool m_ip_setting
use settings for patterns originating from origin
bool m_use_negative_weights
use of negative weights
bool m_add_weight_angle
use weight of patterns in angle coordinate
double m_weight_constant_radius
weight constant of patterns in radius coordinate
MuonHoughMathUtils m_muonhoughmathutils
object for use of mathematical formulas for trackmodels
double m_stepsize_per_angle
stepsize of transform for angle coordinate
const int m_number_of_sectors
number of histograms (1 for cosmics 16 for rz)
double m_stepsize
stepsize of transform for radius coordinate
bool m_add_weight_radius
use weight of patterns in radius coordinate
MuonHoughTransformer(const std::string &tr_name, int nbins, int nbins_angle, double detectorsize, double detectorsize_angle, double threshold_histo, int number_of_sectors=1)
constructor, input values are those of histograms
int r
Definition globals.cxx:22