ATLAS Offline Software
Loading...
Searching...
No Matches
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
6
7#include <TH1.h>
8#include <memory.h>
9
10#include <cmath>
11#include <iostream>
12
13namespace 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
20
21 // setup the histograms
22 reset();
23 }
24
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
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
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
int sign(int a)
int imax(int i, int j)
Header file for AthHistogramAlgorithm.
struct containing additional debug information on the hits that is not needed for the actual alg but ...
std::vector< std::shared_ptr< MuonHough::PhiHit > > PhiHitVec
const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
void fillLayer2(const PhiHitVec &hits, bool substract=false) const
MuonPhiLayerHough(int nbins, float rangemin, float rangemax, Muon::MuonStationIndex::DetectorRegionIndex region_)
void fillLayer(const PhiHitVec &hits, bool substract=false) const
float maximum(float r, float phimin, float phimax, int &posbin) const
bool findMaximum(Maximum &maximum, float maxval) const
std::unique_ptr< unsigned int[]> m_histo
void associateHitsToMaximum(Maximum &maximum, const PhiHitVec &hits) const
Muon::MuonStationIndex::DetectorRegionIndex m_region
std::pair< int, int > range(float, float phi1, float phi2) const
std::vector< TH1 * > rootHistos(const std::string &prefix, const float *phimin=0, const float *phimax=0) const