satellite-input-fstream-time-double-container.cc
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2013 Magister Solutions Ltd.
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License version 2 as
7  * published by the Free Software Foundation;
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17  *
18  * Author: Frans Laakso <frans.laakso@magister.fi>
19  */
20 
22 
23 #include "ns3/abort.h"
24 #include "ns3/log.h"
25 #include "ns3/simulator.h"
26 
27 NS_LOG_COMPONENT_DEFINE("SatInputFileStreamTimeDoubleContainer");
28 
29 namespace ns3
30 {
31 
32 TypeId
34 {
35  static TypeId tid = TypeId("ns3::SatInputFileStreamTimeDoubleContainer")
36  .SetParent<Object>()
37  .AddConstructor<SatInputFileStreamTimeDoubleContainer>();
38  return tid;
39 }
40 
42  std::string filename,
43  std::ios::openmode filemode,
44  uint32_t valuesInRow)
45  : m_inputFileStreamWrapper(),
46  m_inputFileStream(),
47  m_container(),
48  m_fileName(filename),
49  m_fileMode(filemode),
50  m_valuesInRow(valuesInRow),
51  m_lastValidPosition(0),
52  m_numOfPasses(0),
53  m_timeShiftValue(0),
54  m_timeColumn(0)
55 {
56  NS_LOG_FUNCTION(this << m_fileName << m_fileMode);
57 
59 }
60 
62  : m_inputFileStreamWrapper(),
63  m_inputFileStream(),
64  m_container(),
65  m_fileName(),
66  m_fileMode(),
67  m_valuesInRow(),
68  m_lastValidPosition(),
69  m_numOfPasses(),
70  m_timeShiftValue(),
71  m_timeColumn()
72 {
73  NS_LOG_FUNCTION(this);
74  NS_FATAL_ERROR("SatInputFileStreamTimeDoubleContainer::SatInputFileStreamTimeDoubleContainer - "
75  "Constructor not in use");
76 }
77 
79 {
80  NS_LOG_FUNCTION(this);
81 
82  Reset();
83 }
84 
85 void
87 {
88  NS_LOG_FUNCTION(this);
89 
90  Reset();
91  Object::DoDispose();
92 }
93 
94 void
96  std::ios::openmode filemode,
97  uint32_t valuesInRow)
98 {
99  NS_LOG_FUNCTION(this);
100 
101  ClearContainer();
102 
103  m_fileName = filename;
104  m_fileMode = filemode;
105  m_valuesInRow = valuesInRow;
106 
107  m_inputFileStreamWrapper = new SatInputFileStreamWrapper(filename, filemode);
109 
110  if (m_inputFileStream->is_open())
111  {
112  std::vector<double> tempVector = ReadRow();
113 
114  while (!m_inputFileStream->eof())
115  {
116  m_container.push_back(tempVector);
117  tempVector = ReadRow();
118  }
119  m_inputFileStream->close();
120  }
121  else
122  {
123  NS_ABORT_MSG("Input stream is not valid for reading.");
124  }
125 
127 
128  ResetStream();
129 }
130 
131 std::vector<double>
133 {
134  NS_LOG_FUNCTION(this);
135 
136  double tempValue;
137  std::vector<double> tempVector;
138 
139  for (uint32_t i = 0; i < m_valuesInRow; i++)
140  {
141  *m_inputFileStream >> tempValue;
142  tempVector.push_back(tempValue);
143  }
144  return tempVector;
145 }
146 
147 void
149 {
150  NS_LOG_FUNCTION(this);
151 
153  if (m_container.size() < 1)
154  {
155  NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Empty file");
156  }
157  else if (m_container.size() == 1)
158  {
159  if (m_container[m_container.size() - 1].at(m_timeColumn) == 0)
160  {
161  NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Invalid input "
162  "file format (time sample error)");
163  }
164  }
165  else
166  {
167  double tempValue1 = m_container[0].at(m_timeColumn);
168 
169  for (uint32_t i = 1; i < m_container.size(); i++)
170  {
171  if (tempValue1 > m_container[i].at(m_timeColumn))
172  {
173  NS_FATAL_ERROR("SatInputFileStreamDoubleContainer::UpdateContainer - Invalid input "
174  "file format (time sample error)");
175  }
176  tempValue1 = m_container[i].at(m_timeColumn);
177  }
178  }
179 }
180 
181 std::vector<double>
183 {
184  NS_LOG_FUNCTION(this);
185 
186  while (!FindNextClosest(m_lastValidPosition, m_timeShiftValue, Now().GetSeconds()))
187  {
189  m_numOfPasses++;
191 
192  NS_LOG_INFO("Looping samples again with shift value: " << m_timeShiftValue);
193  }
194 
195  if (m_numOfPasses > 0)
196  {
197  std::cout
198  << "WARNING! - SatInputFileStreamDoubleContainer::ProceedToNextClosestTimeSample for "
199  << m_fileName << " is out of samples @ time sample " << Now().GetSeconds()
200  << " (passes " << m_numOfPasses << ")" << std::endl;
201  std::cout << "The container will loop samples from the beginning." << std::endl;
202  }
203 
205 }
206 
207 std::vector<double>
209 {
210  NS_LOG_FUNCTION(this);
211 
212  double currentTime = Now().GetSeconds();
214 
215  std::vector<double> selectedPosition = m_container[m_lastValidPosition];
216  double selectedTime = selectedPosition.at(m_timeColumn);
217 
218  // Easy case: a time sample for the current time exist
219  if (selectedTime == currentTime)
220  {
221  return selectedPosition;
222  }
223 
224  // Fetch the second position to perform linear interpolation
225  std::vector<double> closestPosition;
226  if (selectedTime > currentTime)
227  {
228  if (m_lastValidPosition == 0)
229  {
230  // No previous position available, abort
231  return selectedPosition;
232  }
233  closestPosition = m_container[m_lastValidPosition - 1];
234  }
235  else
236  {
237  if (m_lastValidPosition == m_container.size() - 1)
238  {
239  // No next position available, abort
240  return selectedPosition;
241  }
242  closestPosition = m_container[m_lastValidPosition + 1];
243  }
244 
245  double linearCoefficient =
246  (currentTime - selectedTime) / (closestPosition.at(m_timeColumn) - selectedTime);
247  std::size_t rowSize = selectedPosition.size();
248  std::vector<double> interpolatedPosition(rowSize);
249  for (std::size_t i = 0; i < rowSize; ++i)
250  {
251  interpolatedPosition[i] =
252  selectedPosition[i] + linearCoefficient * (closestPosition[i] - selectedPosition[i]);
253  }
254 
255  return interpolatedPosition;
256 }
257 
258 bool
260  double timeShiftValue,
261  double comparisonTimeValue)
262 {
263  NS_LOG_FUNCTION(this);
264 
265  NS_ASSERT(m_timeColumn < m_valuesInRow);
266  NS_ASSERT(m_container.size() > 0);
267  NS_ASSERT(lastValidPosition >= 0 && lastValidPosition < m_container.size());
268 
269  NS_LOG_INFO("LastValidPosition " << lastValidPosition << " column " << m_timeColumn
270  << " timeShiftValue " << timeShiftValue
271  << " comparisonTimeValue " << comparisonTimeValue);
272 
273  bool valueFound = false;
274 
275  for (uint32_t i = lastValidPosition; i < m_container.size(); i++)
276  {
277  if (m_container[i].at(m_timeColumn) + timeShiftValue >= comparisonTimeValue)
278  {
279  double difference1 = std::abs(m_container[lastValidPosition].at(m_timeColumn) +
280  timeShiftValue - comparisonTimeValue);
281  double difference2 =
282  std::abs(m_container[i].at(m_timeColumn) + timeShiftValue - comparisonTimeValue);
283 
284  if (difference1 < difference2)
285  {
286  m_lastValidPosition = lastValidPosition;
287  }
288  else
289  {
291  }
292  valueFound = true;
293  break;
294  }
295  lastValidPosition = i;
296  }
297 
298  if (valueFound && m_numOfPasses > 0 && m_lastValidPosition == 0)
299  {
300  double difference1 = std::abs(m_container[m_lastValidPosition].at(m_timeColumn) +
301  timeShiftValue - comparisonTimeValue);
302  double difference2 =
303  std::abs(m_container[m_container.size() - 1].at(m_timeColumn) +
304  ((m_numOfPasses - 1) * m_container[m_container.size() - 1].at(m_timeColumn)) -
305  comparisonTimeValue);
306 
307  if (difference1 > difference2)
308  {
309  m_lastValidPosition = m_container.size() - 1;
310  m_numOfPasses--;
312  }
313  }
314 
315  NS_LOG_INFO("Done: " << valueFound
316  << " value: " << m_container[m_lastValidPosition].at(m_timeColumn)
317  << " @ line: " << m_lastValidPosition + 1 << " comparison time value: "
318  << comparisonTimeValue << " passes: " << m_numOfPasses);
319 
320  return valueFound;
321 }
322 
323 void
325 {
326  NS_LOG_FUNCTION(this);
327 
328  ResetStream();
329  ClearContainer();
330 }
331 
332 void
334 {
335  NS_LOG_FUNCTION(this);
336 
337  if (m_inputFileStreamWrapper != NULL)
338  {
341  }
342  m_inputFileStream = 0;
343 }
344 
345 void
347 {
348  NS_LOG_FUNCTION(this);
349 
350  if (!m_container.empty())
351  {
352  for (uint32_t i = 0; i < m_container.size(); i++)
353  {
354  if (!m_container[i].empty())
355  {
356  m_container[i].clear();
357  }
358  }
359  m_container.clear();
360  }
361 
362  m_valuesInRow = 0;
364  m_numOfPasses = 0;
365  m_timeShiftValue = 0;
366 }
367 
368 } // namespace ns3
bool FindNextClosest(uint32_t lastValidPosition, double timeShiftValue, double comparisonTimeValue)
Function for locating the next closest value index.
std::vector< std::vector< double > > m_container
Container for value rows.
uint32_t m_timeColumn
Index for column which contains time information.
std::vector< double > ReadRow()
Function for reading a row from file.
SatInputFileStreamWrapper * m_inputFileStreamWrapper
Pointer to input file stream wrapper.
std::vector< double > ProceedToNextClosestTimeSample()
Function for locating the next closest time sample and returning the values related to it.
uint32_t m_numOfPasses
Number for how many times the available samples have been looped over.
void UpdateContainer(std::string filename, std::ios::openmode filemode, uint32_t valuesInRow)
Function for updating the container.
std::vector< double > InterpolateBetweenClosestTimeSamples()
Function for locating time samples enclosing the current time and a linear interpolation between thes...
A class encapsulating an STL input stream.
std::ifstream * GetStream(void)
Return a pointer to an ifstream previously set in the wrapper.
SatArqSequenceNumber is handling the sequence numbers for the ARQ process.