Cheetah - SKA - PSS - Prototype Time Domain Search Pipeline
PacketGenerator.cpp
1 /*
2  * The MIT License (MIT)
3  *
4  * Copyright (c) 2016 The SKA organisation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in all
14  * copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22  * SOFTWARE.
23  */
24 #include "cheetah/rcpt_low/PacketGenerator.h"
25 #include "panda/Log.h"
26 
27 
28 namespace ska {
29 namespace cheetah {
30 namespace rcpt_low {
31 
32 
33 template<typename DataGenerator>
34 PacketGenerator<DataGenerator>::PacketGenerator(DataGenerator& model
35  ,PacketGeneratorConfig const& config
36  )
37  : _model(model)
38  , _data(config.number_of_spectra(), config.number_of_channels())
39  , _data_iterator(_data.cend())
40  , _counter(0)
41  , _interval(config.interval())
42  , _max_buffers(5)
43  , _buffer_index(0)
44  , _number_of_samples_per_packet(config.number_of_spectra())
45  , _number_of_channels_per_packet(config.number_of_channels_per_packet())
46  , _bandwidth(config.bandwidth())
47  , _fch1(config.fch1())
48 {
49  _buffers.reserve(_max_buffers);
50  for(unsigned i=0; i < _max_buffers; ++i) {
51  _buffers.emplace_back(Packet::size());
52  }
53  _timestamp = ska::cheetah::utils::ModifiedJulianClock::now();
54  _tsamp = ((double)config.number_of_channels()/static_cast<PacketGenerator<DataGenerator>::FrequencyType>(config.bandwidth()).value())*1e-6*data::seconds;
55 }
56 
57 template<typename DataGenerator>
58 PacketGenerator<DataGenerator>::~PacketGenerator()
59 {
60 }
61 
62 template<typename DataGenerator>
63 ska::panda::Buffer<char> PacketGenerator<DataGenerator>::next()
64 {
65  typedef Packet::PacketType PacketType;
66  ska::panda::Buffer<char>& buffer = _buffers[++_buffer_index%_max_buffers];
67 
68  char* ptr = buffer.data();
69  auto packet = new(ptr) Packet; // placement new
70 
71  // fill the packet header.
72  packet->packet_count(_counter/(number_of_channels_low/_number_of_channels_per_packet));
73  packet->first_channel_number((_counter%(number_of_channels_low/_number_of_channels_per_packet))*_number_of_channels_per_packet);
74  packet->packet_type(PacketType::PssLow); // Packet type
75  packet->magic_word(25146554); // consitancy check (MAGICBEED)
76  if(packet->first_channel_number()==0)
77  _timestamp = _timestamp + (_number_of_samples_per_packet * _tsamp);
78  static const std::chrono::time_point<std::chrono::system_clock> system_epoch;
79  static const auto epoch_secs = std::chrono::time_point_cast<std::chrono::seconds>(ska::cheetah::utils::ModifiedJulianClock::time_point(system_epoch));
80  auto secs = std::chrono::time_point_cast<std::chrono::seconds>(_timestamp);
81  auto ns = std::chrono::time_point_cast<std::chrono::nanoseconds>(_timestamp) - std::chrono::time_point_cast<std::chrono::nanoseconds>(secs);
82  struct timespec ts{secs.time_since_epoch().count()-epoch_secs.time_since_epoch().count(), ns.count()};
83  unsigned seconds = (unsigned)(ts.tv_sec);
84  uint64_t attoseconds = (uint64_t)(ts.tv_nsec*1e9);
85 
86  packet->timestamp_seconds(seconds);
87  packet->timestamp_attoseconds(attoseconds);
88  packet->set_unit_weights();
89  packet->channel_separation((uint32_t)((static_cast<PacketGenerator<DataGenerator>::FrequencyType>(_bandwidth).value()/(double)number_of_channels_low)*1e9));
90  packet->first_channel_frequency(_fch1);
91  for (unsigned i = 0; i < Packet::number_of_samples(); ++i) {
92  if(_data_iterator == _data.cend())
93  {
94  // get next chunk of data from the model
95  _model.next(_data);
96  _data_iterator = _data.cbegin();
97  }
98 
99  // Fill the packet data.
100  packet->insert(i, Sample( *_data_iterator, *_data_iterator));
101  ++_data_iterator;
102  }
103  // Increment counters for next time.
104  ++_counter;
105  return buffer;
106 }
107 
108 template<typename DataGenerator>
109 std::chrono::microseconds PacketGenerator<DataGenerator>::interval() const
110 {
111  return _interval;
112 }
113 
114 template<typename DataGenerator>
116 {
117 }
118 
119 } // namespace rcpt_low
120 } // namespace cheetah
121 } // namespace ska
static constexpr std::size_t size()
the total size of the packet (header + payload + footer)
Packs data into a UDP stream Packet Header format of the BeamFormer.
Some limits and constants for FLDO.
Definition: Brdz.h:35
static constexpr std::size_t number_of_samples()
the total number of samples in the rcpt payload