ATLAS Offline Software
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 
13 namespace MuonHough {
14 
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 
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->barcode << 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 
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
MuonHough::MuonPhiLayerHough::maximum
float maximum(float r, float phimin, float phimax, int &posbin) const
Definition: MuonPhiLayerHough.h:63
MuonHough::PhiHitVec
std::vector< std::shared_ptr< MuonHough::PhiHit > > PhiHitVec
Definition: MuonPhiLayerHough.h:20
TRTCalib_Extractor.hits
hits
Definition: TRTCalib_Extractor.py:35
MuonHough::MuonPhiLayerHough::m_rangemax
float m_rangemax
Definition: MuonPhiLayerHough.h:88
MuonHough::MuonPhiLayerHough::reset
void reset() const
Definition: MuonPhiLayerHough.cxx:27
MuonHough::MuonPhiLayerHough::fillLayer
void fillLayer(const PhiHitVec &hits, bool substract=false) const
Definition: MuonPhiLayerHough.cxx:94
MuonHough::MuonPhiLayerHough::rootHistos
std::vector< TH1 * > rootHistos(const std::string &prefix, const float *phimin=0, const float *phimax=0) const
Definition: MuonPhiLayerHough.cxx:177
dqt_zlumi_pandas.hname
string hname
Definition: dqt_zlumi_pandas.py:279
MuonHough::MuonPhiLayerHough::m_histo
std::unique_ptr< unsigned int[]> m_histo
Definition: MuonPhiLayerHough.h:93
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
skel.it
it
Definition: skel.GENtoEVGEN.py:396
MuonHough::MuonPhiLayerHough::fillLayer2
void fillLayer2(const PhiHitVec &hits, bool substract=false) const
Definition: MuonPhiLayerHough.cxx:29
MuonHough::MuonPhiLayerHough::m_debug
bool m_debug
Definition: MuonPhiLayerHough.h:92
MuonHough::MuonPhiLayerHough::associateHitsToMaximum
void associateHitsToMaximum(Maximum &maximum, const PhiHitVec &hits) const
Definition: MuonPhiLayerHough.cxx:246
MuonHough::MuonPhiLayerHough::range
std::pair< int, int > range(float, float phi1, float phi2) const
Definition: MuonPhiLayerHough.h:49
dqt_zlumi_pandas.weight
int weight
Definition: dqt_zlumi_pandas.py:189
bsCompare.db1
int db1
Definition: bsCompare.py:40
Muon::MuonStationIndex::regionName
static const std::string & regionName(DetectorRegionIndex index)
convert DetectorRegionIndex into a string
Definition: MuonStationIndex.cxx:176
lumiFormat.i
int i
Definition: lumiFormat.py:85
beamspotman.n
n
Definition: beamspotman.py:731
MuonHough::MuonPhiLayerHough::Maximum
Definition: MuonPhiLayerHough.h:23
MuonHough
Definition: MuonLayerHoughTool.h:41
checkCorrelInHIST.prefix
dictionary prefix
Definition: checkCorrelInHIST.py:391
sign
int sign(int a)
Definition: TRT_StrawNeighbourSvc.h:107
MakeTH3DFromTH2Ds.hists
hists
Definition: MakeTH3DFromTH2Ds.py:72
Muon::MuonStationIndex::layerName
static const std::string & layerName(LayerIndex index)
convert LayerIndex into a string
Definition: MuonStationIndex.cxx:192
MuonHough::MuonPhiLayerHough::MuonPhiLayerHough
MuonPhiLayerHough(int nbins, float rangemin, float rangemax, Muon::MuonStationIndex::DetectorRegionIndex region_)
Definition: MuonPhiLayerHough.cxx:15
MuonHough::MuonPhiLayerHough::~MuonPhiLayerHough
~MuonPhiLayerHough()
imax
int imax(int i, int j)
Definition: TileLaserTimingTool.cxx:33
Muon::MuonStationIndex::DetectorRegionIndex
DetectorRegionIndex
enum to classify the different layers in the muon spectrometer
Definition: MuonStationIndex.h:47
SCT_CalibAlgs::nbins
@ nbins
Definition: SCT_CalibNumbers.h:10
MuonPhiLayerHough.h
MuonHough::MuonPhiLayerHough::m_nbins
int m_nbins
Definition: MuonPhiLayerHough.h:91
h
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
CxxUtils::reset
constexpr std::enable_if_t< is_bitmask_v< E >, E & > reset(E &lhs, E rhs)
Convenience function to clear bits in a class enum bitmask.
Definition: bitmask.h:251
MuonHough::MuonPhiLayerHough::m_rangemin
float m_rangemin
Definition: MuonPhiLayerHough.h:87
python.TrigEgammaMonitorHelper.TH1F
def TH1F(name, title, nxbins, bins_par2, bins_par3=None, path='', **kwargs)
Definition: TrigEgammaMonitorHelper.py:24
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
MuonHough::MuonPhiLayerHough::m_binsize
float m_binsize
Definition: MuonPhiLayerHough.h:85
MuonHough::MuonPhiLayerHough::findMaximum
bool findMaximum(Maximum &maximum, float maxval) const
Definition: MuonPhiLayerHough.cxx:190