ATLAS Offline Software
Loading...
Searching...
No Matches
FsmwMode1dFinder.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5/*********************************************************************
6 FsmwMode1dFinder.cxx - Description in header file
7*********************************************************************/
8
9//#define FSMWMODE1DFINDER_DEBUG
10
12#include <algorithm>
13#include <cmath>
14#include <vector>
15
16namespace Trk
17{
18
19 FsmwMode1dFinder::FsmwMode1dFinder(const std::string& t, const std::string& n, const IInterface* p) :
20 AthAlgTool(t,n,p),
21 m_fraction(0.5),
23 {
24 declareProperty("Fraction", m_fraction);
25 declareProperty("FirstFraction", m_firstfraction);
26 declareInterface<IMode1dFinder>(this);
27 }
28
30
31
32#ifdef FSMWMODE1DFINDER_DEBUG
33 namespace {
34 int debug_counter=200;
35 }
36#endif
37
38 double FsmwMode1dFinder::getMode(std::vector<DoubleAndWeight> DoubleAndWeights) const {
39
40 if(DoubleAndWeights.empty()) return 0.;
41 if(DoubleAndWeights.size() == 1) return DoubleAndWeights.begin()->first;
42
43#ifdef FSMWMODE1DFINDER_DEBUG
44 msg(MSG::DEBUG) << "entered FsmwMode1dFinder::GetMode " << endmsg;
45#endif
46
47 //first of all order the vector according to the double value
48 std::sort(DoubleAndWeights.begin(),DoubleAndWeights.end(),CompareTheTwoDoubleAndWeights() );
49
50 //ok now begin to consider a certain number of elements according to the fraction
51 std::vector<DoubleAndWeight>::const_iterator begin=DoubleAndWeights.begin();
52 std::vector<DoubleAndWeight>::const_iterator end=DoubleAndWeights.end();
53
54 double overallweight(0.);
55 std::vector<DoubleAndWeight>::const_iterator best_begin=begin;
56 std::vector<DoubleAndWeight>::const_iterator best_end=end;
57
58#ifdef FSMWMODE1DFINDER_DEBUG
59 msg(MSG::DEBUG) << "Size of incoming vector is" << DoubleAndWeights.size() << endmsg;
60#endif
61
62
63 double last_value(1e100);
64
65 bool isthelast=false;
66
67 int counter=0;
68 double fraction=m_firstfraction;
69 while (!isthelast) {
70
71 counter+=1;
72 if (counter==2) {
73 fraction = m_fraction;
74 }
75
76#ifdef FSMWMODE1DFINDER_DEBUG
77 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Before \"int step = (int)std::floor(fraction*(end-begin+1))\" " << endmsg;
78#endif
79 int step = (int)std::floor(fraction*(end-begin+1));
80 overallweight=0.;
81 {
82 std::vector<DoubleAndWeight>::const_iterator i=begin;
83 if (step>0) {
84 std::vector<DoubleAndWeight>::const_iterator j_end=i+step-1;
85 for (std::vector<DoubleAndWeight>::const_iterator j=i;j!=j_end;++j) {
86#ifdef FSMWMODE1DFINDER_DEBUG
87 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "In the single interval, the component number unknown, value: " << j->first << " weight "
88 << j->second << endmsg;
89#endif
90 overallweight+=j->second;
91 }
92 }
93 }
94
95 std::vector<DoubleAndWeight>::const_iterator i_last = begin+step-1;
96
97#ifdef FSMWMODE1DFINDER_DEBUG
98 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "After \"int step = (int)std::floor(fraction*(end-begin+1))\" " << endmsg;
99#endif
100 for (std::vector<DoubleAndWeight>::const_iterator i=begin;i!=(end-step+1);++i, ++i_last) {
101#ifdef FSMWMODE1DFINDER_DEBUG
102 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Interval number unknown, value: " << i->first << endmsg;
103#endif
104
105 //calculate the weight the interval should be divided into
106 overallweight+= i_last->second;
107
108 #ifdef FSMWMODE1DFINDER_DEBUG
109 if (debug_counter>0)
110 {
111 --debug_counter;
112 double alt_overallweight=0.;
113 for (std::vector<DoubleAndWeight>::const_iterator j=i;j!=i+step;j++) {
114#ifdef FSMWMODE1DFINDER_DEBUG
115 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "In the single interval, the component number unknown, value: " << j->first << " weight "
116 << j->second << endmsg;
117#endif
118 alt_overallweight+=j->second;
119 }
120 if (std::abs(alt_overallweight - overallweight) > alt_overallweight * std::numeric_limits<double>::epsilon() * 16 ) {
121 ATH_MSG_ERROR("Weights differ: " << alt_overallweight << " != " << overallweight);
122 }
123 }
124 #endif
125
126
127 double new_value = ((i+step-1)->first-i->first)/overallweight;
128 if (new_value<last_value) {
129#ifdef FSMWMODE1DFINDER_DEBUG
130 msg(MSG::DEBUG) << "New value: " << ((i+step-1)->first-i->first)/overallweight << " while the previous one was " <<
131 last_value << endmsg;
132 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Best case since ever now" << endmsg;
133#endif
134 last_value=((i+step-1)->first-i->first)/overallweight;
135 best_begin=i;
136 best_end=i+step-1;
137 }
138 overallweight-= i->second;
139
140 }
141
142#ifdef FSMWMODE1DFINDER_DEBUG
143 msg(MSG::DEBUG) << "Ended a cycle with success" << endmsg;
144 if (begin==best_begin && end ==best_end) {
145 ATH_MSG_ERROR( "No change at step=" << step );
146 }
147#endif
148 //assign the new begin and end...
149 begin=best_begin;
150 end=best_end;
151 last_value=1e100;
152
153 //Now it should have returned the value with smallest (x2-x1)/weight
154 if (best_end-best_begin<=2) isthelast=true;
155 }
156
157 //return the weighted mean of the best_begin and best_end
158
159 //you are working only on first and last
160 //(but what about taking all three ???)
161
162 if (best_end-best_begin==2)
163 {
164 std::vector<DoubleAndWeight>::const_iterator medium=begin;
165 ++medium;
166 return (begin->first*begin->second+medium->first*medium->second+end->first*end->second)/(begin->second+medium->second+end->second);
167 }
168
169
170 return (begin->first*begin->second+end->first*end->second)/(begin->second+end->second);
171
172 }
173
174
175 double FsmwMode1dFinder::getMode(std::vector<double> Doubles) const {
176
177
178
179#ifdef FSMWMODE1DFINDER_DEBUG
180 msg(MSG::DEBUG) << "entered FsmwMode1dFinder::GetMode " << endmsg;
181#endif
182
183 //first of all order the vector according to the double value
184 std::sort(Doubles.begin(),Doubles.end(),CompareTheTwoDoubles() );
185
186 //ok now begin to consider a certain number of elements according to the fraction
187 std::vector<double>::const_iterator begin=Doubles.begin();
188 std::vector<double>::const_iterator end=Doubles.end();
189
190 // double overallweight(0.);
191 std::vector<double>::const_iterator best_begin=begin;
192 std::vector<double>::const_iterator best_end=end;
193
194#ifdef FSMWMODE1DFINDER_DEBUG
195 msg(MSG::DEBUG) << "Size of incoming vector is" << Doubles.size() << endmsg;
196#endif
197
198
199 double last_value(1e100);
200
201 bool isthelast=false;
202 while (!isthelast) {
203#ifdef FSMWMODE1DFINDER_DEBUG
204 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Before \"int step = (int)std::floor(m_fraction*(end-begin+1))\" " << endmsg;
205#endif
206 int step = (int)std::floor(m_fraction*(end-begin+1));
207#ifdef FSMWMODE1DFINDER_DEBUG
208 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "After \"int step = (int)std::floor(m_fraction*(end-begin+1))\" " << endmsg;
209#endif
210 for (std::vector<double>::const_iterator i=begin;i!=(end-step+1);++i) {
211#ifdef FSMWMODE1DFINDER_DEBUG
212 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Interval number unknown, value: " << i->first << endmsg;
213#endif
214 //calculate the weight the interval should be divided into
215 // overallweight=0.;
216 //for (std::vector<double>::const_iterator j=i;j!=i+step;j++) {
217 //#ifdef FSMWMODE1DFINDER_DEBUG
218 //if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "In the single interval, the component number unknown, value: " << j->first << " weight "
219 //<< j->second << endmsg;
220 //#endif
221 //overallweight+=j->second;
222 //}
223 if ((*(i+step-1)-*i)<last_value) {
224#ifdef FSMWMODE1DFINDER_DEBUG
225 msg(MSG::DEBUG) << "New value: " << *(i+step-1)-*i << " while the previous one was " <<
226 last_value << endmsg;
227 if(msgLvl(MSG::VERBOSE)) msg(MSG::VERBOSE) << "Best case since ever now" << endmsg;
228#endif
229 last_value=*(i+step-1)-*i;
230 best_begin=i;
231 best_end=i+step-1;
232 }
233 }
234
235#ifdef FSMWMODE1DFINDER_DEBUG
236 if(msgLvl(MSG::DEBUG)) msg(MSG::DEBUG) << "Ended a cycle with success" << endmsg;
237#endif
238
239 //assign the new begin and end...
240 begin=best_begin;
241 end=best_end;
242 last_value=1e100;
243
244 //Now it should have returned the value with smallest (x2-x1)/weight
245 if (best_end-best_begin<=2) isthelast=true;
246 }
247
248 if (best_end-best_begin==2)
249 {
250 std::vector<double>::const_iterator medium=begin;
251 ++medium;
252 return (*begin+*medium+*end)/3.;
253 }
254
255 //return the weighted mean of the best_begin and best_end
256 return (*begin+*end)/2.;
257
258
259 }
260}
261
262
#define endmsg
#define ATH_MSG_ERROR(x)
AthAlgTool(const std::string &type, const std::string &name, const IInterface *parent)
Constructor with parameters:
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
bool msgLvl(const MSG::Level lvl) const
MsgStream & msg() const
virtual ~FsmwMode1dFinder()
FsmwMode1dFinder(const std::string &t, const std::string &n, const IInterface *p)
virtual double getMode(std::vector< DoubleAndWeight >) const override final
Ensure that the ATLAS eigen extensions are properly loaded.
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.