ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
MuonSpectrometer
MuonReconstruction
MuonRecUtils
MuonLayerHough
src
MuonPhiLayerHough.cxx
Go to the documentation of this file.
1
/*
2
Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3
*/
4
5
#include "
MuonLayerHough/MuonPhiLayerHough.h
"
6
7
#include <TH1.h>
8
#include <memory.h>
9
10
#include <cmath>
11
#include <iostream>
12
13
namespace
MuonHough
{
14
15
MuonPhiLayerHough::MuonPhiLayerHough
(
int
nbins,
float
rangemin,
float
rangemax,
Muon::MuonStationIndex::DetectorRegionIndex
region) :
16
m_rangemin
(rangemin),
m_rangemax
(rangemax),
m_region
(region),
m_nbins
(nbins),
m_histo
{new unsigned int[
m_nbins
]} {
17
// calculate the binsize
18
m_binsize
= (
m_rangemax
-
m_rangemin
) /
m_nbins
;
19
m_invbinsize
= 1. /
m_binsize
,
20
21
// setup the histograms
22
reset
();
23
}
24
25
MuonPhiLayerHough::~MuonPhiLayerHough
() =
default
;
26
27
void
MuonPhiLayerHough::reset
()
const
{ memset(
m_histo
.get(), 0,
sizeof
(
unsigned
int
) *
m_nbins
); }
28
29
void
MuonPhiLayerHough::fillLayer2
(
const
PhiHitVec
& hits,
bool
subtract)
const
{
30
if
(hits.empty())
return
;
31
32
std::vector<int> layerCounts(
m_nbins
, 0);
33
int
sign
= subtract ? -1000 : 1000;
34
// outer loop over cycles
35
36
// keep track of the previous layer
37
int
prevlayer = hits.front()->layer;
38
39
// inner loop over hits
40
PhiHitVec::const_iterator it = hits.begin();
41
PhiHitVec::const_iterator it_end = hits.end();
42
for
(; it != it_end; ++it) {
43
// if we get to the next layer process the current one and fill the Hough space
44
if
(prevlayer != (*it)->layer) {
45
for
(
int
i = 0; i <
m_nbins
; ++i) {
46
if
(subtract && -layerCounts[i] >=
static_cast<
int
>
(
m_histo
[i]))
47
m_histo
[i] = 0;
48
else
49
m_histo
[i] += layerCounts[i];
50
// if( m_debug && layerCounts[i] != 0 ) std::cout << " filling layer " << prevlayer << " bin " << i << std::endl;
51
layerCounts[i] = 0;
// reset bin
52
}
53
prevlayer = (*it)->layer;
54
}
55
56
// get bin range
57
std::pair<int, int> minMax =
range
((*it)->r, (*it)->phimin, (*it)->phimax);
58
int
binmin = minMax.first;
59
int
binmax = minMax.second;
60
61
// check wether we are within the Hough space
62
if
(binmin >=
m_nbins
)
continue
;
63
if
(binmax < 0)
continue
;
64
65
// adjust boundaries if needed
66
if
(binmin < 0) binmin = 0;
67
if
(binmax >=
m_nbins
) binmax =
m_nbins
- 1;
68
69
// output hit for debug purposes
70
if
(
m_debug
) {
71
std::cout <<
" filling hit "
<< (*it)->layer <<
" phimin "
<< (*it)->phimin <<
" phimax "
<< (*it)->phimax <<
" weight "
72
<< (*it)->w <<
" binmin "
<< binmin <<
" max "
<< binmax;
73
if
((*it)->debugInfo()) {
74
const
HitDebugInfo
* db1 = (*it)->debugInfo();
75
std::cout <<
" sec "
<< db1->sector <<
" r "
<<
Muon::MuonStationIndex::regionName
(db1->region) <<
" type "
<< db1->type
76
<<
" lay "
<<
Muon::MuonStationIndex::layerName
(db1->layer) <<
" bc "
<< db1->uniqueID << std::endl;
77
}
else
78
std::cout << std::endl;
79
}
80
int
weight =
sign
* (*it)->w;
81
// set bits to true
82
for
(; binmin <= binmax; ++binmin) layerCounts[binmin] = weight;
83
}
84
// if the last set of hits was not filled, fill them now
85
for
(
int
i = 0; i <
m_nbins
; ++i) {
86
if
(subtract && -layerCounts[i] >=
static_cast<
int
>
(
m_histo
[i]))
87
m_histo
[i] = 0;
88
else
89
m_histo
[i] += layerCounts[i];
90
// if( m_debug && layerCounts[i] != 0 ) std::cout << " filling layer " << prevlayer << " bin " << i << std::endl;
91
}
92
}
93
94
void
MuonPhiLayerHough::fillLayer
(
const
PhiHitVec
& hits,
bool
subtract)
const
{
95
if
(hits.empty())
return
;
96
if
(
m_debug
) std::cout <<
" filling layers, hits "
<< hits.size() <<
" subtract "
<< subtract << std::endl;
97
int
prevlayer = -1;
98
int
prevbinmin = 10000;
99
int
prevbinmax = -1;
100
// loop over hits
101
PhiHitVec::const_iterator it = hits.begin();
102
PhiHitVec::const_iterator it_end = hits.end();
103
for
(; it != it_end; ++it) {
104
std::pair<int, int> minMax =
range
((*it)->r, (*it)->phimin, (*it)->phimax);
105
// if( m_debug ) std::cout << " filling: min " << minMax.first << " max " << minMax.second << std::endl;
106
int
binmin = minMax.first;
107
int
binmax = minMax.second;
108
109
if
(binmin >=
m_nbins
)
continue
;
110
if
(binmax < 0)
continue
;
111
112
if
(binmin < 0) binmin = 0;
113
if
(binmax >=
m_nbins
) binmax =
m_nbins
- 1;
114
if
(
m_debug
)
115
std::cout <<
" layer "
<< (*it)->layer <<
" r "
<< (*it)->r <<
" phimin "
<< (*it)->phimin <<
" phimax "
<< (*it)->phimax
116
<<
" new min "
<< binmin <<
" "
<< binmax << std::endl;
117
118
// first hit within range
119
if
(prevbinmax == -1) {
120
if
(
m_debug
)
121
std::cout <<
" first range "
<< (*it)->layer <<
" r "
<< (*it)->r <<
" range "
<< binmin <<
" "
<< binmax <<
" new min "
122
<< binmin <<
" "
<< binmax << std::endl;
123
prevbinmin = binmin;
124
prevbinmax = binmax;
125
prevlayer = (*it)->layer;
126
continue
;
127
}
128
129
if
(binmin < prevbinmin && prevlayer == (*it)->layer)
130
std::cout <<
"Error hits are out of order: min "
<< binmin <<
" max "
<< binmax << std::endl;
131
132
// if the max value of the previous hit is smaller than the current minvalue fill the histogram of the previous hit
133
// do the same when reached last hit
134
if
(prevbinmax < binmin || prevlayer != (*it)->layer) {
135
if
(
m_debug
)
136
std::cout <<
" filling "
<< (*it)->layer <<
" r "
<< (*it)->r <<
" phimin "
<< (*it)->phimin <<
" phimax "
137
<< (*it)->phimax <<
" range "
<< prevbinmin <<
" "
<< prevbinmax <<
" new min "
<< binmin <<
" "
<< binmax
138
<< std::endl;
139
for
(
int
n = prevbinmin; n <= prevbinmax; ++n) {
140
unsigned
int
& val =
m_histo
[n];
141
int
w = 1000 * (*it)->w;
142
if
(subtract) w *= -1;
143
if
(w < 0 && (
int
)val < -w)
144
val = 0;
145
else
146
val += w;
147
}
148
prevbinmin = binmin;
149
prevbinmax = binmax;
150
prevlayer = (*it)->layer;
151
152
}
else
{
153
// update the maximum value of the window
154
if
(
m_debug
)
155
std::cout <<
" updating range "
<< (*it)->layer <<
" r "
<< (*it)->r <<
" phimin "
<< (*it)->phimin <<
" phimax "
156
<< (*it)->phimax <<
" range "
<< prevbinmin <<
" "
<< prevbinmax <<
" new min "
<< binmin <<
" "
<< binmax
157
<< std::endl;
158
prevbinmax = binmax;
159
}
160
}
161
if
(prevbinmax != -1) {
162
if
(
m_debug
)
163
std::cout <<
" filling "
<< hits.back()->layer <<
" r "
<< hits.back()->r <<
" phimin "
<< hits.back()->phimin <<
" phimax "
164
<< hits.back()->phimax <<
" range "
<< prevbinmin <<
" "
<< prevbinmax << std::endl;
165
for
(
int
n = prevbinmin; n <= prevbinmax; ++n) {
166
unsigned
int
& val =
m_histo
[n];
167
int
w = 1000 * hits.back()->w;
168
if
(subtract) w *= -1;
169
if
(w < 0 && (
int
)val < -w)
170
val = 0;
171
else
172
val += w;
173
}
174
}
175
}
176
177
std::vector<TH1*>
MuonPhiLayerHough::rootHistos
(
const
std::string& prefix,
const
float
* phimi,
const
float
* phima)
const
{
178
std::vector<TH1*> hists;
179
180
float
phimin = phimi ? *phimi :
m_rangemin
;
181
float
phimax = phima ? *phima :
m_rangemax
;
182
183
TString hname = prefix +
"_hist"
;
184
TH1F*
h
=
new
TH1F(hname, hname,
m_nbins
, phimin, phimax);
185
for
(
int
n = 0; n <
m_nbins
; ++n)
h
->SetBinContent(n + 1,
m_histo
[n] * 0.001);
186
hists.push_back(
h
);
187
return
hists;
188
}
189
190
bool
MuonPhiLayerHough::findMaximum
(
MuonPhiLayerHough::Maximum
&
maximum
,
float
maxval)
const
{
191
maximum
.max = 0;
192
maximum
.pos = 0;
193
194
maximum
.binpos = -1;
195
maximum
.binposmin = -1;
196
maximum
.binposmax = -1;
197
198
maximum
.hits.clear();
199
maximum
.hough =
this
;
200
201
if
(maxval < 0)
return
false
;
202
203
unsigned
int
tmax = 0;
204
int
posb = -1;
205
unsigned
int
imaxval = maxval * 1000;
206
// loop over histograms and find maximum
207
for
(
int
n = 0; n <
m_nbins
; ++n) {
208
if
(
m_histo
[n] < tmax)
continue
;
209
tmax =
m_histo
[n];
210
posb = n;
211
}
212
if
(posb == -1)
return
false
;
213
if
(tmax < imaxval)
return
false
;
214
215
maximum
.max = tmax / 1000.;
216
maximum
.pos =
m_rangemin
+
m_binsize
* posb;
217
maximum
.binpos = posb;
218
maximum
.binposmin = posb;
219
maximum
.binposmax = posb;
220
if
(
maximum
.max > 100) {
221
std::cout <<
" too large maximum: "
<<
maximum
.max <<
" tmax "
<< tmax << std::endl;
222
for
(
int
n = 0; n <
m_nbins
; ++n) std::cout <<
" "
<<
m_histo
[n] << std::endl;
223
}
224
225
// determin width of maximum
226
unsigned
int
imax
=
m_histo
[posb];
227
unsigned
int
sidemax = 0.7 *
imax
;
228
// loop down, catch case the maximum is in the first bin
229
for
(
int
n = posb != 0 ? posb - 1 : posb; n >= 0; --n) {
230
if
(
m_histo
[n] > sidemax) {
231
maximum
.binposmin = n;
232
}
else
{
233
break
;
234
}
235
}
236
for
(
int
n = posb + 1; n <
m_nbins
; ++n) {
237
if
(
m_histo
[n] > sidemax) {
238
maximum
.binposmax = n;
239
}
else
{
240
break
;
241
}
242
}
243
return
true
;
244
}
245
246
void
MuonPhiLayerHough::associateHitsToMaximum
(
MuonPhiLayerHough::Maximum
&
maximum
,
const
PhiHitVec
& hits)
const
{
247
if
(
maximum
.binposmax == -1 ||
maximum
.binposmin == -1)
return
;
248
// loop over hits and find those that are compatible with the maximum
249
PhiHitVec::const_iterator it = hits.begin();
250
PhiHitVec::const_iterator it_end = hits.end();
251
for
(; it != it_end; ++it) {
252
// calculate the bins associated with the hit and check whether any of they are part of the maximum
253
std::pair<int, int> minMax =
range
((*it)->r, (*it)->phimin, (*it)->phimax);
254
if
(
m_debug
)
255
std::cout <<
" hit: r "
<< (*it)->r <<
" phimin "
<< (*it)->phimin <<
" phimax "
<< (*it)->phimax <<
" range "
256
<< minMax.first <<
" "
<< minMax.second <<
" maximum range "
<<
maximum
.binposmin <<
" "
<<
maximum
.binposmax
257
<< std::endl;
258
if
(minMax.first >
maximum
.binposmax)
continue
;
// minimum bin large than the maximum, drop
259
if
(minMax.second <
maximum
.binposmin)
continue
;
// maximum bin smaller than the minimum, drop
260
// keep everything else
261
maximum
.hits.push_back(*it);
262
}
263
}
264
265
}
// namespace MuonHough
MuonPhiLayerHough.h
sign
int sign(int a)
Definition
TRT_StrawNeighbourSvc.h:108
imax
int imax(int i, int j)
Definition
TileLaserTimingTool.cxx:33
h
Header file for AthHistogramAlgorithm.
MuonHough::HitDebugInfo
struct containing additional debug information on the hits that is not needed for the actual alg but ...
Definition
MuonSpectrometer/MuonReconstruction/MuonRecUtils/MuonLayerHough/MuonLayerHough/Hit.h:26
MuonHough
Definition
MuonLayerHoughTool.h:40
MuonHough::PhiHitVec
std::vector< std::shared_ptr< MuonHough::PhiHit > > PhiHitVec
Definition
MuonPhiLayerHough.h:20
Muon::MuonStationIndex::layerName
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
Definition
MuonStationIndex.cxx:154
Muon::MuonStationIndex::DetectorRegionIndex
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
Definition
MuonStationIndex.h:48
Muon::MuonStationIndex::regionName
const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
Definition
MuonStationIndex.cxx:139
MuonHough::MuonPhiLayerHough::Maximum
Definition
MuonPhiLayerHough.h:23
MuonHough::MuonPhiLayerHough::~MuonPhiLayerHough
~MuonPhiLayerHough()
MuonHough::MuonPhiLayerHough::fillLayer2
void fillLayer2(const PhiHitVec &hits, bool substract=false) const
Definition
MuonPhiLayerHough.cxx:29
MuonHough::MuonPhiLayerHough::MuonPhiLayerHough
MuonPhiLayerHough(int nbins, float rangemin, float rangemax, Muon::MuonStationIndex::DetectorRegionIndex region_)
Definition
MuonPhiLayerHough.cxx:15
MuonHough::MuonPhiLayerHough::fillLayer
void fillLayer(const PhiHitVec &hits, bool substract=false) const
Definition
MuonPhiLayerHough.cxx:94
MuonHough::MuonPhiLayerHough::m_binsize
float m_binsize
Definition
MuonPhiLayerHough.h:85
MuonHough::MuonPhiLayerHough::maximum
float maximum(float r, float phimin, float phimax, int &posbin) const
Definition
MuonPhiLayerHough.h:63
MuonHough::MuonPhiLayerHough::m_invbinsize
float m_invbinsize
Definition
MuonPhiLayerHough.h:86
MuonHough::MuonPhiLayerHough::m_rangemin
float m_rangemin
Definition
MuonPhiLayerHough.h:87
MuonHough::MuonPhiLayerHough::findMaximum
bool findMaximum(Maximum &maximum, float maxval) const
Definition
MuonPhiLayerHough.cxx:190
MuonHough::MuonPhiLayerHough::m_histo
std::unique_ptr< unsigned int[]> m_histo
Definition
MuonPhiLayerHough.h:93
MuonHough::MuonPhiLayerHough::m_rangemax
float m_rangemax
Definition
MuonPhiLayerHough.h:88
MuonHough::MuonPhiLayerHough::m_nbins
int m_nbins
Definition
MuonPhiLayerHough.h:91
MuonHough::MuonPhiLayerHough::associateHitsToMaximum
void associateHitsToMaximum(Maximum &maximum, const PhiHitVec &hits) const
Definition
MuonPhiLayerHough.cxx:246
MuonHough::MuonPhiLayerHough::m_region
Muon::MuonStationIndex::DetectorRegionIndex m_region
Definition
MuonPhiLayerHough.h:90
MuonHough::MuonPhiLayerHough::m_debug
bool m_debug
Definition
MuonPhiLayerHough.h:92
MuonHough::MuonPhiLayerHough::reset
void reset() const
Definition
MuonPhiLayerHough.cxx:27
MuonHough::MuonPhiLayerHough::range
std::pair< int, int > range(float, float phi1, float phi2) const
Definition
MuonPhiLayerHough.h:49
MuonHough::MuonPhiLayerHough::rootHistos
std::vector< TH1 * > rootHistos(const std::string &prefix, const float *phimin=0, const float *phimax=0) const
Definition
MuonPhiLayerHough.cxx:177
Generated on
for ATLAS Offline Software by
1.17.0