ATLAS Offline Software
Loading...
Searching...
No Matches
MuonHoughTransformer_xyz.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#include "CxxUtils/sincos.h"
7
8MuonHoughTransformer_xyz::MuonHoughTransformer_xyz(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle,
9 double threshold_histo, int number_of_sectors) :
10 MuonHoughTransformer("MuonHoughTransformer_xyz", nbins, nbins_angle, detectorsize, detectorsize_angle, threshold_histo, number_of_sectors) {
13}
14
15void MuonHoughTransformer_xyz::fillHit(const std::shared_ptr<MuonHoughHit>& hit, double weight) {
16 double radius = hit->getRadius();
17 double hitx = hit->getHitx();
18 double hity = hit->getHity();
19 int sectorhit = sector(hit);
20 double dotprod{0.};
21
22 if (m_ip_setting) {
23 std::pair<double, double> endpoints = getEndPointsFillLoop(radius, m_stepsize, sectorhit);
24 for (double r0 = endpoints.first; r0 < endpoints.second; r0 += m_stepsize) {
25 double phi = calculateAngle(hitx, hity, r0);
26 CxxUtils::sincos scphi(phi);
27 dotprod = scphi.apply(hity, hitx); // hity * sincosphi[0] + hitx * sincosphi[1];
28 if (dotprod >= 0) {
29 double phi_in_grad = phi * MuonHough::rad_degree_conversion_factor;
30 fillHisto(r0, phi_in_grad, weight, sectorhit);
31 }
32 }
33 } // m_ip_setting
34
35 else // m_ip_setting == false
36 {
38 double phi_in_rad = MuonHough::degree_rad_conversion_factor * phi;
39 CxxUtils::sincos scphi(phi_in_rad);
40 double r0 = scphi.apply(hitx, -hity);
41 fillHisto(r0, phi, weight, sectorhit);
42 }
43 }
44}
45
46int MuonHoughTransformer_xyz::fillHisto(double r0, double phi, double weight, int sector) // phi in grad!
47{
48 MuonHoughHisto2D* histo = m_histos.getHisto(sector);
49
50 const int filled_binnumber = histo->fill(r0, phi, weight);
51
52 // applying a 'butterfly' weighting effect:
53 bool butterfly = true;
54 if (butterfly) {
55 // nearby sectors:
56 if (m_number_of_sectors >= 3) {
57 double third_weight = weight / 3.;
58 if (sector != 0 && sector != m_number_of_sectors - 1) {
59 m_histos.getHisto(sector + 1)->fill(filled_binnumber, third_weight);
60 m_histos.getHisto(sector - 1)->fill(filled_binnumber, third_weight);
61 } else if (sector == 0) {
62 m_histos.getHisto(sector + 1)->fill(filled_binnumber, third_weight);
63 } else // sector == m_number_of_sectors - 1
64 {
65 m_histos.getHisto(sector - 1)->fill(filled_binnumber, third_weight);
66 }
67 }
68
69 double half_weight = 0.5 * weight;
70
71 histo->fill(filled_binnumber - 1, half_weight);
72 histo->fill(filled_binnumber + 1, half_weight);
73
74 const int upperright = filled_binnumber + m_nbins_plus3;
75 const int lowerleft = filled_binnumber - m_nbins_plus3;
76
77 if (phi - m_binwidthy < 0) {
78 histo->fill(r0 - m_binwidthx, phi - m_binwidthy + m_detectorsize_angle, half_weight); // should calculate binnumber..
79 histo->fill(upperright, half_weight);
81 histo->fill(r0 + m_binwidthx, phi - m_binwidthy + m_detectorsize_angle, -half_weight);
82 histo->fill(upperright - 2, -half_weight);
83 }
84 } else if (phi + m_binwidthy > m_detectorsize_angle) {
85 histo->fill(lowerleft, half_weight);
86 histo->fill(r0 + m_binwidthx, phi + m_binwidthy - m_detectorsize_angle, half_weight);
88 histo->fill(lowerleft + 2, -half_weight);
89 histo->fill(r0 - m_binwidthx, phi + m_binwidthy - m_detectorsize_angle, -half_weight);
90 }
91 } else {
92 histo->fill(lowerleft, half_weight);
93 histo->fill(upperright, half_weight);
95 histo->fill(lowerleft + 2, -half_weight);
96 histo->fill(upperright - 2, -half_weight);
97 }
98 }
99 }
100 return filled_binnumber;
101}
102
103double MuonHoughTransformer_xyz::calculateAngle(double hitx, double hity, double r0) {
104 double phi = 0;
105 double height_squared = hitx * hitx + hity * hity - r0 * r0;
106 if (height_squared >= 0) {
107 double height = std::sqrt(height_squared);
108 phi = std::atan2(hity, hitx) + std::atan2(r0, height);
109 }
110
111 else {
112 phi = std::atan2(hity, hitx);
113 }
114
115 if (phi < 0) { phi += MuonHough::two_Pi; }
117
118 return phi;
119}
120
122 std::pair<double, double> coordsmaximum, double max_residu_mm,
123 double /*max_residu_angle*/, int max_sector) const {
124 std::unique_ptr<MuonHoughPattern> houghpattern{initialiseHoughPattern()};
125 ATH_MSG_DEBUG("MuonHoughTransformer_xyz::hookAssociateHitsToMaximum (start)");
126
127
128 double ephi{0.}, eradius{0.}, sin_phi{0.}, cos_phi{0.};
129 double dotprod{0.}, etheta{0.}, residu_distance{0.};
130
131 ATH_MSG_DEBUG("MuonHoughTransformer_xyz::size_event: " << event.size() );
132 ATH_MSG_DEBUG("MuonHoughTransformer_xyz::found_maximum: r: " << coordsmaximum.first << " phi: " << coordsmaximum.second
133 << " sector: " << max_sector);
134
135
136
137 double phimax = m_muonhoughmathutils.angleFromGradToRadial(coordsmaximum.second);
138 CxxUtils::sincos scphimax(phimax);
139
140 int max_secmax = max_sector + 1;
141 int max_secmin = max_sector - 1;
142 if (max_secmin < 0) max_secmin = max_sector;
143 if (max_secmax > m_number_of_sectors - 1) max_secmax = max_sector;
144
145 for (unsigned int i = 0; i < event.size(); i++) {
146 double hitx = event.getHitx(i);
147 double hity = event.getHity(i);
148 double hitz = event.getHitz(i);
149
150 double radiushit = std::sqrt(hitx * hitx + hity * hity);
151 int sectorhit = sector(event.getHit(i));
152
153 if (sectorhit == max_sector || sectorhit == max_secmin || sectorhit == max_secmax) {
154 if (!m_ip_setting) {
155 dotprod = 1.;
156 } else {
157 dotprod = scphimax.apply(getHitPos(event, i).second,
158 getHitPos(event, i).first);
159 }
160 if (dotprod >= 0) {
161 residu_distance = -coordsmaximum.first +
162 scphimax.apply(getHitPos(event, i).first,
163 -getHitPos(event, i).second);
164 ATH_MSG_VERBOSE("MuonHoughTransformer_xyz::hitx: " << getHitPos(event, i).first
165 << " hity: " << getHitPos(event, i).second << " dotprod: " << dotprod << " sector: "
166 << sectorhit<<",residu_distance: " << residu_distance);
167
168 if (std::abs(residu_distance) < max_residu_mm) {
169 houghpattern->addHit(event.getHit(i));
170
171 ATH_MSG_VERBOSE("MuonHoughTransformer_xyz::hit added to houghpattern!");
172 ATH_MSG_VERBOSE(" hit already earlier associated to pattern!");
173
174 event.getHit(i)->setAssociated(true);
175
176 double phi = calculateAngle(hitx, hity, coordsmaximum.first);
177
178 double thetah = std::atan2(radiushit, hitz);
179 ATH_MSG_VERBOSE(" X Y hit added to hough pattern phi hit " << std::atan2(event.getHity(i), event.getHitx(i))
180 << " phi_calc: " << phi << " phi all " << phimax << " theta hit " << thetah );
181
182
183 etheta += thetah;
184 CxxUtils::sincos scphi(phi);
185
186 sin_phi += scphi.sn;
187 cos_phi += scphi.cs;
188
189 double radius = MuonHoughMathUtils::signedDistanceOfLineToOrigin2D(event.getHitx(i), event.getHity(i), phimax);
190 eradius += radius;
191 ATH_MSG_VERBOSE(" calculateAngle: " << phi << " calculateradius: " << radius);
192 }
193 } // dotprod >=0
194 } // sector requirement
195 } // size
196
197 eradius = eradius / (houghpattern->size() + 0.0001);
198 etheta = etheta / (houghpattern->size() + 0.0001);
199 ephi = std::atan2(sin_phi, cos_phi);
200
201 ATH_MSG_VERBOSE("ephi: " << ephi << " eradius: " << eradius << " etheta " << etheta);
202
203 if (m_ip_setting)
204 houghpattern->setEPhi(ephi);
205 else {
206 houghpattern->setEPhi(phimax);
207 }
208
209 houghpattern->setERPhi(coordsmaximum.first);
210 houghpattern->setETheta(etheta);
211
212 if (!houghpattern->empty() && std::abs(std::sin(houghpattern->getEPhi() - phimax)) > 0.05) {
213 ATH_MSG_WARNING("MuonHoughTransformer_xyz:: Ephi calculation went wrong -- histo radius: "
214 << coordsmaximum.first << " phi: " << phimax <<", ephi: " << ephi);
215 houghpattern->setEPhi(MuonHoughMathUtils::angleFromMinusPiToPi(phimax));
216 houghpattern->setERPhi(coordsmaximum.first);
217 }
218
219 if (!m_ip_setting) {
220 houghpattern->updateParametersRPhi(true); // switch off ip constraint! (cosmics==true), on by default (cosmics== false)
221
222 ATH_MSG_VERBOSE("updateParameterstheta new phi (phi flipped Pi for cosmics): " << houghpattern->getEPhi()
223 << " old phi: " << phimax <<" new r0: " << houghpattern->getERPhi()
224 << " old r0: " << coordsmaximum.first);
225 }
226
227 return houghpattern;
228}
229
232 return (1. / (std::abs(r0 / m_weight_constant_radius) + 1.));
233 } else {
234 return 1;
235 } // weight function, to give more importance to patterns close to origin
236}
237
238int MuonHoughTransformer_xyz::sector(const std::shared_ptr<MuonHoughHit>& hit) const {
239 double radius = hit->getRadius();
240 double hitz = hit->getHitz();
241
242 // returns the sector number of the hit 0..m_number_of_sectors-1
243
244 // Peter Kluit correction
245 double theta = std::atan2(radius, hitz); // radius>0 : theta: [0,Pi]
246
247 int sectorhit = static_cast<int>(theta * m_number_of_sectors / M_PI);
248 if (sectorhit == m_number_of_sectors) sectorhit += -1; // could happen in rare cases
249 return sectorhit; // only valid for xy!! yz to be done (or to be abondoned)
250}
#define M_PI
Scalar phi() const
phi method
Scalar theta() const
theta method
#define ATH_MSG_VERBOSE(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Histogram class, similar to Root's TH2D.
static double signedDistanceOfLineToOrigin2D(double x, double y, double phi)
signed distance of line with point (x,y) and angle phi to origin
static double angleFromMinusPiToPi(double angle)
computes angle in rad between -Pi and Pi
std::unique_ptr< MuonHoughPattern > hookAssociateHitsToMaximum(const MuonHoughHitContainer &event, std::pair< double, double > coordsmaximum, double residu_mm, double residu_grad, int sector) const override final
associate hits to maximum found
virtual std::unique_ptr< MuonHoughPattern > initialiseHoughPattern() const =0
build new houghpattern
static double calculateAngle(double hitx, double hity, double r0)
calcalates the phi angle for a given hit and r0
float weightHoughTransform(double r0) const override final
put weight on houghtransform dependent on r0
void fillHit(const std::shared_ptr< MuonHoughHit > &hit, double weight) override final
fill hit in histogram
int fillHisto(double r0, double phi, double weight, int sector) override final
fill transformed values in histogram
virtual std::pair< double, double > getHitPos(const MuonHoughHitContainer &event, int hitid) const =0
returns the relevant 2d hit position
int sector(const std::shared_ptr< MuonHoughHit > &hit) const override final
returns the rz sector
MuonHoughTransformer_xyz(int nbins, int nbins_angle, double detectorsize, double detectorsize_angle, double threshold_histo, int number_of_sectors=1)
constructor
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
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
double m_binwidthx
x-binwidth of histogram
const int m_nbins_plus3
number of bins in histograms in radius coordinate
double m_binwidthy
y-binwidth of histogram
bool m_add_weight_radius
use weight of patterns in radius coordinate
std::pair< double, double > getEndPointsFillLoop(double radius, double stepsize, int sector) const
returns begin and end value of the filling loop
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 two_Pi
constexpr double degree_rad_conversion_factor
constexpr double rad_degree_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
double apply(double a, double b) const
Definition sincos.h:57