A Discrete-Event Network Simulator
API
snr-to-block-error-rate-manager.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2007,2008, 2009 INRIA, UDcast
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation;
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * You should have received a copy of the GNU General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16  *
17  * Author: Mohamed Amine Ismail <amine.ismail@sophia.inria.fr>
18  * <amine.ismail@udcast.com>
19  */
20 
22 
23 #include "default-traces.h"
25 
26 #include "ns3/assert.h"
27 #include "ns3/log.h"
28 
29 #include <cstring>
30 #include <fstream>
31 #include <sstream>
32 
33 namespace ns3
34 {
35 
36 NS_LOG_COMPONENT_DEFINE("SNRToBlockErrorRateManager");
37 
39 {
40  for (int i = 0; i < 7; i++)
41  {
42  m_recordModulation[i] = new std::vector<SNRToBlockErrorRateRecord*>();
43  }
44  m_activateLoss = false;
45  m_traceFilePath = "DefaultTraces";
46 }
47 
49 {
50  ClearRecords();
51  for (int i = 0; i < 7; i++)
52  {
53  delete m_recordModulation[i];
54  }
55 }
56 
57 void
59 {
60  for (int i = 0; i < 7; i++)
61  {
62  for (auto iter = m_recordModulation[i]->begin(); iter != m_recordModulation[i]->end();
63  ++iter)
64  {
65  if (*iter)
66  {
67  delete (*iter);
68  (*iter) = 0;
69  }
70  }
71  m_recordModulation[i]->clear();
72  }
73 }
74 
75 void
77 {
78  m_activateLoss = loss;
79 }
80 
81 void
83 {
84  std::ifstream traceFile;
85  ClearRecords();
86  double snrValue;
87  double bitErrorRate;
88  double burstErrorRate;
89  double sigma2;
90  double I1;
91  double I2;
92 
93  for (int i = 0; i < 7; i++)
94  {
95  std::stringstream traceFilePath;
96  traceFilePath << m_traceFilePath << "/modulation" << i << ".txt";
97 
98  traceFile.open(traceFilePath.str(), std::ifstream::in);
99  if (!traceFile.good())
100  {
101  NS_LOG_INFO("Unable to load " << traceFilePath.str() << "!! Loading default traces...");
103  return;
104  }
105  while (traceFile.good())
106  {
107  traceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
108  auto record = new SNRToBlockErrorRateRecord(snrValue,
109  bitErrorRate,
110  burstErrorRate,
111  sigma2,
112  I1,
113  I2);
114  m_recordModulation[i]->push_back(record);
115  }
116  traceFile.close();
117  }
118  m_activateLoss = true;
119 }
120 
121 void
123 {
124  double snrValue;
125  double bitErrorRate;
126  double burstErrorRate;
127  double sigma2;
128  double I1;
129  double I2;
130  ClearRecords();
131  for (unsigned int j = 0; j < sizeof(modulation0[0]) / sizeof(double); j++)
132  {
133  snrValue = modulation0[0][j];
134  bitErrorRate = modulation0[1][j];
135  burstErrorRate = modulation0[2][j];
136  sigma2 = modulation0[3][j];
137  I1 = modulation0[4][j];
138  I2 = modulation0[5][j];
139  auto record =
140  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
141  m_recordModulation[0]->push_back(record);
142  }
143  for (unsigned int j = 0; j < sizeof(modulation1[0]) / sizeof(double); j++)
144  {
145  snrValue = modulation1[0][j];
146  bitErrorRate = modulation1[1][j];
147  burstErrorRate = modulation1[2][j];
148  sigma2 = modulation1[3][j];
149  I1 = modulation1[4][j];
150  I2 = modulation1[5][j];
151  auto record =
152  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
153  m_recordModulation[1]->push_back(record);
154  }
155  for (unsigned int j = 0; j < sizeof(modulation2[0]) / sizeof(double); j++)
156  {
157  snrValue = modulation2[0][j];
158  bitErrorRate = modulation2[1][j];
159  burstErrorRate = modulation2[2][j];
160  sigma2 = modulation2[3][j];
161  I1 = modulation2[4][j];
162  I2 = modulation2[5][j];
163  auto record =
164  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
165  m_recordModulation[2]->push_back(record);
166  }
167  for (unsigned int j = 0; j < sizeof(modulation3[0]) / sizeof(double); j++)
168  {
169  snrValue = modulation3[0][j];
170  bitErrorRate = modulation3[1][j];
171  burstErrorRate = modulation3[2][j];
172  sigma2 = modulation3[3][j];
173  I1 = modulation3[4][j];
174  I2 = modulation3[5][j];
175  auto record =
176  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
177  m_recordModulation[3]->push_back(record);
178  }
179  for (unsigned int j = 0; j < sizeof(modulation4[0]) / sizeof(double); j++)
180  {
181  snrValue = modulation4[0][j];
182  bitErrorRate = modulation4[1][j];
183  burstErrorRate = modulation4[2][j];
184  sigma2 = modulation4[3][j];
185  I1 = modulation4[4][j];
186  I2 = modulation4[5][j];
187  auto record =
188  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
189  m_recordModulation[4]->push_back(record);
190  }
191  for (unsigned int j = 0; j < sizeof(modulation5[0]) / sizeof(double); j++)
192  {
193  snrValue = modulation5[0][j];
194  bitErrorRate = modulation5[1][j];
195  burstErrorRate = modulation5[2][j];
196  sigma2 = modulation5[3][j];
197  I1 = modulation5[4][j];
198  I2 = modulation5[5][j];
199  auto record =
200  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
201  m_recordModulation[5]->push_back(record);
202  }
203  for (unsigned int j = 0; j < sizeof(modulation6[0]) / sizeof(double); j++)
204  {
205  snrValue = modulation6[0][j];
206  bitErrorRate = modulation6[1][j];
207  burstErrorRate = modulation6[2][j];
208  sigma2 = modulation6[3][j];
209  I1 = modulation6[4][j];
210  I2 = modulation6[5][j];
211  auto record =
212  new SNRToBlockErrorRateRecord(snrValue, bitErrorRate, burstErrorRate, sigma2, I1, I2);
213  m_recordModulation[6]->push_back(record);
214  }
215  m_activateLoss = true;
216 }
217 
218 void
220 {
221  double snrValue;
222  double bitErrorRate;
223  double burstErrorRate;
224  double sigma2;
225  double I1;
226  double I2;
227 
228  ClearRecords();
229 
230  std::ifstream traceFile;
231 
232  for (int i = 0; i < 7; i++)
233  {
234  std::stringstream traceFilePath;
235  traceFilePath << m_traceFilePath << "/Modulation" << i << ".txt";
236 
237  traceFile.open(traceFilePath.str(), std::ifstream::in);
238  if (!traceFile.good())
239  {
240  NS_LOG_INFO("Unable to load " << traceFilePath.str() << "!!Loading default traces...");
242  return;
243  }
244  while (traceFile.good())
245  {
246  traceFile >> snrValue >> bitErrorRate >> burstErrorRate >> sigma2 >> I1 >> I2;
247  auto record = new SNRToBlockErrorRateRecord(snrValue,
248  bitErrorRate,
249  burstErrorRate,
250  sigma2,
251  I1,
252  I2);
253 
254  m_recordModulation[i]->push_back(record);
255  }
256  traceFile.close();
257  }
258  m_activateLoss = true;
259 }
260 
261 void
263 {
264  m_traceFilePath = traceFilePath;
265 }
266 
267 std::string
269 {
270  return m_traceFilePath;
271 }
272 
273 double
274 SNRToBlockErrorRateManager::GetBlockErrorRate(double SNR, uint8_t modulation)
275 {
276  if (!m_activateLoss)
277  {
278  return 0;
279  }
280 
281  std::vector<SNRToBlockErrorRateRecord*>* record = nullptr;
282 
283  record = m_recordModulation[modulation];
284 
285  if (SNR <= (record->at(0)->GetSNRValue()))
286  {
287  return 1;
288  }
289  if (SNR >= (record->at(record->size() - 1)->GetSNRValue()))
290  {
291  return 0;
292  }
293 
294  unsigned int i;
295  for (i = 0; i < record->size(); i++)
296  {
297  if (SNR < record->at(i)->GetSNRValue())
298  {
299  break;
300  }
301  }
302  double intervalSize = (record->at(i)->GetSNRValue() - record->at(i - 1)->GetSNRValue());
303  double coeff1 = (SNR - record->at(i - 1)->GetSNRValue()) / intervalSize;
304  double coeff2 = -1 * (SNR - record->at(i)->GetSNRValue()) / intervalSize;
305  double BlockErrorRate = coeff2 * (record->at(i - 1)->GetBlockErrorRate()) +
306  coeff1 * (record->at(i)->GetBlockErrorRate());
307  return BlockErrorRate;
308 }
309 
312 {
313  if (!m_activateLoss)
314  {
315  return new SNRToBlockErrorRateRecord(SNR, 0, 0, 0, 0, 0);
316  }
317 
318  std::vector<SNRToBlockErrorRateRecord*>* record = nullptr;
319  record = m_recordModulation[modulation];
320 
321  if (SNR <= (record->at(0)->GetSNRValue()))
322  {
323  return record->at(0)->Copy();
324  }
325  if (SNR >= (record->at(record->size() - 1)->GetSNRValue()))
326  {
327  return record->at(record->size() - 1)->Copy();
328  }
329 
330  unsigned int i;
331  for (i = 0; i < record->size(); i++)
332  {
333  if (SNR < record->at(i)->GetSNRValue())
334  {
335  break;
336  }
337  }
338  double intervalSize = (record->at(i)->GetSNRValue() - record->at(i - 1)->GetSNRValue());
339  double coeff1 = (SNR - record->at(i - 1)->GetSNRValue()) / intervalSize;
340  double coeff2 = -1 * (SNR - record->at(i)->GetSNRValue()) / intervalSize;
341  double BER = coeff2 * (record->at(i - 1)->GetBitErrorRate()) +
342  coeff1 * (record->at(i)->GetBitErrorRate());
343  double BlcER = coeff2 * (record->at(i - 1)->GetBlockErrorRate()) +
344  coeff1 * (record->at(i)->GetBlockErrorRate());
345  double sigma2 =
346  coeff2 * (record->at(i - 1)->GetSigma2()) + coeff1 * (record->at(i)->GetSigma2());
347  double I1 = coeff2 * (record->at(i - 1)->GetI1()) + coeff1 * (record->at(i)->GetI1());
348  double I2 = coeff2 * (record->at(i - 1)->GetI2()) + coeff1 * (record->at(i)->GetI2());
349 
350  auto SNRToBlockErrorRate = new SNRToBlockErrorRateRecord(SNR, BER, BlcER, sigma2, I1, I2);
351  return SNRToBlockErrorRate;
352 }
353 
354 } // namespace ns3
void ActivateLoss(bool loss)
If activate loss is called with false, all the returned BlcER will be 0 (no losses)
static const double modulation5[6][547]
These represent default traces, providing a number of parameters for each SNR value.
static const double modulation1[6][42]
These represent default traces, providing a number of parameters for each SNR value.
void LoadTraces()
Loads the traces form the repository specified in the constructor or set by SetTraceFilePath function...
SNRToBlockErrorRateRecord * GetSNRToBlockErrorRateRecord(double SNR, uint8_t modulation)
returns a record of type SNRToBlockErrorRateRecord corresponding to a given modulation and SNR value
static const double modulation0[6][29]
These represent default traces, providing a number of parameters for each SNR value.
static const double modulation6[6][626]
These represent default traces, providing a number of parameters for each SNR value.
static const double modulation3[6][117]
These represent default traces, providing a number of parameters for each SNR value.
double GetBlockErrorRate(double SNR, uint8_t modulation)
returns the Block Error Rate for a given modulation and SNR value
void SetTraceFilePath(char *traceFilePath)
Set the path of the repository containing the traces.
static const double modulation2[6][96]
These represent default traces, providing a number of parameters for each SNR value.
std::vector< SNRToBlockErrorRateRecord * > * m_recordModulation[7]
record modulation
void LoadDefaultTraces()
Loads the default traces from default-traces.h file.
static const double modulation4[6][331]
These represent default traces, providing a number of parameters for each SNR value.
This class represents a record (handled by SnrToBlockErrorRate manager) that keeps a mapping between ...
#define NS_LOG_COMPONENT_DEFINE(name)
Define a Log component with a specific name.
Definition: log.h:202
#define NS_LOG_INFO(msg)
Use NS_LOG to output a message of level LOG_INFO.
Definition: log.h:275
Every class exported by the ns3 library is enclosed in the ns3 namespace.