text: /*****************************************
  @file
  @brief Stage for splitting visibility data by frequency.
  - freqSplit : public kotekan::Stage
  *****************************************/
  #ifndef FREQ_SPLIT_HPP
  #define FREQ_SPLIT_HPP
  
  #include "Config.hpp"
  #include "Stage.hpp" // for Stage
  #include "buffer.h"
  #include "bufferContainer.hpp"
  #include "dataset.hpp" // for dset_id_t
  
  #include <array>   // for array
  #include <future>  // for future
  #include <string>  // for string
  #include <utility> // for pair
  #include <vector>  // for vector
  
  
  /**
   * @class freqSplit
   * @brief Separate a VisBuffer stream into two by selecting frequencies in the upper and lower
   * half of the band.
   *
   * This task takes data coming out of a VisBuffer stream and separates it into
   * two streams. It selects which frames to copy to which buffer by assigning
   * frequencies in the upper and lower half of the CHIME band to different buffer
   * streams.
   *
   * @par Buffers
   * @buffer in_buf The buffer to be split
   *         @buffer_format VisBuffer structured
   *         @buffer_metadata VisMetadata
   * @buffer out_bufs The two buffers containing the respective upper or lower band frequencies
   *         @buffer_format VisBuffer structured
   *         @buffer_metadata VisMetadata
   *
   * @conf split_freq             Double. Frequency to split the incoming buffer
   *                              at. Lower frequencies got to the first output
   *                              buffer, equal and higher frequencies go to the
   *                              second. Default 512.
   *
   * @todo Generalise to arbitary frequency splits.
   * @author Mateus Fandino
   */
  class freqSplit : public kotekan::Stage {
  
  public:
      // Default constructor
      freqSplit(kotekan::Config& config, const std::string& unique_name,
                kotekan::bufferContainer& buffer_container);
  
      // Main loop for the stage
      void main_thread() override;
  
  private:
      /// adds states and datasets and gets new output dataset IDs from manager
      std::array<dset_id_t, 2> change_dataset_state(dset_id_t input_dset_id);
  
      // Vector of the buffers we are using and their current frame ids.
      std::vector<std::pair<Buffer*, unsigned int>> out_bufs;
      Buffer* in_buf;
  
      std::future<std::array<dset_id_t, 2>> _output_dset_id;
  
      // config values
      double _split_freq;
  };
  
  
  #endif
  