Program Listing for File spatialfilter.cpp

Return to documentation for file (processors/spatialfilter/spatialfilter.cpp)

// ---------------------------------------------------------------------
// This file is part of falcon-core.
//
// Copyright (C) 2015, 2016, 2017 Neuro-Electronics Research Flanders
//
// Falcon-server is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Falcon-server is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with falcon-core. If not, see <http://www.gnu.org/licenses/>.
// ---------------------------------------------------------------------

#include "spatialfilter.hpp"

#include <chrono>
#include <exception>
#include <string>

SpatialFilter::SpatialFilter() : IProcessor() {}

void SpatialFilter::CreatePorts() {
  data_in_port_ = create_input_port<TimeSeriesType<double>>(
      "data", TimeSeriesType<double>::Capabilities(ChannelRange(1, std::numeric_limits<uint32_t>::max())),
      PortInPolicy(SlotRange(0, std::numeric_limits<uint16_t>::max())));

  data_out_port_ = create_output_port<TimeSeriesType<double>>(
      "data", TimeSeriesType<double>::Parameters(),
              PortOutPolicy(SlotRange(0, std::numeric_limits<uint16_t>::max())));
}

void SpatialFilter::CompleteStreamInfo() {
  // check if we have the same number of input and output slots
  if (data_in_port_->number_of_slots() != data_out_port_->number_of_slots()) {
    auto err_msg = "Number of output slots (" +
                   std::to_string(data_out_port_->number_of_slots()) +
                   ") on port '" + data_out_port_->name() +
                   "' does not match number of input slots (" +
                   std::to_string(data_in_port_->number_of_slots()) +
                   ") on port '" + data_in_port_->name() + "'.";
    throw ProcessingStreamInfoError(err_msg, name());

  }

  for (int k = 0; k < data_in_port_->number_of_slots(); ++k) {
    data_out_port_->streaminfo(k).set_stream_parameters(
        data_in_port_->streaminfo(k));

    data_out_port_->streaminfo(k).set_parameters(
        data_in_port_->prototype(k).parameters());
    }

}

void SpatialFilter::Process(ProcessingContext &context) {
  TimeSeriesType<double>::Data *data_in = nullptr;
  TimeSeriesType<double>::Data *data_out = nullptr;
  auto nslots = data_in_port_->number_of_slots();
  double sum;

  while (!context.terminated()) {

    for (unsigned int k = 0; k < nslots; ++k) {
      if (!data_in_port_->slot(k)->RetrieveData(data_in)) {
        break;
      }
      // claim output data buckets
      data_out = data_out_port_->slot(k)->ClaimData(false);
        // Global CAR
        for(unsigned int sample=0; sample<data_in->nsamples(); sample++){
               sum = std::accumulate(data_in->begin_sample(sample),data_in->end_sample(sample), 0);
               sum = sum/data_in->ncolumns();
               std::transform(data_in->begin_sample(sample),data_in->end_sample(sample),
                              data_out->begin_sample(sample),
                              [sum](auto& value){return value-sum;});
        }
      data_out->set_sample_timestamps(data_in->sample_timestamps());
      data_out->set_hardware_timestamp(data_in->hardware_timestamp());
      data_out->set_source_timestamp();

      // publish and release data
      data_out_port_->slot(k)->PublishData();
      data_in_port_->slot(k)->ReleaseData();
    }
  }
}

REGISTERPROCESSOR(SpatialFilter)