GatedSpectrometer_cli.cu 9.29 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include "boost/program_options.hpp"
#include "psrdada_cpp/cli_utils.hpp"
#include "psrdada_cpp/common.hpp"
#include "psrdada_cpp/dada_input_stream.hpp"
#include "psrdada_cpp/dada_null_sink.hpp"
#include "psrdada_cpp/dada_output_stream.hpp"
#include "psrdada_cpp/multilog.hpp"
#include "psrdada_cpp/simple_file_writer.hpp"

#include "psrdada_cpp/effelsberg/edd/GatedSpectrometer.cuh"

#include <ctime>
#include <iostream>
#include <time.h>


using namespace psrdada_cpp;


namespace {
const size_t ERROR_IN_COMMAND_LINE = 1;
const size_t SUCCESS = 0;
const size_t ERROR_UNHANDLED_EXCEPTION = 2;
} // namespace


27
28
29
30
31
32


template<typename T,
         class InputType,
         class OutputType
    >
Tobias Winchen's avatar
Tobias Winchen committed
33
void launchSpectrometer(const effelsberg::edd::GatedSpectrometerInputParameters &i, const std::string &filename, const std::string &output_type)
34
35
{

36
    MultiLog log("DadaBufferLayout");
Tobias Winchen's avatar
Tobias Winchen committed
37
38
    std::cout << "Running with output_type: " << output_type << std::endl;
    if (output_type == "file")
39
    {
Tobias Winchen's avatar
Tobias Winchen committed
40
      SimpleFileWriter sink(filename);
41
      effelsberg::edd::GatedSpectrometer<decltype(sink), InputType, OutputType>
Tobias Winchen's avatar
Tobias Winchen committed
42
          spectrometer(i, sink);
43

44
      DadaInputStream<decltype(spectrometer)> istream(i.dadaBufferLayout.getInputkey(), log,
45
46
47
                                                      spectrometer);
      istream.start();
    }
Tobias Winchen's avatar
Tobias Winchen committed
48
    else if (output_type == "dada")
49
    {
Tobias Winchen's avatar
Tobias Winchen committed
50
51
52
      DadaOutputStream sink(string_to_key(filename), log);
      effelsberg::edd::GatedSpectrometer<decltype(sink), InputType, OutputType>
          spectrometer(i, sink);
53

54
      DadaInputStream<decltype(spectrometer)> istream(i.dadaBufferLayout.getInputkey(), log,
55
56
      spectrometer);
      istream.start();
57
    }
Tobias Winchen's avatar
Tobias Winchen committed
58
     else if (output_type == "profile")
59
60
    {
      NullSink sink;
Tobias Winchen's avatar
Tobias Winchen committed
61
62
      effelsberg::edd::GatedSpectrometer<decltype(sink),  InputType, OutputType>
          spectrometer(i, sink);
63

64
65
      std::vector<char> buffer(i.dadaBufferLayout.getBufferSize());
      cudaHostRegister(buffer.data(), buffer.size(), cudaHostRegisterPortable);
66
67
68
69
70
71
72
73
      RawBytes ib(buffer.data(), buffer.size(), buffer.size());
      spectrometer.init(ib);
      for (int i =0; i< 10; i++)
      {
        std::cout << "Profile Block: "<< i +1 << std::endl;
        spectrometer(ib);
      }

74
75
76
77
78
79
80
    }
    else
    {
      throw std::runtime_error("Unknown oputput-type");
    }
}

Tobias Winchen's avatar
Tobias Winchen committed
81

Tobias Winchen's avatar
Tobias Winchen committed
82
template<typename T> void io_eval(const effelsberg::edd::GatedSpectrometerInputParameters &inputParameters, const std::string &input_polarizations, const std::string &output_format, const std::string &filename, const std::string &output_type)
83
84
85
86
{
    if (input_polarizations == "Single" && output_format == "Power")
    {
        launchSpectrometer<T, effelsberg::edd::SinglePolarizationInput,
Tobias Winchen's avatar
Tobias Winchen committed
87
            effelsberg::edd::GatedPowerSpectrumOutput>(inputParameters, filename, output_type);
88
89
90
91
92
93
94
95
    }
    else if (input_polarizations == "Dual" && output_format == "Power")
    {
       throw std::runtime_error("Not implemented yet.");
    }
    else if (input_polarizations == "Dual" && output_format == "Stokes")
    {
        launchSpectrometer<T, effelsberg::edd::DualPolarizationInput,
Tobias Winchen's avatar
Tobias Winchen committed
96
            effelsberg::edd::GatedFullStokesOutput>(inputParameters, filename, output_type);
97
98
99
100
101
102
103
104
105
106
107
    }
    else
    {
       throw std::runtime_error("Not implemented yet.");
    }

}




Tobias Winchen's avatar
Tobias Winchen committed
108

109
110
111
int main(int argc, char **argv) {
  try {
    key_t input_key;
112

Tobias Winchen's avatar
Tobias Winchen committed
113
    effelsberg::edd::GatedSpectrometerInputParameters ip;
114
115
    std::time_t now = std::time(NULL);
    std::tm *ptm = std::localtime(&now);
116
117
118
119
120
    char default_filename[32];
    std::strftime(default_filename, 32, "%Y-%m-%d-%H:%M:%S.bp", ptm);

    std::string input_polarizations = "Single";
    std::string output_format = "Power";
Tobias Winchen's avatar
Tobias Winchen committed
121
122
    std::string filename;
    std::string output_type;
123
124
125
126
127
128
129
130
131
132
133
134
    /** Define and parse the program options
    */
    namespace po = boost::program_options;
    po::options_description desc("Options");

    desc.add_options()("help,h", "Print help messages");
    desc.add_options()(
        "input_key,i",
        po::value<std::string>()->default_value("dada")->notifier(
            [&input_key](std::string in) { input_key = string_to_key(in); }),
        "The shared memory key for the dada buffer to connect to (hex "
        "string)");
Tobias Winchen's avatar
Tobias Winchen committed
135
    desc.add_options()(
Tobias Winchen's avatar
Tobias Winchen committed
136
        "output_type", po::value<std::string>(&output_type)->default_value("file"),
137
        "output type [dada, file, profile]. Default is file. Profile executes the spectrometer 10x on random data and passes the ouput to a null sink."
Tobias Winchen's avatar
Tobias Winchen committed
138
139
        );
    desc.add_options()(
Tobias Winchen's avatar
Tobias Winchen committed
140
        "output_key,o", po::value<std::string>(&filename)->default_value(default_filename),
Tobias Winchen's avatar
Tobias Winchen committed
141
142
143
        "The key of the output bnuffer / name of the output file to write spectra "
        "to");

144
145
146
147
148
149
150
151
    desc.add_options()(
        "input_polarizations,p", po::value<std::string>(&input_polarizations)->default_value(input_polarizations),
        "Single, Dual");
    desc.add_options()(
        "output_format,f", po::value<std::string>(&output_format)->default_value(output_format),
        "Power, Stokes (requires dual poalriation input)");


Tobias Winchen's avatar
Tobias Winchen committed
152
    desc.add_options()("nsidechannelitems,s",
Tobias Winchen's avatar
Tobias Winchen committed
153
                       po::value<size_t>()->default_value(1)->notifier(
154
                           [&ip](size_t in) { ip.nSideChannels = in; }),
Tobias Winchen's avatar
Tobias Winchen committed
155
                       "Number of side channel items ( s >= 1)");
156
    desc.add_options()(
Tobias Winchen's avatar
Tobias Winchen committed
157
        "selected_sidechannel,e",
158
        po::value<size_t>()->default_value(0)->notifier(
159
            [&ip](size_t in) { ip.selectedSideChannel = in; }),
160
        "Side channel selected for evaluation.");
Tobias Winchen's avatar
Tobias Winchen committed
161
    desc.add_options()("selected_bit,B",
162
                       po::value<size_t>()->default_value(0)->notifier(
163
                           [&ip](size_t in) { ip.selectedBit = in; }),
164
                       "Side channel selected for evaluation.");
Tobias Winchen's avatar
Tobias Winchen committed
165
    desc.add_options()("speadheap_size",
166
                       po::value<size_t>()->default_value(4096)->notifier(
167
                           [&ip](size_t in) { ip.speadHeapSize = in; }),
168
169
170
                       "size of the spead data heaps. The number of the "
                       "heaps in the dada block depends on the number of "
                       "side channel items.");
171
172

    desc.add_options()("nbits,b", po::value<unsigned int>(&ip.nbits)->required(),
173
                       "The number of bits per sample in the "
Tobias Winchen's avatar
Tobias Winchen committed
174
                       "packetiser output (8, 10 12)");
175
    desc.add_options()("fft_length,n", po::value<size_t>(&ip.fft_length)->required(),
Tobias Winchen's avatar
Tobias Winchen committed
176
177
                       "The length of the FFT to perform on the data");
    desc.add_options()("naccumulate,a",
178
                       po::value<size_t>(&ip.naccumulate)->required(),
Tobias Winchen's avatar
Tobias Winchen committed
179
                       "The number of samples to integrate in each channel");
180
181
182
183
184
    desc.add_options()("disable_gate,d",
                       po::value<uint8_t>()->notifier(
                           [&ip](size_t in) { ip.active_gates.set(in, false); }),
                       "Disable processing of ND state 0 or 1.");

185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
    desc.add_options()(
        "log_level", po::value<std::string>()->default_value("info")->notifier(
                         [](std::string level) { set_log_level(level); }),
        "The logging level to use "
        "(debug, info, warning, "
        "error)");

    po::variables_map vm;
    try {
      po::store(po::parse_command_line(argc, argv, desc), vm);
      if (vm.count("help")) {
        std::cout << "GatedSpectrometer -- Read EDD data from a DADA buffer "
                     "and split the data into two streams depending on a bit "
                     "set in the side channel data. On each stream a simple "
                     "FFT spectrometer is performed."
                  << std::endl
                  << desc << std::endl;
        return SUCCESS;
      }
Tobias Winchen's avatar
Tobias Winchen committed
204

205
      po::notify(vm);
Tobias Winchen's avatar
Tobias Winchen committed
206
      if (vm.count("output_type") && (!(output_type == "dada" || output_type == "file" || output_type== "profile") ))
Tobias Winchen's avatar
Tobias Winchen committed
207
      {
Tobias Winchen's avatar
Tobias Winchen committed
208
        throw po::validation_error(po::validation_error::invalid_option_value, "output_type", output_type);
Tobias Winchen's avatar
Tobias Winchen committed
209
      }
Tobias Winchen's avatar
Tobias Winchen committed
210

211
212
213
214
215
216
217
218
219
220
221
      if (vm.count("input_polarizations") && (!(input_polarizations == "Single" || input_polarizations == "Dual") ))
      {
        throw po::validation_error(po::validation_error::invalid_option_value, "input_polarizations", input_polarizations);
      }

      if (vm.count("output_format") && (!(output_format == "Power" || output_format == "Stokes") ))
      {
        throw po::validation_error(po::validation_error::invalid_option_value, "output_format", output_format);
      }

      if (!(ip.nSideChannels >= 1))
Tobias Winchen's avatar
Tobias Winchen committed
222
223
224
225
      {
        throw po::validation_error(po::validation_error::invalid_option_value, "Number of side channels must be 1 or larger!");
      }

226
227
228
229
230
231
    } catch (po::error &e) {
      std::cerr << "ERROR: " << e.what() << std::endl << std::endl;
      std::cerr << desc << std::endl;
      return ERROR_IN_COMMAND_LINE;
    }

232
233
234
235
236
237
    if ((output_format ==  "Stokes") && (input_polarizations != "Dual"))
    {
        throw po::validation_error(po::validation_error::invalid_option_value, "Stokes output requires dual polarization input!");
    }

    ip.dadaBufferLayout.intitialize(input_key, ip.speadHeapSize, ip.nSideChannels);
238

Tobias Winchen's avatar
Tobias Winchen committed
239
    io_eval<float>(ip, input_polarizations, output_format, filename, output_type );
Tobias Winchen's avatar
Tobias Winchen committed
240

241
242
243
244
245
246
247
248
  } catch (std::exception &e) {
    std::cerr << "Unhandled Exception reached the top of main: " << e.what()
              << ", application will now exit" << std::endl;
    return ERROR_UNHANDLED_EXCEPTION;
  }
  return SUCCESS;
}