EMANE  1.2.1
spectrumwindowutils.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014 - Adjacent Link LLC, Bridgewater, New Jersey
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * * Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in
13  * the documentation and/or other materials provided with the
14  * distribution.
15  * * Neither the name of Adjacent Link LLC nor the names of its
16  * contributors may be used to endorse or promote products derived
17  * from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
25  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
27  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
29  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
35 
37 
38 #include <algorithm>
39 
40 std::pair<double,bool> EMANE::Utils::maxBinNoiseFloorRange(const SpectrumWindow & window,
41  double dRxPowerdBm,
42  const TimePoint & startTime,
43  const TimePoint & endTime)
44 {
45  const auto & noiseData = std::get<0>(window);
46  const TimePoint & windowStartTime = std::get<1>(window);
47  const Microseconds & binSize = std::get<2>(window);
48  const double & dRxSensitivityMilliWatt = std::get<3>(window);
49  const bool & bSignalInNoise{std::get<4>(window)};
50 
51  Microseconds::rep windowStartBin{timepointToAbsoluteBin(windowStartTime,binSize,false)};
52 
53  std::size_t startIndex{};
54  std::size_t endIndex{noiseData.size()-1};
55 
56  if(startTime < windowStartTime)
57  {
58  throw makeException<SpectrumServiceException>("max bin start time < window start time");
59  }
60  else
61  {
62  startIndex = timepointToAbsoluteBin(startTime,binSize,false) - windowStartBin;
63  }
64 
65  if(endTime != TimePoint::min())
66  {
67  if(endTime < startTime)
68  {
69  throw makeException<SpectrumServiceException>("max bin end time < max bin start time");
70  }
71  else
72  {
73  endIndex = timepointToAbsoluteBin(endTime,binSize,true) - windowStartBin;
74  }
75  }
76 
77  return maxBinNoiseFloor(noiseData,dRxSensitivityMilliWatt,dRxPowerdBm,bSignalInNoise,startIndex,endIndex);
78 }
79 
80 std::pair<double,bool> EMANE::Utils::maxBinNoiseFloor(const SpectrumWindow & window,
81  double dRxPowerdBm,
82  const TimePoint & startTime)
83 {
84  const auto & noiseData = std::get<0>(window);
85  const TimePoint & windowStartTime = std::get<1>(window);
86  const Microseconds & binSize = std::get<2>(window);
87  const double & dRxSensitivityMilliWatt = std::get<3>(window);
88  const bool & bSignalInNoise{std::get<4>(window)};
89 
90  Microseconds::rep windowStartBin{timepointToAbsoluteBin(windowStartTime,binSize,false)};
91 
92  std::size_t startIndex{};
93  std::size_t endIndex{noiseData.size()-1};
94 
95  if(startTime != TimePoint::min())
96  {
97  if(startTime < windowStartTime)
98  {
99  throw makeException<SpectrumServiceException>("max bin start time %13.6f < window start time %13.6f",
100  std::chrono::duration_cast<DoubleSeconds>(startTime.time_since_epoch()).count(),
101  std::chrono::duration_cast<DoubleSeconds>(windowStartTime.time_since_epoch()).count());
102  }
103  else
104  {
105  startIndex = timepointToAbsoluteBin(startTime,binSize,false) - windowStartBin;
106  }
107  }
108 
109  return maxBinNoiseFloor(noiseData,dRxSensitivityMilliWatt,dRxPowerdBm,bSignalInNoise,startIndex,endIndex);
110 }
111 
112 std::pair<double,bool> EMANE::Utils::maxBinNoiseFloor(const std::vector<double> & noiseData,
113  double dRxSensitivityMilliWatt,
114  double dRxPowerdBm,
115  bool bSignalInNoise,
116  std::size_t startBin,
117  std::size_t endBin)
118 {
119  if(endBin < startBin)
120  {
121  throw makeException<SpectrumServiceException>("max bin end index %zu < max bin start index %zu,"
122  " num bins %zu",
123  startBin,
124  endBin,
125  noiseData.size());
126  }
127  else if(endBin >= noiseData.size() || startBin >= noiseData.size())
128  {
129  throw makeException<SpectrumServiceException>("bin index out of range, start index %zu,"
130  " end index %zu, num bins %zu",
131  startBin,
132  endBin,
133  noiseData.size());
134  }
135 
136  double dNoiseFloorMilliWatt{*std::max_element(&noiseData[startBin],&noiseData[endBin+1])};
137 
138  if(bSignalInNoise)
139  {
140  dNoiseFloorMilliWatt -= Utils::DB_TO_MILLIWATT(dRxPowerdBm);
141  }
142 
143  if(dNoiseFloorMilliWatt < dRxSensitivityMilliWatt)
144  {
145  dNoiseFloorMilliWatt = dRxSensitivityMilliWatt;
146  }
147 
148  return {Utils::MILLIWATT_TO_DB(dNoiseFloorMilliWatt),bSignalInNoise};
149 }
150 
151 EMANE::Microseconds::rep EMANE::Utils::timepointToAbsoluteBin(const TimePoint & tp,
152  const Microseconds & binSize,
153  bool bAdjust)
154 {
155  auto count =
156  std::chrono::duration_cast<Microseconds>(tp.time_since_epoch()).count();
157 
158  // times that fall on a bin boundary belong to the previous bin
159  // (count % binSizeMicroseconds_ == 0) will evaluate to 0 or 1
160  return count == 0 ? 0 : count / binSize.count() - (bAdjust && (count % binSize.count() == 0));
161 }
162 
164 EMANE::Utils::spectrumCompress(const std::vector<double> & window)
165 {
167 
168  double fPrevious{};
169 
170  std::size_t i{};
171 
172  for(const auto & entry : window)
173  {
174  if(fPrevious != entry || (ret.empty() && entry != 0))
175  {
176  ret.push_back(std::make_pair(i,entry));
177  fPrevious = entry;
178  }
179 
180  ++i;
181  }
182 
183  return ret;
184 }
SpectrumCompressedRepresentation spectrumCompress(const std::vector< double > &window)
double MILLIWATT_TO_DB(double dMillWatt)
std::tuple< std::vector< double >, TimePoint, Microseconds, double, bool > SpectrumWindow
std::pair< double, bool > maxBinNoiseFloorRange(const SpectrumWindow &window, double dRxPowerdBm, const TimePoint &startTime, const TimePoint &endTime=TimePoint::min())
Microseconds::rep timepointToAbsoluteBin(const TimePoint &timePoint, const Microseconds &binSize, bool bAdjust)
std::vector< std::pair< std::size_t, float > > SpectrumCompressedRepresentation
std::chrono::microseconds Microseconds
Definition: types.h:45
std::chrono::duration< double > DoubleSeconds
Definition: types.h:47
std::pair< double, bool > maxBinNoiseFloor(const SpectrumWindow &window, double dRxPowerdBm, const TimePoint &startTime=TimePoint::min())
double DB_TO_MILLIWATT(double ddB)
Clock::time_point TimePoint
Definition: types.h:50