ATLAS Offline Software
Loading...
Searching...
No Matches
MuonHoughTransformer_rzcosmics.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
7#include "CxxUtils/sincos.h"
8
9MuonHoughTransformer_rzcosmics::MuonHoughTransformer_rzcosmics(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle,
10 double threshold_histo, int number_of_sectors) :
11 MuonHoughTransformer("MuonHoughTransformer_rzcosmics", nbins, nbins_angle, detectorsize, detectorsize_angle,
12 threshold_histo, number_of_sectors) {
14 m_weight_constant_radius = 0.3; // 1./(1 + m_weight_constant_radius*std::abs(r0)/m_detectorsize) = 1/(1+10^-5*r)
15 m_add_weight_angle = true;
16
17 m_phisec.reset(new double[m_number_of_sectors]);
18 m_sinphisec.reset(new double[m_number_of_sectors]);
19 m_cosphisec.reset(new double[m_number_of_sectors]);
20
21 for (int phisector = 0; phisector < m_number_of_sectors; phisector++) {
22 m_phisec[phisector] = (phisector + 0.5) * M_PI / (m_number_of_sectors + 0.) - M_PI; // phi [-Pi,0]
23 CxxUtils::sincos sc(m_phisec[phisector]);
24 m_sinphisec[phisector] = sc.sn;
25 m_cosphisec[phisector] = sc.cs;
26 }
27
28 m_theta_in_grad.reset(new double[m_nbins_angle]);
29 m_sintheta.reset(new double[m_nbins_angle]);
30 m_costheta.reset(new double[m_nbins_angle]);
31
32 for (int i = 0; i < m_nbins_angle; i++) {
34 const double theta_in_rad = MuonHough::degree_rad_conversion_factor * m_theta_in_grad[i];
35 CxxUtils::sincos sc(theta_in_rad);
36 m_sintheta[i] = sc.sn;
37 m_costheta[i] = sc.cs;
38 }
39}
40
41void MuonHoughTransformer_rzcosmics::fillHit(const std::shared_ptr<MuonHoughHit>& hit, double weight) {
42 const double invradius = 1. / hit->getRadius();
43 const double hitx = hit->getHitx();
44 const double hity = hit->getHity();
45 const double hitz = hit->getHitz();
46
47 for (int phisector = 0; phisector < m_number_of_sectors; phisector++) {
48 const double rphi = hitx * m_cosphisec[phisector] + hity * m_sinphisec[phisector];
49 const double dotprod = rphi * invradius;
50
51 // for (double theta_in_grad=m_stepsize_per_angle/2.; theta_in_grad<m_detectorsize_angle; theta_in_grad+=m_stepsize_per_angle)
52 // {
53 for (int i = 0; i < m_nbins_angle; i++) {
54 const double rz0 = -m_costheta[i] * rphi + m_sintheta[i] * hitz;
55 const double weighthough = weight * weightHoughTransform(rz0, m_sintheta[i], m_sinphisec[phisector], dotprod);
56 fillHisto(rz0, m_theta_in_grad[i], weighthough, phisector);
57 }
58 }
59}
60
61int MuonHoughTransformer_rzcosmics::fillHisto(double rz0, double theta_in_grad, double weight, int sector) {
62 MuonHoughHisto2D* histo = m_histos.getHisto(sector);
63
64 int filled_binnumber = histo->fill(rz0, theta_in_grad, weight);
65
66 // this houghtransform has a full butterfly pattern:
67 double half_weight = 0.5 * weight;
68
69 // should be filled using filled_binnumber!
70
71 if (theta_in_grad - m_binwidthy < 0) {
72 histo->fill(rz0 + m_binwidthx, theta_in_grad + m_binwidthy, half_weight);
73 // histo->fill(rz0-m_binwidthx,theta_in_grad-m_binwidthy + 180.,half_weight); // no cyclic angle here
74 histo->fill(rz0 - m_binwidthx, theta_in_grad + m_binwidthy, half_weight);
75 } else if (theta_in_grad + m_binwidthy > 180.) {
76 // histo->fill(rz0+m_binwidthx,theta_in_grad+m_binwidthy - 180.,half_weight);
77 histo->fill(rz0 - m_binwidthx, theta_in_grad - m_binwidthy, half_weight);
78 histo->fill(rz0 + m_binwidthx, theta_in_grad - m_binwidthy, half_weight);
79 } else {
80 histo->fill(rz0 + m_binwidthx, theta_in_grad + m_binwidthy, half_weight);
81 histo->fill(rz0 - m_binwidthx, theta_in_grad - m_binwidthy, half_weight);
82 histo->fill(rz0 - m_binwidthx, theta_in_grad + m_binwidthy, half_weight);
83 histo->fill(rz0 + m_binwidthx, theta_in_grad - m_binwidthy, half_weight);
84 }
85 return filled_binnumber;
86}
87
89 std::pair<double, double> coordsmaximum,
90 double maximum_residu_mm, double /*maximum_residu_angle*/,
91 int maxsector) const {
92
93 std::unique_ptr<MuonHoughPattern> houghpattern = std::make_unique<MuonHoughPattern>(MuonHough::hough_rzcosmics);
94
95 double eradius{0.}, er0{0.};
96 const double theta = m_muonhoughmathutils.angleFromGradToRadial(coordsmaximum.second);
97 const double rz0 = coordsmaximum.first;
98
99 const double phimax = m_phisec[maxsector];
100
101 ATH_MSG_VERBOSE("hookAssociateHitsToMaximum() -- sector: " << maxsector << " phimax: " << phimax
102 << " coordsmaximumfirst: " << rz0 << " coordsmaximumsecond: " << coordsmaximum.second
103 << " coordsmaximumsecondinrad: " << theta <<", size of event: " << event.size());
104 for (unsigned int i = 0; i < event.size(); i++) {
105 const double hitx = event.getHitx(i);
106 const double hity = event.getHity(i);
107
108 // select which hits could be in maximum:
109 const double hitz = event.getHitz(i);
110 const double perp = hitx * m_cosphisec[maxsector] + hity * m_sinphisec[maxsector];
111
112 double residu_distance = MuonHoughMathUtils::signedDistanceToLine(hitz, perp, rz0, theta);
113
114 ATH_MSG_VERBOSE("MuonHoughTransformer_rzcosmics() -- hitx: " << hitx << " hity: " << hity << " hitz: " << hitz
115 << " perp: " << perp <<", residu_distance: " << residu_distance );
116
117 if (std::abs(residu_distance) < maximum_residu_mm) // here no circular effect
118 {
119 ATH_MSG_VERBOSE("hit added to houghpattern! detector: " << event.getHit(i)->getWhichDetector()
120 <<" already associated "<< event.getHit(i)->getAssociated());
121 houghpattern->addHit(event.getHit(i));
122 event.getHit(i)->setAssociated(true);
123
124 double rz0hit = residu_distance + rz0;
125 eradius += rz0hit;
126
127 double r0hit = hitx * m_sinphisec[maxsector] - hity * m_cosphisec[maxsector];
128 er0 += r0hit;
129
130 } // hit in distance
131 } // hitno
132
133 eradius = eradius / (houghpattern->size() + 1e-7);
134 er0 = er0 / (houghpattern->size() + 1e-7);
135
136 houghpattern->setEPhi(phimax);
137 houghpattern->setERPhi(er0);
138 houghpattern->setETheta(theta);
139 houghpattern->setERTheta(eradius);
140 houghpattern->setECurvature(1.);
141
142 if (houghpattern->empty()) {
143 ATH_MSG_VERBOSE("no hits found on pattern");
144 }
145
146 else if (std::abs(eradius - rz0) > 500.) {
147 ATH_MSG_VERBOSE("Eradius or Etheta calc. WRONG -- rz0: " << rz0 << " theta: "
148 << theta<< ", eradius: " << eradius);
149
150 houghpattern->setERTheta(rz0);
151 }
152
153 updateParameters(houghpattern.get()); // not possible when phi direction not known!
154
155 ATH_MSG_VERBOSE("updateParameterstheta new phi: " << houghpattern->getEPhi()
156 << " old phi: " << phimax <<", new r0: " << houghpattern->getERPhi()
157 << " old r0: " << er0 <<" new theta: " << houghpattern->getETheta()
158 << " old theta: " << theta << " new z0: " << houghpattern->getERTheta()
159 << " old z0: " << eradius );
160 return houghpattern;
161}
162
165 return m_detectorsize / (m_detectorsize + m_weight_constant_radius * std::abs(r0));
166 } else {
167 return 1;
168 } // weight function, to give more importance to patterns close to origin
169}
170
171float MuonHoughTransformer_rzcosmics::weightHoughTransform(double r0, double sintheta, double sinphi,
172 double dotprod) const // theta in grad
173{
174 if (!m_add_weight_angle) {
175 return weightHoughTransform(r0);
176 } else {
177 double dotprod_part = 0.5 + 0.5 * dotprod * dotprod; // preference for angles that are normal to the chamber
178 double sintheta_part = 0.9 + 0.1 * sintheta * sintheta; // preference for patterns from above
179 double sinphi_part = 0.75 + 0.25 * sinphi * sinphi; // preference for patterns from above
180 float r_theta_weight = dotprod_part * sintheta_part * sinphi_part;
181
182 return r_theta_weight * weightHoughTransform(r0); // preference for patterns with low impact parameter
183 }
184}
185
186int MuonHoughTransformer_rzcosmics::sector(const std::shared_ptr<MuonHoughHit>& /*hit*/) const {
187 // function not implemented for this transform
188 return 0;
189}
190
192 const unsigned int size = houghpattern->size();
193
194 if (size <= 1) return;
195
196 const double phi = houghpattern->getEPhi();
197 const double cosphi = std::cos(phi);
198 const double sinphi = std::sin(phi);
199
200 double sum_radii = 0.;
201 double sum_z = 0.;
202
203 for (unsigned int i = 0; i < size; i++) {
204 sum_radii += houghpattern->getHitx(i) * cosphi + houghpattern->getHity(i) * sinphi;
205 sum_z += houghpattern->getHitz(i);
206 }
207
208 const double av_radii = sum_radii / (size + 0.);
209 const double av_z = sum_z / (size + 0.);
210
211 double sumr = 0.;
212 double sumz = 0.;
213 for (unsigned int i = 0; i < size; i++) {
214 double radius = houghpattern->getHitx(i) * cosphi + houghpattern->getHity(i) * sinphi;
215 double hitz = houghpattern->getHitz(i);
216 double r_offset = radius - av_radii;
217 double z_offset = hitz - av_z;
218 double weight = r_offset * r_offset + z_offset * z_offset;
219 int sign = 1;
220 if (r_offset * radius + z_offset * hitz < 0) { sign = -1; }
221 sumr += weight * sign * r_offset;
222 sumz += weight * sign * z_offset;
223 }
224
225 if (std::abs(sumr) < 0.000001 || std::abs(sumz) < 0.000001) { return; }
226
227 double theta = std::atan2(sumr, sumz);
228
229 if (theta < 0) theta += M_PI;
230
231 // if theta almost straight rely on hit for prediction (transform has difficulties prediction direction in this case):
232 double offset = 0.02;
233 if (theta < offset) {
234 if (houghpattern->getHitz(0) < 0) { theta = M_PI - theta; }
235 }
236
237 else if (theta > M_PI - offset) {
238 if (houghpattern->getHitz(0) > 0) { theta = M_PI - theta; }
239 }
240
241 const double rz0 = av_z * std::sin(theta) - av_radii * std::cos(theta);
242
243 houghpattern->setETheta(theta);
244 houghpattern->setERTheta(rz0);
245}
#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)
static Double_t sc
int sign(int a)
Histogram class, similar to Root's TH2D.
unsigned int size() const
returns size of hitcontainer
double getHitx(unsigned int hitno) const
returns x position of hit hitno
double getHity(unsigned int hitno) const
returns y position of hit hitno
double getHitz(unsigned int hitno) const
returns z position of hit hitno
static double signedDistanceToLine(double x0, double y0, double r0, double phi)
distance from (x0,y0) to the line (r0,phi), phi in rad
double getEPhi() const
returns phi of pattern
void setETheta(double etheta)
set theta of pattern
void setERTheta(double ertheta)
set z0 of pattern
MuonHoughTransformer_rzcosmics(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle, double threshold_histo, int number_of_sectors=1)
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
float weightHoughTransform(double r0) const override final
weight houghtransform, give more importance to houghtransforms close to origin
void fillHit(const std::shared_ptr< MuonHoughHit > &hit, double weight) override final
fill histograms with hit
int fillHisto(double rz0, double theta, double weight, int sector) override final
fill histogram with certain coordinate
std::unique_ptr< double[]> m_phisec
arrays that store values of transform
int sector(const std::shared_ptr< MuonHoughHit > &hit) const override final
returns sector for coords
static void updateParameters(MuonHoughPattern *)
recalculate trackparameters of pattern
MuonHoughHisto2DContainer m_histos
histogram container
bool m_add_weight_angle
use weight of patterns in angle coordinate
const int m_nbins_angle
number of bins in histograms 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_binwidthx
x-binwidth of histogram
const double m_detectorsize
range of radius coordinate
double m_binwidthy
y-binwidth of histogram
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
constexpr double degree_rad_conversion_factor
Helper to simultaneously calculate sin and cos of the same angle.
Helper to simultaneously calculate sin and cos of the same angle.
Definition sincos.h:39