<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGradientDescentOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/

#include <itkGradientDescentOptimizer.h>
#include <itkPoint.h>
#include <itkCovariantVector.h>

/**
 *  The objectif function is the quadratic form:
 *
 *  1/2 x^T A x - b^T x
 *
 *  Where A is a matrix and b is a vector
 *  The system in this example is:
 *
 *     | 3  2 ||x|   | 2|   |0|
 *     | 2  6 ||y| + |-8| = |0|
 *
 *
 *   the solution is the vector | 2 -2 |
 *
 */
class CostFunction : public itk::LightObject
{
public:

  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { SpaceDimension=2 };

  typedef itk::Point<  double, SpaceDimension >          ParametersType;

  typedef itk::CovariantVector< double, SpaceDimension > DerivativeType;

  typedef double MeasureType ;

  CostFunction()
  {
  }

  const ParametersType & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetValue( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Measure = 0.5*(3*x*x+4*x*y+6*y*y) - 2*x + 8*y;

    std::cout << m_Measure << std::endl;

    return m_Measure;

  }

  const DerivativeType & GetDerivative(
             const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetDerivative( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Derivative[0] = 3 * x + 2 * y -2;
    m_Derivative[1] = 2 * x + 6 * y +8;

    std::cout << m_Derivative << std::endl;

    return m_Derivative;
  }

  void GetValueAndDerivative( const ParametersType & parameters,
    MeasureType& value, DerivativeType& deriv ) const
  {
    value = this->GetValue( parameters );
    deriv = this->GetDerivative( parameters );
  }

private:

  mutable ParametersType  m_Parameters;
  mutable MeasureType     m_Measure;
  mutable DerivativeType  m_Derivative;

};

int main()
{
  std::cout << "Gradient Descent Optimizer Test ";
  std::cout << std::endl << std::endl;

  typedef  itk::GradientDescentOptimizer<
                                CostFunction >  OptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction costFunction;

  itkOptimizer->SetCostFunction( &costFunction );

   typedef CostFunction::ParametersType    ParametersType;

  // We start not so far from  | 2 -2 |
  ParametersType  initialPosition;
  initialPosition[0] =  100;
  initialPosition[1] = -100;

  ParametersType  parametersScale;
  parametersScale[0] = 1.0;
  parametersScale[1] = 1.0;

  itkOptimizer->SetMinimize();
  itkOptimizer->SetScale( parametersScale );
  itkOptimizer->SetLearningRate( 0.1 );
  itkOptimizer->SetNumberOfIterations( 50 );

  itkOptimizer->SetInitialPosition( initialPosition );
  itkOptimizer->StartOptimization();

  ParametersType finalPosition;
  finalPosition = costFunction.GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[2] = { 2, -2 };
  for( unsigned int j = 0; j < 2; j++ )
    {
    if( vnl_math_abs( finalPosition[j] - trueParameters[j] ) > 0.01 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

  return 0;

}

<commit_msg>ENH: removed redundant return 0 at the end<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkGradientDescentOptimizerTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 2000 National Library of Medicine
  All rights reserved.

  See COPYRIGHT.txt for copyright details.

=========================================================================*/

#include <itkGradientDescentOptimizer.h>
#include <itkPoint.h>
#include <itkCovariantVector.h>

/**
 *  The objectif function is the quadratic form:
 *
 *  1/2 x^T A x - b^T x
 *
 *  Where A is a matrix and b is a vector
 *  The system in this example is:
 *
 *     | 3  2 ||x|   | 2|   |0|
 *     | 2  6 ||y| + |-8| = |0|
 *
 *
 *   the solution is the vector | 2 -2 |
 *
 */
class CostFunction : public itk::LightObject
{
public:

  typedef CostFunction Self;
  typedef itk::LightObject  Superclass;
  typedef itk::SmartPointer<Self> Pointer;
  typedef itk::SmartPointer<const Self> ConstPointer;
  itkNewMacro( Self );

  enum { SpaceDimension=2 };

  typedef itk::Point<  double, SpaceDimension >          ParametersType;

  typedef itk::CovariantVector< double, SpaceDimension > DerivativeType;

  typedef double MeasureType ;

  CostFunction()
  {
  }

  const ParametersType & GetParameters(void) const
  {
    return m_Parameters;
  }

  const MeasureType & GetValue( const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetValue( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Measure = 0.5*(3*x*x+4*x*y+6*y*y) - 2*x + 8*y;

    std::cout << m_Measure << std::endl;

    return m_Measure;

  }

  const DerivativeType & GetDerivative(
             const ParametersType & parameters ) const
  {

    m_Parameters = parameters;

    double x = m_Parameters[0];
    double y = m_Parameters[1];

    std::cout << "GetDerivative( " ;
    std::cout << x << " ";
    std::cout << y << ") = ";

    m_Derivative[0] = 3 * x + 2 * y -2;
    m_Derivative[1] = 2 * x + 6 * y +8;

    std::cout << m_Derivative << std::endl;

    return m_Derivative;
  }

  void GetValueAndDerivative( const ParametersType & parameters,
    MeasureType& value, DerivativeType& deriv ) const
  {
    value = this->GetValue( parameters );
    deriv = this->GetDerivative( parameters );
  }

private:

  mutable ParametersType  m_Parameters;
  mutable MeasureType     m_Measure;
  mutable DerivativeType  m_Derivative;

};

int main()
{
  std::cout << "Gradient Descent Optimizer Test ";
  std::cout << std::endl << std::endl;

  typedef  itk::GradientDescentOptimizer<
                                CostFunction >  OptimizerType;

  // Declaration of a itkOptimizer
  OptimizerType::Pointer  itkOptimizer = OptimizerType::New();

  // Declaration of the CostFunction adaptor
  CostFunction costFunction;

  itkOptimizer->SetCostFunction( &costFunction );

   typedef CostFunction::ParametersType    ParametersType;

  // We start not so far from  | 2 -2 |
  ParametersType  initialPosition;
  initialPosition[0] =  100;
  initialPosition[1] = -100;

  ParametersType  parametersScale;
  parametersScale[0] = 1.0;
  parametersScale[1] = 1.0;

  itkOptimizer->SetMinimize();
  itkOptimizer->SetScale( parametersScale );
  itkOptimizer->SetLearningRate( 0.1 );
  itkOptimizer->SetNumberOfIterations( 50 );

  itkOptimizer->SetInitialPosition( initialPosition );
  itkOptimizer->StartOptimization();

  ParametersType finalPosition;
  finalPosition = costFunction.GetParameters();
  std::cout << "Solution        = (";
  std::cout << finalPosition[0] << "," ;
  std::cout << finalPosition[1] << ")" << std::endl;

  //
  // check results to see if it is within range
  //
  bool pass = true;
  double trueParameters[2] = { 2, -2 };
  for( unsigned int j = 0; j < 2; j++ )
    {
    if( vnl_math_abs( finalPosition[j] - trueParameters[j] ) > 0.01 )
      pass = false;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "Parser.h"

#include <algorithm>

#include "IMediaLibrary.h"
#include "Media.h"
#include "File.h"
#include "utils/ModificationsNotifier.h"

Parser::Parser( MediaLibrary* ml )
    : m_ml( ml )
    , m_callback( ml->getCb() )
    , m_notifier( ml->getNotifier() )
    , m_opToDo( 0 )
    , m_opDone( 0 )
    , m_percent( 0 )
{
}

void Parser::addService( ServicePtr service )
{
    service->initialize( m_ml, this );
    m_services.push_back( std::move( service ) );
}

void Parser::parse( std::shared_ptr<Media> media, std::shared_ptr<File> file )
{
    if ( m_services.size() == 0 )
        return;
    m_services[0]->parse( std::unique_ptr<parser::Task>( new parser::Task( media, file ) ) );
    m_opToDo += m_services.size();
    updateStats();
}

void Parser::start()
{
    restore();
    for ( auto& s : m_services )
        s->start();
}

void Parser::pause()
{
    for ( auto& s : m_services )
        s->pause();
}

void Parser::resume()
{
    for ( auto& s : m_services )
        s->resume();
}

void Parser::restore()
{
    if ( m_services.empty() == true )
        return;

    static const std::string req = "SELECT * FROM " + policy::FileTable::Name
            + " WHERE parsed = 0 AND is_present = 1";
    auto files = File::fetchAll<File>( m_ml, req );

    for ( auto& f : files )
    {
        auto m = f->media();
        parse( m, f );
    }
}

void Parser::updateStats()
{
    auto percent = m_opToDo > 0 ? ( m_opDone * 100 / m_opToDo ) : 0;
    if ( percent != m_percent )
    {
        m_percent = percent;
        m_callback->onParsingStatsUpdated( m_percent );
    }
}

void Parser::done( std::unique_ptr<parser::Task> t, parser::Task::Status status )
{
    ++m_opDone;
    updateStats();

    if ( status == parser::Task::Status::TemporaryUnavailable ||
         status == parser::Task::Status::Fatal )
    {
        return;
    }
    if ( status == parser::Task::Status::Success )
    {
        m_notifier->notifyMediaModification( t->media );
    }

    auto serviceIdx = ++t->currentService;
    if ( serviceIdx == m_services.size() )
    {
        t->file->markParsed();
        return;
    }
    m_services[serviceIdx]->parse( std::move( t ) );
}
<commit_msg>Parser: Decrement the number of "todo" operations when aborting a parsing due to error<commit_after>/*****************************************************************************
 * Media Library
 *****************************************************************************
 * Copyright (C) 2015 Hugo Beauzée-Luyssen, Videolabs
 *
 * Authors: Hugo Beauzée-Luyssen<hugo@beauzee.fr>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2.1 of the License, or
 * (at your option) any later version.
 *
 * This program 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
 *****************************************************************************/

#include "Parser.h"

#include <algorithm>

#include "IMediaLibrary.h"
#include "Media.h"
#include "File.h"
#include "utils/ModificationsNotifier.h"

Parser::Parser( MediaLibrary* ml )
    : m_ml( ml )
    , m_callback( ml->getCb() )
    , m_notifier( ml->getNotifier() )
    , m_opToDo( 0 )
    , m_opDone( 0 )
    , m_percent( 0 )
{
}

void Parser::addService( ServicePtr service )
{
    service->initialize( m_ml, this );
    m_services.push_back( std::move( service ) );
}

void Parser::parse( std::shared_ptr<Media> media, std::shared_ptr<File> file )
{
    if ( m_services.size() == 0 )
        return;
    m_services[0]->parse( std::unique_ptr<parser::Task>( new parser::Task( media, file ) ) );
    m_opToDo += m_services.size();
    updateStats();
}

void Parser::start()
{
    restore();
    for ( auto& s : m_services )
        s->start();
}

void Parser::pause()
{
    for ( auto& s : m_services )
        s->pause();
}

void Parser::resume()
{
    for ( auto& s : m_services )
        s->resume();
}

void Parser::restore()
{
    if ( m_services.empty() == true )
        return;

    static const std::string req = "SELECT * FROM " + policy::FileTable::Name
            + " WHERE parsed = 0 AND is_present = 1";
    auto files = File::fetchAll<File>( m_ml, req );

    for ( auto& f : files )
    {
        auto m = f->media();
        parse( m, f );
    }
}

void Parser::updateStats()
{
    auto percent = m_opToDo > 0 ? ( m_opDone * 100 / m_opToDo ) : 0;
    if ( percent != m_percent )
    {
        m_percent = percent;
        m_callback->onParsingStatsUpdated( m_percent );
    }
}

void Parser::done( std::unique_ptr<parser::Task> t, parser::Task::Status status )
{
    ++m_opDone;

    auto serviceIdx = ++t->currentService;

    if ( status == parser::Task::Status::TemporaryUnavailable ||
         status == parser::Task::Status::Fatal )
    {
        if ( serviceIdx < m_services.size() )
        {
            // We won't process the next tasks, so we need to keep the number of "todo" operations coherent:
            m_opToDo -= m_services.size() - serviceIdx;
            updateStats();
        }
        return;
    }
    updateStats();

    if ( status == parser::Task::Status::Success )
    {
        m_notifier->notifyMediaModification( t->media );
    }

    if ( serviceIdx == m_services.size() )
    {
        t->file->markParsed();
        return;
    }
    m_services[serviceIdx]->parse( std::move( t ) );
}
<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009-2012, Willow Garage, Inc.
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::visualization;
using namespace std;

PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
search::KdTree<PointXYZ>::Ptr tree;
search::KdTree<PointNormal>::Ptr tree2;

// add by ktran to test update functions
PointCloud<PointXYZ>::Ptr cloud1 (new PointCloud<PointXYZ>);
PointCloud<PointNormal>::Ptr cloud_with_normals1 (new PointCloud<PointNormal>);
search::KdTree<PointXYZ>::Ptr tree3;
search::KdTree<PointNormal>::Ptr tree4;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TEST (PCL, PCLVisualizer_camera)
{
  PCLVisualizer visualizer;
  visualizer.initCameraParameters ();

  // First test if the intrinsic+extrinsic to OpenGL conversion works back and forth
  Eigen::Matrix3f given_intrinsics (Eigen::Matrix3f::Identity ());
  given_intrinsics (0, 0) = 525.f;
  given_intrinsics (1, 1) = 525.f;
  given_intrinsics (0, 2) = 320.f;
  given_intrinsics (1, 2) = 240.f;

  float M_PIf = static_cast<float> (M_PI);
  Eigen::Matrix4f given_extrinsics (Eigen::Matrix4f::Identity ());
  given_extrinsics.block<3, 3> (0, 0) = Eigen::AngleAxisf (30.f * M_PIf / 180.f, Eigen::Vector3f (1.f, 0.f, 0.f)).matrix ();
  given_extrinsics.block<3, 1> (0, 3) = Eigen::Vector3f (10.f, 15.f, 20.f);

  visualizer.setCameraParameters (given_intrinsics, given_extrinsics);
  Eigen::Matrix4f viewer_pose = visualizer.getViewerPose ().matrix ();

  for (size_t i = 0; i < 4; ++i)
    for (size_t j = 0; j < 4; ++j)
      EXPECT_NEAR (given_extrinsics (i, j), viewer_pose (i, j), 1e-6);

  // Next, check if setting the OpenGL settings translate well back
  // Look towards the x-axis, which equates to a 90 degree rotation around the y-axis
  Eigen::Vector3f trans (10.f, 2.f, 20.f);
  visualizer.setCameraPosition (trans[0], trans[1], trans[2], trans[0] + 1., trans[1], trans[2], 0., 1., 0.);
  viewer_pose = visualizer.getViewerPose ().matrix ();
  Eigen::Matrix3f expected_rotation = Eigen::AngleAxisf (M_PIf / 2.0f, Eigen::Vector3f (0.f, 1.f, 0.f)).matrix ();
  for (size_t i = 0; i < 3; ++i)
    for (size_t j = 0; j < 3; ++j)
      EXPECT_NEAR (viewer_pose (i, j), expected_rotation (i, j), 1e-6);
  for (size_t i = 0; i < 3; ++i)
    EXPECT_NEAR (viewer_pose (i, 3), trans[i], 1e-6);

  // Now add the bunny point cloud and reset the camera based on the scene (i.e., VTK will compute a new camera pose
  // so that it includes the whole scene in the window)
  /// TODO stuck here, resetCamera () does not seem to work if there is no window present - can't do that on a Mac
//  visualizer.addPointCloud (cloud1);
//  visualizer.resetCamera ();
//  visualizer.spinOnce ();
//  viewer_pose = visualizer.getViewerPose ().matrix ();

//  cerr << "reset camera viewer pose:" << endl << viewer_pose << endl;
}

/* ---[ */
int
main (int argc, char** argv)
{
  if (argc < 2)
  {
    std::cerr << "No test file given. Please download `bunny.pcd` and pass its path to the test." << std::endl;
    return (-1);
  }

  // Load file
  pcl::PCLPointCloud2 cloud_blob;
  loadPCDFile (argv[1], cloud_blob);
  fromPCLPointCloud2 (cloud_blob, *cloud);

  // Create search tree
  tree.reset (new search::KdTree<PointXYZ> (false));
  tree->setInputCloud (cloud);

  // Normal estimation
  NormalEstimation<PointXYZ, Normal> n;
  PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
  n.setInputCloud (cloud);
  //n.setIndices (indices[B);
  n.setSearchMethod (tree);
  n.setKSearch (20);
  n.compute (*normals);

  // Concatenate XYZ and normal information
  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);

  // Create search tree
  tree2.reset (new search::KdTree<PointNormal>);
  tree2->setInputCloud (cloud_with_normals);

  // Process for update cloud
  if (argc == 3)
  {
    pcl::PCLPointCloud2 cloud_blob1;
    loadPCDFile (argv[2], cloud_blob1);
    fromPCLPointCloud2 (cloud_blob1, *cloud1);
        // Create search tree
    tree3.reset (new search::KdTree<PointXYZ> (false));
    tree3->setInputCloud (cloud1);

    // Normal estimation
    NormalEstimation<PointXYZ, Normal> n1;
    PointCloud<Normal>::Ptr normals1 (new PointCloud<Normal> ());
    n1.setInputCloud (cloud1);

    n1.setSearchMethod (tree3);
    n1.setKSearch (20);
    n1.compute (*normals1);

    // Concatenate XYZ and normal information
    pcl::concatenateFields (*cloud1, *normals1, *cloud_with_normals1);
    // Create search tree
    tree4.reset (new search::KdTree<PointNormal>);
    tree4->setInputCloud (cloud_with_normals1);
  }

  // Testing
  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
/* ]--- */
<commit_msg>[TEST] Add a unit test for 'getPointCloudRenderingProperties()'.<commit_after>/*
 * Software License Agreement (BSD License)
 *
 *  Copyright (c) 2009-2012, Willow Garage, Inc.
 *  Copyright (c) 2012-, Open Perception, Inc.
 *
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of the copyright holder(s) nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 *  POSSIBILITY OF SUCH DAMAGE.
 *
 * $Id$
 *
 */

#include <gtest/gtest.h>

#include <pcl/point_types.h>
#include <pcl/io/pcd_io.h>
#include <pcl/features/normal_3d.h>
#include <pcl/visualization/pcl_visualizer.h>

using namespace pcl;
using namespace pcl::io;
using namespace pcl::visualization;
using namespace std;

PointCloud<PointXYZ>::Ptr cloud (new PointCloud<PointXYZ>);
PointCloud<PointNormal>::Ptr cloud_with_normals (new PointCloud<PointNormal>);
search::KdTree<PointXYZ>::Ptr tree;
search::KdTree<PointNormal>::Ptr tree2;

// add by ktran to test update functions
PointCloud<PointXYZ>::Ptr cloud1 (new PointCloud<PointXYZ>);
PointCloud<PointNormal>::Ptr cloud_with_normals1 (new PointCloud<PointNormal>);
search::KdTree<PointXYZ>::Ptr tree3;
search::KdTree<PointNormal>::Ptr tree4;

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
TEST (PCL, PCLVisualizer_camera)
{
  PCLVisualizer visualizer;
  visualizer.initCameraParameters ();

  // First test if the intrinsic+extrinsic to OpenGL conversion works back and forth
  Eigen::Matrix3f given_intrinsics (Eigen::Matrix3f::Identity ());
  given_intrinsics (0, 0) = 525.f;
  given_intrinsics (1, 1) = 525.f;
  given_intrinsics (0, 2) = 320.f;
  given_intrinsics (1, 2) = 240.f;

  float M_PIf = static_cast<float> (M_PI);
  Eigen::Matrix4f given_extrinsics (Eigen::Matrix4f::Identity ());
  given_extrinsics.block<3, 3> (0, 0) = Eigen::AngleAxisf (30.f * M_PIf / 180.f, Eigen::Vector3f (1.f, 0.f, 0.f)).matrix ();
  given_extrinsics.block<3, 1> (0, 3) = Eigen::Vector3f (10.f, 15.f, 20.f);

  visualizer.setCameraParameters (given_intrinsics, given_extrinsics);
  Eigen::Matrix4f viewer_pose = visualizer.getViewerPose ().matrix ();

  for (size_t i = 0; i < 4; ++i)
    for (size_t j = 0; j < 4; ++j)
      EXPECT_NEAR (given_extrinsics (i, j), viewer_pose (i, j), 1e-6);

  // Next, check if setting the OpenGL settings translate well back
  // Look towards the x-axis, which equates to a 90 degree rotation around the y-axis
  Eigen::Vector3f trans (10.f, 2.f, 20.f);
  visualizer.setCameraPosition (trans[0], trans[1], trans[2], trans[0] + 1., trans[1], trans[2], 0., 1., 0.);
  viewer_pose = visualizer.getViewerPose ().matrix ();
  Eigen::Matrix3f expected_rotation = Eigen::AngleAxisf (M_PIf / 2.0f, Eigen::Vector3f (0.f, 1.f, 0.f)).matrix ();
  for (size_t i = 0; i < 3; ++i)
    for (size_t j = 0; j < 3; ++j)
      EXPECT_NEAR (viewer_pose (i, j), expected_rotation (i, j), 1e-6);
  for (size_t i = 0; i < 3; ++i)
    EXPECT_NEAR (viewer_pose (i, 3), trans[i], 1e-6);

  // Now add the bunny point cloud and reset the camera based on the scene (i.e., VTK will compute a new camera pose
  // so that it includes the whole scene in the window)
  /// TODO stuck here, resetCamera () does not seem to work if there is no window present - can't do that on a Mac
//  visualizer.addPointCloud (cloud1);
//  visualizer.resetCamera ();
//  visualizer.spinOnce ();
//  viewer_pose = visualizer.getViewerPose ().matrix ();

//  cerr << "reset camera viewer pose:" << endl << viewer_pose << endl;
}

////////////////////////////////////////////////////////////////////////////////
TEST (PCL, PCLVisualizer_getPointCloudRenderingProperties)
{
  PCLVisualizer::Ptr visualizer (new PCLVisualizer);

  std::string cloud_id = "input_cloud";
  visualizer->addPointCloud (cloud, cloud_id);
  ASSERT_TRUE (visualizer->setPointCloudRenderingProperties (PCL_VISUALIZER_COLOR,
                                                             1.d, 0.d, 0.d, cloud_id));
  double r, g, b;
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_POINT_SIZE,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_OPACITY,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_LINE_WIDTH,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_FONT_SIZE,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_REPRESENTATION,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_IMMEDIATE_RENDERING,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_SHADING,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_LUT,
                                                              r, g, b, cloud_id));
  EXPECT_FALSE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_LUT_RANGE,
                                                              r, g, b, cloud_id));

  r = 666.d;
  g = 666.d;
  b = 666.d;
  EXPECT_TRUE (visualizer->getPointCloudRenderingProperties (PCL_VISUALIZER_COLOR,
                                                             r, g, b, cloud_id));

  EXPECT_EQ (r, 1.d);
  EXPECT_EQ (g, 0.d);
  EXPECT_EQ (b, 0.d);
}

/* ---[ */
int
main (int argc, char** argv)
{
  if (argc < 2)
  {
    std::cerr << "No test file given. Please download `bunny.pcd` and pass its path to the test." << std::endl;
    return (-1);
  }

  // Load file
  pcl::PCLPointCloud2 cloud_blob;
  loadPCDFile (argv[1], cloud_blob);
  fromPCLPointCloud2 (cloud_blob, *cloud);

  // Create search tree
  tree.reset (new search::KdTree<PointXYZ> (false));
  tree->setInputCloud (cloud);

  // Normal estimation
  NormalEstimation<PointXYZ, Normal> n;
  PointCloud<Normal>::Ptr normals (new PointCloud<Normal> ());
  n.setInputCloud (cloud);
  //n.setIndices (indices[B);
  n.setSearchMethod (tree);
  n.setKSearch (20);
  n.compute (*normals);

  // Concatenate XYZ and normal information
  pcl::concatenateFields (*cloud, *normals, *cloud_with_normals);

  // Create search tree
  tree2.reset (new search::KdTree<PointNormal>);
  tree2->setInputCloud (cloud_with_normals);

  // Process for update cloud
  if (argc == 3)
  {
    pcl::PCLPointCloud2 cloud_blob1;
    loadPCDFile (argv[2], cloud_blob1);
    fromPCLPointCloud2 (cloud_blob1, *cloud1);
        // Create search tree
    tree3.reset (new search::KdTree<PointXYZ> (false));
    tree3->setInputCloud (cloud1);

    // Normal estimation
    NormalEstimation<PointXYZ, Normal> n1;
    PointCloud<Normal>::Ptr normals1 (new PointCloud<Normal> ());
    n1.setInputCloud (cloud1);

    n1.setSearchMethod (tree3);
    n1.setKSearch (20);
    n1.compute (*normals1);

    // Concatenate XYZ and normal information
    pcl::concatenateFields (*cloud1, *normals1, *cloud_with_normals1);
    // Create search tree
    tree4.reset (new search::KdTree<PointNormal>);
    tree4->setInputCloud (cloud_with_normals1);
  }

  // Testing
  testing::InitGoogleTest (&argc, argv);
  return (RUN_ALL_TESTS ());
}
/* ]--- */
<|endoftext|>


<commit_before>#include "instruments/population/GenerationFitnessCSV.hpp"
#include <cmath>
#include <string>

GenerationFitnessCSV::GenerationFitnessCSV(
	PopulationNode* target,
	std::string outFile,
	float bottomFitness,
	float topFitness,
	float resolution
) : GenerationalCSVInstrument(target, outFile) {
	std::vector<float> buckets;
	for (float i = bottomFitness; i <= topFitness; i+= resolution)
		buckets.push_back(i);

	this->buckets = buckets;
	this->resolution = resolution;
	this->addToHeader("Generation");
	this->addToHeader(buckets);
}

float GenerationFitnessCSV::bucket(float actual) {
	float mod = fmod(actual, this->resolution);

	return (mod < this->resolution/2 ?
		actual - mod : actual - mod + resolution);
}

void GenerationFitnessCSV::report() {
	auto output = this->buildEmptyMap(this->buckets, (unsigned int)0);
	output.emplace("Generation", this->target->currentGeneration());
	for (auto fitness: this->stringifyVector(this->target->getFitnesses()))
		output[fitness]++;
	this->write(output, (unsigned int)0);
}
<commit_msg>[GenerationFitnessCSV]: Fixed bucketing problems<commit_after>#include "instruments/population/GenerationFitnessCSV.hpp"
#include <cmath>
#include <string>

GenerationFitnessCSV::GenerationFitnessCSV(
	PopulationNode* target,
	std::string outFile,
	float bottomFitness,
	float topFitness,
	float resolution
) : GenerationalCSVInstrument(target, outFile) {
	std::vector<float> buckets;
	for (float i = bottomFitness; i <= topFitness; i+= resolution)
		buckets.push_back(i);

	this->buckets = buckets;
	this->resolution = resolution;
	this->addToHeader("Generation");
	this->addToHeader(buckets);
}

float GenerationFitnessCSV::bucket(float actual) {
	float mod = fmod(actual, this->resolution);

	return (mod < this->resolution/2 ?
		actual - mod : actual - mod + resolution);
}

void GenerationFitnessCSV::report() {
	auto output = this->buildEmptyMap(this->buckets, (unsigned int)0);
	output.emplace("Generation", this->target->currentGeneration());
	for (auto fitness: this->target->getFitnesses())
		output[this->stringify(this->bucket(fitness))]++;
	this->write(output, (unsigned int)0);
}
<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     bci.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     December, 2013
*
* @section  LICENSE
*
* Copyright (C) 2013, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MASSACHUSETTS GENERAL HOSPITAL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the BCI class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "bci.h"

#include "FormFiles/bcisetupwidget.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtCore/QtPlugin>
#include <QtCore/QTextStream>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace BCIPlugin;
using namespace std;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

BCI::BCI()
: m_qStringResourcePath(qApp->applicationDirPath()+"/mne_x_plugins/resources/bci/"),
  m_bProcessData(false)
{
}

//*************************************************************************************************************

BCI::~BCI()
{
    //std::cout << "BCI::~BCI() " << std::endl;

    //If the program is closed while the sampling is in process
    if(this->isRunning())
        this->stop();
}

//*************************************************************************************************************

QSharedPointer<IPlugin> BCI::clone() const
{
    QSharedPointer<BCI> pTMSIClone(new BCI());
    return pTMSIClone;
}

//*************************************************************************************************************

void BCI::init()
{
    m_bIsRunning = false;

    // Inputs - Source estimates and sensor level
    m_pRTSEInput = PluginInputData<RealTimeSourceEstimate>::create(this, "BCIInSource", "BCI source input data");
    connect(m_pRTSEInput.data(), &PluginInputConnector::notify, this, &BCI::updateSource, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTSEInput);

    m_pRTMSAInput = PluginInputData<NewRealTimeMultiSampleArray>::create(this, "BCIInSensor", "SourceLab sensor input data");
    connect(m_pRTMSAInput.data(), &PluginInputConnector::notify, this, &BCI::updateSensor, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTMSAInput);

    // Output
    m_pBCIOutput = PluginOutputData<NewRealTimeSampleArray>::create(this, "ControlSignal", "BCI output data");
    m_outputConnectors.append(m_pBCIOutput);

    //m_pBCIOutput->data()->setMaxValue();

    //Delete Buffer - will be initailzed with first incoming data
    if(!m_pBCIBuffer_Sensor.isNull())
        m_pBCIBuffer_Sensor = CircularMatrixBuffer<double>::SPtr();

    if(!m_pBCIBuffer_Source.isNull())
        m_pBCIBuffer_Source = CircularMatrixBuffer<double>::SPtr();

    // Delete fiff info because the initialisation of the fiff info is seen as the first data acquisition from the input stream
    if(!m_pFiffInfo_Sensor.isNull())
        m_pFiffInfo_Sensor = FiffInfo::SPtr();

    // Intitalise GUI stuff
    m_bUseSensorData = true;
    m_bUseSourceData = false;
    m_bUseArtefactThresholdReduction = false;
    m_dSlidingWindowSize = 1.0;
    m_dBaseLineWindowSize = 1.0;
    m_dTimeBetweenWindows = 0.04;
    m_iNumberSubSignals = 1;
    m_sSensorBoundaryPath = m_qStringResourcePath;
    m_sSourceBoundaryPath = m_qStringResourcePath;

    // Intitalise feature selection
    m_slChosenFeatureSensor << "LA4" << "RA4"; //<< "TEST";

    // Initialise boundaries with linear coefficients y = mx+c -> vector = [m c] -> default [1 0]
    m_vLoadedSensorBoundary.push_back(1);
    m_vLoadedSensorBoundary.push_back(0);

    m_vLoadedSourceBoundary.push_back(1);
    m_vLoadedSourceBoundary.push_back(0);

    // Initalise sliding window stuff
    m_iTBWIndexSensor = 0;
    m_bFillSensorWindowFirstTime = true;
}

//*************************************************************************************************************

bool BCI::start()
{
    m_bIsRunning = true;

    //If statement if acquisiton plugin is connected - if not dont start

    QThread::start();

    return true;
}

//*************************************************************************************************************

bool BCI::stop()
{
    //Wait until this thread (BCI) is stopped
    m_bIsRunning = false;

    // Get data buffers out of idle state if they froze in the acquire or release function
    //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)

    if(m_bProcessData) // Only clear if buffers have been initialised
    {
        m_pBCIBuffer_Sensor->releaseFromPop();
        m_pBCIBuffer_Sensor->releaseFromPush();
        //    m_pBCIBuffer_Source->releaseFromPop();
        //    m_pBCIBuffer_Source->releaseFromPush();
    }

    // Stop filling buffers with data from the inputs
    m_bProcessData = false;

    return true;
}

//*************************************************************************************************************

IPlugin::PluginType BCI::getType() const
{
    return _IAlgorithm;
}

//*************************************************************************************************************

QString BCI::getName() const
{
    return "BCI EEG";
}

//*************************************************************************************************************

QWidget* BCI::setupWidget()
{
    BCISetupWidget* widget = new BCISetupWidget(this);//widget is later destroyed by CentralWidget - so it has to be created everytime new

    //init properties dialog
    widget->initGui();

    return widget;
}

//*************************************************************************************************************

void BCI::updateSensor(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<NewRealTimeMultiSampleArray> pRTMSA = pMeasurement.dynamicCast<NewRealTimeMultiSampleArray>();
    if(pRTMSA)
    {
        //Check if buffer initialized
        if(!m_pBCIBuffer_Sensor)
            m_pBCIBuffer_Sensor = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize()));

        //Fiff information for sensor level
        if(!m_pFiffInfo_Sensor)
        {
            m_pFiffInfo_Sensor = pRTMSA->getFiffInfo();

            // Adjust working matrixes (sliding window and time between windows matrix) size so that the samples from the tmsi plugin stream fit in the matrix perfectly
            int modulo = (int)(m_pFiffInfo_Sensor->sfreq*m_dSlidingWindowSize) % (int)pRTMSA->getMultiArraySize();

            int rows = m_slChosenFeatureSensor.size();
            int cols = m_pFiffInfo_Sensor->sfreq*m_dSlidingWindowSize-modulo;
            m_matSlidingWindowSensor.resize(rows, cols);

            modulo = (int)(m_pFiffInfo_Sensor->sfreq*m_dTimeBetweenWindows) % (int)pRTMSA->getMultiArraySize();
            rows = m_slChosenFeatureSensor.size();
            cols = m_pFiffInfo_Sensor->sfreq*m_dTimeBetweenWindows-modulo;
            m_matTimeBetweenWindowsSensor.resize(rows, cols);
        }

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize());

            for(unsigned char i = 0; i < pRTMSA->getMultiArraySize(); ++i)
                t_mat.col(i) = pRTMSA->getMultiSampleArray()[i];

            m_pBCIBuffer_Sensor->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void BCI::updateSource(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<RealTimeSourceEstimate> pRTSE = pMeasurement.dynamicCast<RealTimeSourceEstimate>();
    if(pRTSE)
    {
        //Check if buffer initialized
        if(!m_pBCIBuffer_Source)
            m_pBCIBuffer_Source = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTSE->getValue().size(), pRTSE->getArraySize()));

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTSE->getValue().size(), pRTSE->getArraySize());

            for(unsigned char i = 0; i < pRTSE->getArraySize(); ++i)
                t_mat.col(i) = pRTSE->getStc().data.col(i);

            m_pBCIBuffer_Source->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void BCI::run()
{
    while(m_bIsRunning)
    {
        // Wait for fiff Info if not yet received - this is needed because we have to wait until the buffers are firstly initiated in the update functions
        while(!m_pFiffInfo_Sensor)
            msleep(10);

        // Start filling buffers with data from the inputs
        m_bProcessData = true;

        // Sensor level: Fill matrices with data
        if(m_bFillSensorWindowFirstTime) // Sensor level: Fill m_matSlidingWindowSensor with data for the first time
        {
            if(m_iTBWIndexSensor < m_matSlidingWindowSensor.cols())
            {
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matSlidingWindowSensor.rows(); i++)
                    m_matSlidingWindowSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // m_matSlidingWindowSensor is full for the first time
            {
                m_iTBWIndexSensor = 0;
                m_bFillSensorWindowFirstTime = false;
            }
        }
        else // Sensor level: Fill m_matTimeBetweenWindowsSensor matrix until full -> Then -> recalculate m_matSlidingWindowSensor, calculate features and classify
        {
            if(m_iTBWIndexSensor < m_matTimeBetweenWindowsSensor.cols())
            {
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matTimeBetweenWindowsSensor.rows(); i++)
                    m_matTimeBetweenWindowsSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // Recalculate m_matSlidingWindowSensor -> Calculate features, classify and store results
            {
                // Recalculate m_matSlidingWindowSensor -> Delete same block size of data from the right -> use eval() to resolve Eigens aliasing problem
                m_matSlidingWindowSensor.block(0, 0, m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()) = m_matSlidingWindowSensor.block(0, m_matTimeBetweenWindowsSensor.cols(), m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()).eval();

                // Recalculate m_matSlidingWindowSensor -> push m_matTimeBetweenWindowsSensor from the left
                m_matSlidingWindowSensor.block(0, m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols(), m_matTimeBetweenWindowsSensor.rows(), m_matTimeBetweenWindowsSensor.cols()) = m_matTimeBetweenWindowsSensor;

                // Test if data is correctly streamed to this plugin
//                cout<<"Recalculate matrix"<<endl;
//                for(int i = 1; i<m_matSlidingWindowSensor.cols() ; i++)
//                {
//                    cout<<m_matSlidingWindowSensor(2,i)<<endl;
////                    if(m_matSlidingWindowSensor(2,i) - m_matSlidingWindowSensor(2,i-1) != 1)
////                        cout<<"Sequence error while streaming from tmsi plugin at position: "<<i<<endl;
//                }
                m_iTBWIndexSensor = 0;
            }
        }
    }
}
<commit_msg>- BCI Plugin: Marked To Do's<commit_after>//=============================================================================================================
/**
* @file     bci.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     December, 2013
*
* @section  LICENSE
*
* Copyright (C) 2013, Lorenz Esch, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of the Massachusetts General Hospital nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MASSACHUSETTS GENERAL HOSPITAL BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains the implementation of the BCI class.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "bci.h"

#include "FormFiles/bcisetupwidget.h"

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QtCore/QtPlugin>
#include <QtCore/QTextStream>
#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace BCIPlugin;
using namespace std;

//*************************************************************************************************************
//=============================================================================================================
// DEFINE MEMBER METHODS
//=============================================================================================================

BCI::BCI()
: m_qStringResourcePath(qApp->applicationDirPath()+"/mne_x_plugins/resources/bci/"),
  m_bProcessData(false)
{
}

//*************************************************************************************************************

BCI::~BCI()
{
    //std::cout << "BCI::~BCI() " << std::endl;

    //If the program is closed while the sampling is in process
    if(this->isRunning())
        this->stop();
}

//*************************************************************************************************************

QSharedPointer<IPlugin> BCI::clone() const
{
    QSharedPointer<BCI> pTMSIClone(new BCI());
    return pTMSIClone;
}

//*************************************************************************************************************

void BCI::init()
{
    m_bIsRunning = false;

    // Inputs - Source estimates and sensor level
    m_pRTSEInput = PluginInputData<RealTimeSourceEstimate>::create(this, "BCIInSource", "BCI source input data");
    connect(m_pRTSEInput.data(), &PluginInputConnector::notify, this, &BCI::updateSource, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTSEInput);

    m_pRTMSAInput = PluginInputData<NewRealTimeMultiSampleArray>::create(this, "BCIInSensor", "SourceLab sensor input data");
    connect(m_pRTMSAInput.data(), &PluginInputConnector::notify, this, &BCI::updateSensor, Qt::DirectConnection);
    m_inputConnectors.append(m_pRTMSAInput);

    // Output
    m_pBCIOutput = PluginOutputData<NewRealTimeSampleArray>::create(this, "ControlSignal", "BCI output data");
    m_outputConnectors.append(m_pBCIOutput);

    //m_pBCIOutput->data()->setMaxValue();

    //Delete Buffer - will be initailzed with first incoming data
    if(!m_pBCIBuffer_Sensor.isNull())
        m_pBCIBuffer_Sensor = CircularMatrixBuffer<double>::SPtr();

    if(!m_pBCIBuffer_Source.isNull())
        m_pBCIBuffer_Source = CircularMatrixBuffer<double>::SPtr();

    // Delete fiff info because the initialisation of the fiff info is seen as the first data acquisition from the input stream
    if(!m_pFiffInfo_Sensor.isNull())
        m_pFiffInfo_Sensor = FiffInfo::SPtr();

    // Intitalise GUI stuff
    m_bUseSensorData = true;
    m_bUseSourceData = false;
    m_bUseArtefactThresholdReduction = false;
    m_dSlidingWindowSize = 1.0;
    m_dBaseLineWindowSize = 1.0;
    m_dTimeBetweenWindows = 0.04;
    m_iNumberSubSignals = 1;
    m_sSensorBoundaryPath = m_qStringResourcePath;
    m_sSourceBoundaryPath = m_qStringResourcePath;

    // Intitalise feature selection
    m_slChosenFeatureSensor << "LA4" << "RA4"; //<< "TEST";

    // Initialise boundaries with linear coefficients y = mx+c -> vector = [m c] -> default [1 0]
    m_vLoadedSensorBoundary.push_back(1);
    m_vLoadedSensorBoundary.push_back(0);

    m_vLoadedSourceBoundary.push_back(1);
    m_vLoadedSourceBoundary.push_back(0);

    // Initalise sliding window stuff
    m_iTBWIndexSensor = 0;
    m_bFillSensorWindowFirstTime = true;
}

//*************************************************************************************************************

bool BCI::start()
{
    m_bIsRunning = true;

    //If statement if acquisiton plugin is connected - if not dont start

    QThread::start();

    return true;
}

//*************************************************************************************************************

bool BCI::stop()
{
    //Wait until this thread (BCI) is stopped
    m_bIsRunning = false;

    // Get data buffers out of idle state if they froze in the acquire or release function
    //In case the semaphore blocks the thread -> Release the QSemaphore and let it exit from the pop function (acquire statement)

    if(m_bProcessData) // Only clear if buffers have been initialised
    {
        m_pBCIBuffer_Sensor->releaseFromPop();
        m_pBCIBuffer_Sensor->releaseFromPush();
        //    m_pBCIBuffer_Source->releaseFromPop();
        //    m_pBCIBuffer_Source->releaseFromPush();
    }

    // Stop filling buffers with data from the inputs
    m_bProcessData = false;

    return true;
}

//*************************************************************************************************************

IPlugin::PluginType BCI::getType() const
{
    return _IAlgorithm;
}

//*************************************************************************************************************

QString BCI::getName() const
{
    return "BCI EEG";
}

//*************************************************************************************************************

QWidget* BCI::setupWidget()
{
    BCISetupWidget* widget = new BCISetupWidget(this);//widget is later destroyed by CentralWidget - so it has to be created everytime new

    //init properties dialog
    widget->initGui();

    return widget;
}

//*************************************************************************************************************

void BCI::updateSensor(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<NewRealTimeMultiSampleArray> pRTMSA = pMeasurement.dynamicCast<NewRealTimeMultiSampleArray>();
    if(pRTMSA)
    {
        //Check if buffer initialized
        if(!m_pBCIBuffer_Sensor)
            m_pBCIBuffer_Sensor = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize()));

        //Fiff information for sensor level
        if(!m_pFiffInfo_Sensor)
        {
            m_pFiffInfo_Sensor = pRTMSA->getFiffInfo();

            // Adjust working matrixes (sliding window and time between windows matrix) size so that the samples from the tmsi plugin stream fit in the matrix perfectly
            int modulo = (int)(m_pFiffInfo_Sensor->sfreq*m_dSlidingWindowSize) % (int)pRTMSA->getMultiArraySize();

            int rows = m_slChosenFeatureSensor.size();
            int cols = m_pFiffInfo_Sensor->sfreq*m_dSlidingWindowSize-modulo;
            m_matSlidingWindowSensor.resize(rows, cols);

            modulo = (int)(m_pFiffInfo_Sensor->sfreq*m_dTimeBetweenWindows) % (int)pRTMSA->getMultiArraySize();
            rows = m_slChosenFeatureSensor.size();
            cols = m_pFiffInfo_Sensor->sfreq*m_dTimeBetweenWindows-modulo;
            m_matTimeBetweenWindowsSensor.resize(rows, cols);
        }

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTMSA->getNumChannels(), pRTMSA->getMultiArraySize());

            for(unsigned char i = 0; i < pRTMSA->getMultiArraySize(); ++i)
                t_mat.col(i) = pRTMSA->getMultiSampleArray()[i];

            m_pBCIBuffer_Sensor->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void BCI::updateSource(XMEASLIB::NewMeasurement::SPtr pMeasurement)
{
    QSharedPointer<RealTimeSourceEstimate> pRTSE = pMeasurement.dynamicCast<RealTimeSourceEstimate>();
    if(pRTSE)
    {
        //Check if buffer initialized
        if(!m_pBCIBuffer_Source)
            m_pBCIBuffer_Source = CircularMatrixBuffer<double>::SPtr(new CircularMatrixBuffer<double>(64, pRTSE->getValue().size(), pRTSE->getArraySize()));

        if(m_bProcessData)
        {
            MatrixXd t_mat(pRTSE->getValue().size(), pRTSE->getArraySize());

            for(unsigned char i = 0; i < pRTSE->getArraySize(); ++i)
                t_mat.col(i) = pRTSE->getStc().data.col(i);

            m_pBCIBuffer_Source->push(&t_mat);
        }
    }
}

//*************************************************************************************************************

void BCI::run()
{
    while(m_bIsRunning)
    {
        // Wait for fiff Info if not yet received - this is needed because we have to wait until the buffers are firstly initiated in the update functions
        while(!m_pFiffInfo_Sensor)
            msleep(10);

        // Start filling buffers with data from the inputs
        m_bProcessData = true;

        // Sensor level: Fill matrices with data
        if(m_bFillSensorWindowFirstTime) // Sensor level: Fill m_matSlidingWindowSensor with data for the first time
        {
            if(m_iTBWIndexSensor < m_matSlidingWindowSensor.cols())
            {
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matSlidingWindowSensor.rows(); i++)
                    m_matSlidingWindowSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // m_matSlidingWindowSensor is full for the first time
            {
                m_iTBWIndexSensor = 0;
                m_bFillSensorWindowFirstTime = false;
            }
        }
        else // Sensor level: Fill m_matTimeBetweenWindowsSensor matrix until full -> Then -> recalculate m_matSlidingWindowSensor, calculate features and classify
        {
            if(m_iTBWIndexSensor < m_matTimeBetweenWindowsSensor.cols())
            {
                MatrixXd t_mat = m_pBCIBuffer_Sensor->pop();

                // Get only the rows from the matrix which correspond with the selected features, namely electrodes on sensor level and destrieux clustered regions on source level
                for(int i = 0; i < m_matTimeBetweenWindowsSensor.rows(); i++)
                    m_matTimeBetweenWindowsSensor.block(i, m_iTBWIndexSensor, 1, t_mat.cols()) = t_mat.block(m_mapElectrodePinningScheme[m_slChosenFeatureSensor.at(i)], 0, 1, t_mat.cols());

                m_iTBWIndexSensor = m_iTBWIndexSensor + t_mat.cols();
            }
            else // Recalculate m_matSlidingWindowSensor -> Calculate features, classify and store results
            {
                // Recalculate m_matSlidingWindowSensor -> Delete same block size of data from the right -> use eval() to resolve Eigens aliasing problem
                m_matSlidingWindowSensor.block(0, 0, m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()) = m_matSlidingWindowSensor.block(0, m_matTimeBetweenWindowsSensor.cols(), m_matSlidingWindowSensor.rows(), m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols()).eval();

                // Recalculate m_matSlidingWindowSensor -> push m_matTimeBetweenWindowsSensor from the left
                m_matSlidingWindowSensor.block(0, m_matSlidingWindowSensor.cols()-m_matTimeBetweenWindowsSensor.cols(), m_matTimeBetweenWindowsSensor.rows(), m_matTimeBetweenWindowsSensor.cols()) = m_matTimeBetweenWindowsSensor;

                // TODO: Filter data in m_matSlidingWindowSensor

                // TODO: Calculate features

                // TODO: Store features

                // TODO: Classify features and store results

                // TODO: Check how full the classification result vector is -> if too big emit signal and average results, delete all results and make final decision to triggerbox

                // Test if data is correctly streamed to this plugin
//                cout<<"Recalculate matrix"<<endl;
//                for(int i = 1; i<m_matSlidingWindowSensor.cols() ; i++)
//                {
//                    cout<<m_matSlidingWindowSensor(2,i)<<endl;
////                    if(m_matSlidingWindowSensor(2,i) - m_matSlidingWindowSensor(2,i-1) != 1)
////                        cout<<"Sequence error while streaming from tmsi plugin at position: "<<i<<endl;
//                }

                m_iTBWIndexSensor = 0;
            }
        }
    }
}
<|endoftext|>


<commit_before>/*
	Copyright (C) 2015-2016 Claude SIMON (http://q37.info/contact/).

	This file is part of 'orgnzq' software.

    'orgnzq' is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    'orgnzq' 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with 'orgnzq'.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "record.h"

#include "core.h"
#include "registry.h"
#include "sclfrntnd.h"

namespace {
	E_CDEF( char *, XSLAffix_, "Record" );

	E_CDEF( char *, FieldsFrameId_, "Fields" );
	E_CDEF( char *, ColumnFrameId_, "Column" );

	void GetContext_(
		core::rSession &Session,
		str::string_ &XML )
	{
	qRH
		base::rContextRack Rack;
	qRB
		Rack.Init( XSLAffix_, XML, Session );
	qRR
	qRT
	qRE
	}

	void SetCasting_(
		const char *Id,
		core::rSession &Session )
	{
	qRH
		str::string XML, XSL;
	qRB
		XML.Init();
		GetContext_( Session,  XML );

		XSL.Init();
		sclxdhtml::LoadXSLAndTranslateTags(rgstry::tentry___( registry::definition::XSLCastingFile, XSLAffix_ ), Session.Registry() , XSL );

		Session.FillElementCastings( Id, XML, XSL );
	qRR
	qRT
	qRE
	}

	static void GetContent_(
		const sclrgstry::registry_ &Registry,
		core::rSession &Session,
		str::string_ &XML )
	{
	qRH
		base::content_rack___ Rack;
	qRB
		Rack.Init( XSLAffix_, XML, Session );

		Session.User.DumpFieldBuffer( Rack() );
	qRR
	qRT
	qRE
	}
}

void record::SetLayout(
	const char *Id,
	core::rSession &Session )
{
qRH
	str::string XML, XSL;
qRB
	XML.Init();
	GetContent_( Session.Registry(), Session, XML );

	XSL.Init();
	sclxdhtml::LoadXSLAndTranslateTags( rgstry::tentry___( registry::definition::XSLLayoutFile, XSLAffix_ ), Session.Registry(), XSL );

	Session.FillElement( Id, XML, XSL );

	SetCasting_( Id, Session );

	switch ( Session.User.View() ) {
	case frdinstc::vRecord:
	case frdinstc::vField:
		fields::SetLayout( FieldsFrameId_, Session );
		break;
	case frdinstc::vColumn:
		column::SetLayout( ColumnFrameId_, Session );
		break;
	}
qRR
qRT
qRE
}

void record::SetFieldsLayout( core::rSession &Session )
{
	fields::SetLayout( FieldsFrameId_, Session );
}

BASE_AC( record::sDefineNewField )
{
	Session.User.DefineNewField();

	main::SetRecordLayout( Session );
}

<commit_msg>18/05/2016 10:49:02<commit_after>/*
	Copyright (C) 2015-2016 Claude SIMON (http://q37.info/contact/).

	This file is part of 'orgnzq' software.

    'orgnzq' is free software: you can redistribute it and/or modify it
    under the terms of the GNU Affero General Public License as published
    by the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    'orgnzq' 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 Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with 'orgnzq'.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "record.h"

#include "core.h"
#include "registry.h"
#include "sclfrntnd.h"

namespace {
	E_CDEF( char *, XSLAffix_, "Record" );

	E_CDEF( char *, FieldsFrameId_, "Fields" );
	E_CDEF( char *, ColumnFrameId_, "Column" );

	void GetContext_(
		core::rSession &Session,
		str::string_ &XML )
	{
	qRH
		base::rContextRack Rack;
	qRB
		Rack.Init( XSLAffix_, XML, Session );
	qRR
	qRT
	qRE
	}

	void SetCasting_(
		const char *Id,
		core::rSession &Session )
	{
	qRH
		str::string XML, XSL;
	qRB
		XML.Init();
		GetContext_( Session,  XML );

		XSL.Init();
		sclxdhtml::LoadXSLAndTranslateTags(rgstry::tentry___( registry::definition::XSLCastingFile, XSLAffix_ ), Session.Registry() , XSL );

		Session.FillElementCastings( Id, XML, XSL );
	qRR
	qRT
	qRE
	}

	static void GetContent_(
		const sclrgstry::registry_ &Registry,
		core::rSession &Session,
		str::string_ &XML )
	{
	qRH
		base::content_rack___ Rack;
	qRB
		Rack.Init( XSLAffix_, XML, Session );

		Session.User.DumpFieldBuffer( Rack() );
	qRR
	qRT
	qRE
	}
}

void record::SetLayout(
	const char *Id,
	core::rSession &Session )
{
qRH
	str::string XML, XSL;
qRB
	XML.Init();
	GetContent_( Session.Registry(), Session, XML );

	XSL.Init();
	sclxdhtml::LoadXSLAndTranslateTags( rgstry::tentry___( registry::definition::XSLLayoutFile, XSLAffix_ ), Session.Registry(), XSL );

	Session.FillElement( Id, XML, XSL );

	SetCasting_( Id, Session );

	switch ( Session.User.View() ) {
	case frdinstc::vRecord:
	case frdinstc::vField:
		fields::SetLayout( FieldsFrameId_, Session );
		break;
	case frdinstc::vColumn:
		column::SetLayout( ColumnFrameId_, Session );
		break;
	default:
		qRGnr();
		break;
	}
qRR
qRT
qRE
}

void record::SetFieldsLayout( core::rSession &Session )
{
	fields::SetLayout( FieldsFrameId_, Session );
}

BASE_AC( record::sDefineNewField )
{
	Session.User.DefineNewField();

	main::SetRecordLayout( Session );
}

<|endoftext|>


<commit_before>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#include "native-stack.hh"
#include "native-stack-impl.hh"
#include "net.hh"
#include "ip.hh"
#include "tcp-stack.hh"
#include "udp.hh"
#include "virtio.hh"
#include "proxy.hh"
#include <memory>
#include <queue>

namespace net {

// native_network_stack
class native_network_stack : public network_stack {
    static std::unique_ptr<native_network_stack> _s;
    interface _netif;
    ipv4 _inet;
    udp_v4 _udp;
    using tcp4 = tcp<ipv4_traits>;
public:
    explicit native_network_stack(boost::program_options::variables_map opts);
    virtual server_socket listen(socket_address sa, listen_options opt) override;
    virtual udp_channel make_udp_channel(ipv4_addr addr) override;
    static std::unique_ptr<network_stack> create(boost::program_options::variables_map opts) {
        return std::make_unique<native_network_stack>(opts);
    }
    friend class native_server_socket_impl<tcp4>;
};

udp_channel
native_network_stack::make_udp_channel(ipv4_addr addr) {
    return _udp.make_channel(addr);
}

native_network_stack::native_network_stack(boost::program_options::variables_map opts)
    : _netif(smp::main_thread() ? create_virtio_net_device(opts["tap-device"].as<std::string>(), opts) : create_proxy_net_device(opts))
    , _inet(&_netif)
    , _udp(_inet) {
    _inet.set_host_address(ipv4_address(opts["host-ipv4-addr"].as<std::string>()));
    _inet.set_gw_address(ipv4_address(opts["gw-ipv4-addr"].as<std::string>()));
    _inet.set_netmask_address(ipv4_address(opts["netmask-ipv4-addr"].as<std::string>()));
    _udp.set_queue_size(opts["udpv4-queue-size"].as<int>());
}

server_socket
native_network_stack::listen(socket_address sa, listen_options opts) {
    assert(sa.as_posix_sockaddr().sa_family == AF_INET);
    return tcpv4_listen(_inet.get_tcp(), ntohs(sa.as_posix_sockaddr_in().sin_port), opts);
}

std::unique_ptr<native_network_stack> native_network_stack::_s;

boost::program_options::options_description nns_options() {
    boost::program_options::options_description opts(
            "Native networking stack options");
    opts.add_options()
        ("tap-device",
                boost::program_options::value<std::string>()->default_value("tap0"),
                "tap device to connect to")
        ("host-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.2"),
                "static IPv4 address to use")
        ("gw-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.1"),
                "static IPv4 gateway to use")
        ("netmask-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("255.255.255.0"),
                "static IPv4 netmask to use")
        ("udpv4-queue-size",
                boost::program_options::value<int>()->default_value(udp_v4::default_queue_size),
                "Default size of the UDPv4 per-channel packet queue")
        ;
    opts.add(get_virtio_net_options_description());
    return opts;
}

network_stack_registrator nns_registrator{
    "native", nns_options(), native_network_stack::create
};

}
<commit_msg>native stack: support more than virtio<commit_after>/*
 * Copyright (C) 2014 Cloudius Systems, Ltd.
 */

#include "native-stack.hh"
#include "native-stack-impl.hh"
#include "net.hh"
#include "ip.hh"
#include "tcp-stack.hh"
#include "udp.hh"
#include "virtio.hh"
#include "xenfront.hh"
#include "proxy.hh"
#include <memory>
#include <queue>
#ifdef HAVE_OSV
#include <osv/firmware.hh>
#include <gnu/libc-version.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>

namespace net {

// native_network_stack
class native_network_stack : public network_stack {
    static std::unique_ptr<native_network_stack> _s;
    interface _netif;
    ipv4 _inet;
    udp_v4 _udp;
    using tcp4 = tcp<ipv4_traits>;
public:
    explicit native_network_stack(boost::program_options::variables_map opts);
    virtual server_socket listen(socket_address sa, listen_options opt) override;
    virtual udp_channel make_udp_channel(ipv4_addr addr) override;
    static std::unique_ptr<network_stack> create(boost::program_options::variables_map opts) {
        return std::make_unique<native_network_stack>(opts);
    }
    friend class native_server_socket_impl<tcp4>;
};

udp_channel
native_network_stack::make_udp_channel(ipv4_addr addr) {
    return _udp.make_channel(addr);
}

enum class xen_info {
    nonxen = 0,
    userspace = 1,
    osv = 2,
};

static xen_info is_xen()
{
    struct stat buf;
    if (!stat("/proc/xen", &buf) || !stat("/dev/xen", &buf)) {
        return xen_info::userspace;
    }

#ifdef HAVE_OSV
    const char *str = gnu_get_libc_release();
    if (std::string("OSv") != str) {
        return xen_info::nonxen;
    }
    auto firmware = osv::firmware_vendor();
    if (firmware == "Xen") {
        return xen_info::osv;
    }
#endif

    return xen_info::nonxen;
}

std::unique_ptr<net::device> create_native_net_device(boost::program_options::variables_map opts) {

    if (!smp::main_thread()) {
        return create_proxy_net_device(opts);
    }

    auto xen = is_xen();
    if (xen == xen_info::nonxen) {
        return create_virtio_net_device(opts["tap-device"].as<std::string>(), opts);
    }
    return create_xenfront_net_device(opts, xen == xen_info::userspace);
}

void
add_native_net_options_description(boost::program_options::options_description &opts) {

    auto xen = is_xen();
    if (xen != xen_info::nonxen) {
        opts.add(get_xenfront_net_options_description());
    } else {
        opts.add(get_virtio_net_options_description());
    }
}

native_network_stack::native_network_stack(boost::program_options::variables_map opts)
    : _netif(create_native_net_device(opts))
    , _inet(&_netif)
    , _udp(_inet) {
    _inet.set_host_address(ipv4_address(opts["host-ipv4-addr"].as<std::string>()));
    _inet.set_gw_address(ipv4_address(opts["gw-ipv4-addr"].as<std::string>()));
    _inet.set_netmask_address(ipv4_address(opts["netmask-ipv4-addr"].as<std::string>()));
    _udp.set_queue_size(opts["udpv4-queue-size"].as<int>());
}

server_socket
native_network_stack::listen(socket_address sa, listen_options opts) {
    assert(sa.as_posix_sockaddr().sa_family == AF_INET);
    return tcpv4_listen(_inet.get_tcp(), ntohs(sa.as_posix_sockaddr_in().sin_port), opts);
}

std::unique_ptr<native_network_stack> native_network_stack::_s;

boost::program_options::options_description nns_options() {
    boost::program_options::options_description opts(
            "Native networking stack options");
    opts.add_options()
        ("tap-device",
                boost::program_options::value<std::string>()->default_value("tap0"),
                "tap device to connect to")
        ("host-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.2"),
                "static IPv4 address to use")
        ("gw-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("192.168.122.1"),
                "static IPv4 gateway to use")
        ("netmask-ipv4-addr",
                boost::program_options::value<std::string>()->default_value("255.255.255.0"),
                "static IPv4 netmask to use")
        ("udpv4-queue-size",
                boost::program_options::value<int>()->default_value(udp_v4::default_queue_size),
                "Default size of the UDPv4 per-channel packet queue")
        ;

    add_native_net_options_description(opts);
    return opts;
}

network_stack_registrator nns_registrator{
    "native", nns_options(), native_network_stack::create
};

}
<|endoftext|>


<commit_before>//
// Created by Axel Naumann on 09/12/15.
//

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The Interpreter object cast to void*
using TheInterpreter = void ;

/// Create an interpreter object.
TheInterpreter *cling_create(int argc, const char *argv[], const char* llvmdir) {
  auto interp = new cling::Interpreter(argc, argv, llvmdir);
  printf("Interpreter @%p\n", interp);
  return interp;
}

/// Evaluate a string of code. Returns 0 on success.
int cling_eval(TheInterpreter *interpVP, const char *code) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  //cling::Value V;
  cling::Interpreter::CompilationResult Res = interp->process(code /*, V*/);
  if (Res != cling::Interpreter::kSuccess)
    return 1;
  return 0;
}
///\}

} // extern "C"
<commit_msg>Add destruction of Interpreter.<commit_after>//
// Created by Axel Naumann on 09/12/15.
//

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The Interpreter object cast to void*
using TheInterpreter = void ;

/// Create an interpreter object.
TheInterpreter *cling_create(int argc, const char *argv[], const char* llvmdir) {
  auto interp = new cling::Interpreter(argc, argv, llvmdir);
  printf("Interpreter @%p\n", interp);
  return interp;
}

/// Destroy the interpreter.
void cling_destroy(TheInterpreter *interpVP) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  delete interp;
}

/// Evaluate a string of code. Returns 0 on success.
int cling_eval(TheInterpreter *interpVP, const char *code) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  //cling::Value V;
  cling::Interpreter::CompilationResult Res = interp->process(code /*, V*/);
  if (Res != cling::Interpreter::kSuccess)
    return 1;
  return 0;
}
///\}

} // extern "C"
<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// FIXME: This file shall contain the decl of cling::Jupyter in a future
// revision!
//#include "cling/Interpreter/Jupyter/Kernel.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"

#include "llvm/Support/raw_ostream.h"

#include <map>
#include <string>
#include <cstring>
#ifndef LLVM_ON_WIN32
# include <unistd.h>
#else
# include <io.h>
# define write _write
#endif

// FIXME: should be moved into a Jupyter interp struct that then gets returned
// from create.
int pipeToJupyterFD = -1;

namespace cling {
  namespace Jupyter {
    struct MIMEDataRef {
      const char* m_Data;
      const long m_Size;

      MIMEDataRef(const std::string& str):
      m_Data(str.c_str()), m_Size((long)str.length() + 1) {}
      MIMEDataRef(const char* str):
      MIMEDataRef(std::string(str)) {}
      MIMEDataRef(const char* data, long size):
      m_Data(data), m_Size(size) {}
    };

    /// Push MIME stuff to Jupyter. To be called from user code.
    ///\param contentDict - dictionary of MIME type versus content. E.g.
    /// {{"text/html", {"

", }}
    ///\returns `false` if the output could not be sent.
    bool pushOutput(const std::map<std::string, MIMEDataRef> contentDict) {

      // Pipe sees (all numbers are longs, except for the first:
      // - num bytes in a long (sent as a single unsigned char!)
      // - num elements of the MIME dictionary; Jupyter selects one to display.
      // For each MIME dictionary element:
      //   - size of MIME type string  (including the terminating 0)
      //   - MIME type as 0-terminated string
      //   - size of MIME data buffer (including the terminating 0 for
      //     0-terminated strings)
      //   - MIME data buffer

      // Write number of dictionary elements (and the size of that number in a
      // char)
      unsigned char sizeLong = sizeof(long);
      if (write(pipeToJupyterFD, &sizeLong, 1) != 1)
        return false;
      long dictSize = contentDict.size();
      if (write(pipeToJupyterFD, &dictSize, sizeof(long)) != sizeof(long))
        return false;

      for (auto iContent: contentDict) {
        const std::string& mimeType = iContent.first;
        long mimeTypeSize = (long)mimeType.size();
        if (write(pipeToJupyterFD, &mimeTypeSize, sizeof(long)) != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeType.c_str(), mimeType.size() + 1)
            != (long)(mimeType.size() + 1))
          return false;
        const MIMEDataRef& mimeData = iContent.second;
        if (write(pipeToJupyterFD, &mimeData.m_Size, sizeof(long))
            != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeData.m_Data, mimeData.m_Size)
            != mimeData.m_Size)
          return false;
      }
      return true;
    }
  } // namespace Jupyter
} // namespace cling

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The Interpreter object cast to void*
using TheInterpreter = void ;

/// Create an interpreter object.
TheInterpreter*
cling_create(int argc, const char *argv[], const char* llvmdir, int pipefd) {
  auto interp = new cling::Interpreter(argc, argv, llvmdir);
  pipeToJupyterFD = pipefd;
  return interp;
}

/// Destroy the interpreter.
void cling_destroy(TheInterpreter *interpVP) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  delete interp;
}

/// Stringify a cling::Value
static std::string ValueToString(const cling::Value& V) {
  std::string valueString;
  {
    llvm::raw_string_ostream os(valueString);
    V.print(os);
  }
  return valueString;
}

/// Evaluate a string of code. Returns nullptr on failure.
/// Returns a string representation of the expression (can be "") on success.
char* cling_eval(TheInterpreter *interpVP, const char *code) {
  cling::Interpreter *interp = (cling::Interpreter *) interpVP;
  cling::Value V;
  cling::Interpreter::CompilationResult Res = interp->process(code, &V);
  if (Res != cling::Interpreter::kSuccess)
    return nullptr;

  // cling::Jupyter::pushOutput({{"text/html", "You just executed C++ code!"}});
  if (!V.isValid())
    return strdup("");
  return strdup(ValueToString(V).c_str());
}

void cling_eval_free(char* str) {
  free(str);
}

/// Code completion interfaces.

/// Start completion of code. Returns a handle to be passed to
/// cling_complete_next() to iterate over the completion options. Returns nulptr
/// if no completions are known.
void* cling_complete_start(const char* code) {
  return new int(42);
}

/// Grab the next completion of some code. Returns nullptr if none is left.
const char* cling_complete_next(void* completionHandle) {
  int* counter = (int*) completionHandle;
  if (++(*counter) > 43) {
    delete counter;
    return nullptr;
  }
  return "COMPLETE!";
}

///\}

} // extern "C"
<commit_msg>Bind Jupyter to MetaProcessor instead of Interpreter.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Axel Naumann <axel@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// FIXME: This file shall contain the decl of cling::Jupyter in a future
// revision!
//#include "cling/Interpreter/Jupyter/Kernel.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/Value.h"
#include "cling/MetaProcessor/MetaProcessor.h"

#include "llvm/Support/raw_ostream.h"

#include <map>
#include <string>
#include <cstring>
#ifndef LLVM_ON_WIN32
# include <unistd.h>
#else
# include <io.h>
# define write _write
#endif

// FIXME: should be moved into a Jupyter interp struct that then gets returned
// from create.
int pipeToJupyterFD = -1;

namespace cling {
  namespace Jupyter {
    struct MIMEDataRef {
      const char* m_Data;
      const long m_Size;

      MIMEDataRef(const std::string& str):
      m_Data(str.c_str()), m_Size((long)str.length() + 1) {}
      MIMEDataRef(const char* str):
      MIMEDataRef(std::string(str)) {}
      MIMEDataRef(const char* data, long size):
      m_Data(data), m_Size(size) {}
    };

    /// Push MIME stuff to Jupyter. To be called from user code.
    ///\param contentDict - dictionary of MIME type versus content. E.g.
    /// {{"text/html", {"

", }}
    ///\returns `false` if the output could not be sent.
    bool pushOutput(const std::map<std::string, MIMEDataRef> contentDict) {

      // Pipe sees (all numbers are longs, except for the first:
      // - num bytes in a long (sent as a single unsigned char!)
      // - num elements of the MIME dictionary; Jupyter selects one to display.
      // For each MIME dictionary element:
      //   - size of MIME type string  (including the terminating 0)
      //   - MIME type as 0-terminated string
      //   - size of MIME data buffer (including the terminating 0 for
      //     0-terminated strings)
      //   - MIME data buffer

      // Write number of dictionary elements (and the size of that number in a
      // char)
      unsigned char sizeLong = sizeof(long);
      if (write(pipeToJupyterFD, &sizeLong, 1) != 1)
        return false;
      long dictSize = contentDict.size();
      if (write(pipeToJupyterFD, &dictSize, sizeof(long)) != sizeof(long))
        return false;

      for (auto iContent: contentDict) {
        const std::string& mimeType = iContent.first;
        long mimeTypeSize = (long)mimeType.size();
        if (write(pipeToJupyterFD, &mimeTypeSize, sizeof(long)) != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeType.c_str(), mimeType.size() + 1)
            != (long)(mimeType.size() + 1))
          return false;
        const MIMEDataRef& mimeData = iContent.second;
        if (write(pipeToJupyterFD, &mimeData.m_Size, sizeof(long))
            != sizeof(long))
          return false;
        if (write(pipeToJupyterFD, mimeData.m_Data, mimeData.m_Size)
            != mimeData.m_Size)
          return false;
      }
      return true;
    }
  } // namespace Jupyter
} // namespace cling

extern "C" {
///\{
///\name Cling4CTypes
/// The Python compatible view of cling

/// The MetaProcessor cast to void*
using TheMetaProcessor = void;

/// Create an interpreter object.
TheMetaProcessor*
cling_create(int argc, const char *argv[], const char* llvmdir, int pipefd) {
  pipeToJupyterFD = pipefd;
  auto I = new cling::Interpreter(argc, argv, llvmdir);
  return new cling::MetaProcessor(*I, llvm::errs());
}

/// Destroy the interpreter.
void cling_destroy(TheMetaProcessor *metaProc) {
  cling::MetaProcessor *M = (cling::MetaProcessor*)metaProc;
  cling::Interpreter *I = const_cast<cling::Interpreter*>(&M->getInterpreter());
  delete M;
  delete I;
}

/// Stringify a cling::Value
static std::string ValueToString(const cling::Value& V) {
  std::string valueString;
  {
    llvm::raw_string_ostream os(valueString);
    V.print(os);
  }
  return valueString;
}

/// Evaluate a string of code. Returns nullptr on failure.
/// Returns a string representation of the expression (can be "") on success.
char* cling_eval(TheMetaProcessor *metaProc, const char *code) {
  cling::MetaProcessor *M = (cling::MetaProcessor*)metaProc;
  cling::Value V;
  cling::Interpreter::CompilationResult Res;
  if (M->process(code, Res, &V)) {
    cling::Jupyter::pushOutput({{"text/html", "Incomplete input! Ignored."}});
    M->cancelContinuation();
    return nullptr;
  }
  if (Res != cling::Interpreter::kSuccess)
    return nullptr;

  if (!V.isValid())
    return strdup("");
  return strdup(ValueToString(V).c_str());
}

void cling_eval_free(char* str) {
  free(str);
}

/// Code completion interfaces.

/// Start completion of code. Returns a handle to be passed to
/// cling_complete_next() to iterate over the completion options. Returns nulptr
/// if no completions are known.
void* cling_complete_start(const char* code) {
  return new int(42);
}

/// Grab the next completion of some code. Returns nullptr if none is left.
const char* cling_complete_next(void* completionHandle) {
  int* counter = (int*) completionHandle;
  if (++(*counter) > 43) {
    delete counter;
    return nullptr;
  }
  return "COMPLETE!";
}

///\}

} // extern "C"
<|endoftext|>


<commit_before>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2018 Igor Petrovic

    This program 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.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "board/Board.h"
#include "pins/Map.h"
#include "board/common/analog/input/Variables.h"
#include "board/common/digital/input/Variables.h"
#include "board/common/digital/input/direct/Variables.h"
#include "board/common/digital/input/Variables.h"
#include "../../../../interface/digital/output/leds/Variables.h"
#include "../../../../interface/digital/output/leds/Helpers.h"
#include "board/common/indicators/Variables.h"
#include "board/common/constants/LEDs.h"

volatile uint32_t rTime_ms;

volatile bool MIDIreceived, MIDIsent;
static uint8_t lastLEDstate[MAX_NUMBER_OF_LEDS] = { 255 };

inline void storeDigitalIn()
{
    setLow(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
    setLow(SR_IN_LATCH_PORT, SR_IN_LATCH_PIN);
    _NOP();
    _NOP();

    setHigh(SR_IN_LATCH_PORT, SR_IN_LATCH_PIN);

    for (int i=0; i<MAX_NUMBER_OF_BUTTONS; i++)
    {
        setLow(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
        _NOP();
        BIT_WRITE(digitalInBuffer[digitalInBufferCounter], i, !readPin(SR_IN_DATA_PORT, SR_IN_DATA_PIN));
        setHigh(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
    }

    digitalInBufferCounter++;
}

inline void checkLEDs()
{
    bool updateSR = false;

    for (int i=0; i<MAX_NUMBER_OF_LEDS; i++)
    {
        uint8_t ledStateSingle = LED_ON(ledState[i]);

        if (ledStateSingle != lastLEDstate[i])
        {
            lastLEDstate[i] = ledStateSingle;
            updateSR = true;
        }
    }

    if (updateSR)
    {
        setLow(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

        for (int i=0; i<MAX_NUMBER_OF_LEDS; i++)
        {
            LED_ON(ledState[i]) ? setLow(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : setHigh(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
            pulseHighToLow(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
        }

        setHigh(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);
    }
}

ISR(TIMER0_COMPA_vect)
{
    static uint8_t updateStuff = 0;
    updateStuff++;

    if (analogSampleCounter != NUMBER_OF_ANALOG_SAMPLES)
        startADCconversion();

    if (updateStuff == 4)
    {
        rTime_ms++;
        checkLEDs();

        if (digitalInBufferCounter < DIGITAL_IN_BUFFER_SIZE)
            storeDigitalIn();

        updateStuff = 0;
    }
}

inline void setMuxInput()
{
    BIT_READ(activeMuxInput, 0) ? setHigh(MUX_S0_PORT, MUX_S0_PIN) : setLow(MUX_S0_PORT, MUX_S0_PIN);
    BIT_READ(activeMuxInput, 1) ? setHigh(MUX_S1_PORT, MUX_S1_PIN) : setLow(MUX_S1_PORT, MUX_S1_PIN);
    BIT_READ(activeMuxInput, 2) ? setHigh(MUX_S2_PORT, MUX_S2_PIN) : setLow(MUX_S2_PORT, MUX_S2_PIN);
    BIT_READ(activeMuxInput, 3) ? setHigh(MUX_S3_PORT, MUX_S3_PIN) : setLow(MUX_S3_PORT, MUX_S3_PIN);
}

ISR(ADC_vect)
{
    analogBuffer[analogIndex] += ADC;
    analogIndex++;
    activeMuxInput++;

    bool switchMux = (activeMuxInput == NUMBER_OF_MUX_INPUTS);

    if (switchMux)
    {
        activeMuxInput = 0;
        activeMux++;

        if (activeMux == NUMBER_OF_MUX)
        {
            activeMux = 0;
            analogIndex = 0;
            analogSampleCounter++;
        }

        setADCchannel(muxInPinArray[activeMux]);
    }

    //always set mux input
    setMuxInput();
}
<commit_msg>fix button readout on kodama board<commit_after>/*
    OpenDeck MIDI platform firmware
    Copyright (C) 2015-2018 Igor Petrovic

    This program 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.

    This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "board/Board.h"
#include "pins/Map.h"
#include "board/common/analog/input/Variables.h"
#include "board/common/digital/input/Variables.h"
#include "board/common/digital/input/direct/Variables.h"
#include "board/common/digital/input/Variables.h"
#include "../../../../interface/digital/output/leds/Variables.h"
#include "../../../../interface/digital/output/leds/Helpers.h"
#include "board/common/indicators/Variables.h"
#include "board/common/constants/LEDs.h"

volatile uint32_t rTime_ms;

volatile bool MIDIreceived, MIDIsent;
static uint8_t lastLEDstate[MAX_NUMBER_OF_LEDS] = { 255 };

inline void storeDigitalIn()
{
    setLow(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
    setLow(SR_IN_LATCH_PORT, SR_IN_LATCH_PIN);
    _NOP();
    _NOP();

    setHigh(SR_IN_LATCH_PORT, SR_IN_LATCH_PIN);

    for (int i=0; i<NUMBER_OF_IN_SR; i++)
    {
        for (int j=0; j<8; j++)
        {
            setLow(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
            _NOP();
            BIT_WRITE(digitalInBuffer[i], j, !readPin(SR_IN_DATA_PORT, SR_IN_DATA_PIN));
            setHigh(SR_IN_CLK_PORT, SR_IN_CLK_PIN);
        }
    }

    digitalInBufferCounter = DIGITAL_IN_BUFFER_SIZE;
}

inline void checkLEDs()
{
    bool updateSR = false;

    for (int i=0; i<MAX_NUMBER_OF_LEDS; i++)
    {
        uint8_t ledStateSingle = LED_ON(ledState[i]);

        if (ledStateSingle != lastLEDstate[i])
        {
            lastLEDstate[i] = ledStateSingle;
            updateSR = true;
        }
    }

    if (updateSR)
    {
        setLow(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);

        for (int i=0; i<MAX_NUMBER_OF_LEDS; i++)
        {
            LED_ON(ledState[i]) ? setLow(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN) : setHigh(SR_OUT_DATA_PORT, SR_OUT_DATA_PIN);
            pulseHighToLow(SR_OUT_CLK_PORT, SR_OUT_CLK_PIN);
        }

        setHigh(SR_OUT_LATCH_PORT, SR_OUT_LATCH_PIN);
    }
}

ISR(TIMER0_COMPA_vect)
{
    static uint8_t updateStuff = 0;
    updateStuff++;

    if (analogSampleCounter != NUMBER_OF_ANALOG_SAMPLES)
        startADCconversion();

    if (updateStuff == 4)
    {
        rTime_ms++;
        checkLEDs();

        if (digitalInBufferCounter < DIGITAL_IN_BUFFER_SIZE)
            storeDigitalIn();

        updateStuff = 0;
    }
}

inline void setMuxInput()
{
    BIT_READ(activeMuxInput, 0) ? setHigh(MUX_S0_PORT, MUX_S0_PIN) : setLow(MUX_S0_PORT, MUX_S0_PIN);
    BIT_READ(activeMuxInput, 1) ? setHigh(MUX_S1_PORT, MUX_S1_PIN) : setLow(MUX_S1_PORT, MUX_S1_PIN);
    BIT_READ(activeMuxInput, 2) ? setHigh(MUX_S2_PORT, MUX_S2_PIN) : setLow(MUX_S2_PORT, MUX_S2_PIN);
    BIT_READ(activeMuxInput, 3) ? setHigh(MUX_S3_PORT, MUX_S3_PIN) : setLow(MUX_S3_PORT, MUX_S3_PIN);
}

ISR(ADC_vect)
{
    analogBuffer[analogIndex] += ADC;
    analogIndex++;
    activeMuxInput++;

    bool switchMux = (activeMuxInput == NUMBER_OF_MUX_INPUTS);

    if (switchMux)
    {
        activeMuxInput = 0;
        activeMux++;

        if (activeMux == NUMBER_OF_MUX)
        {
            activeMux = 0;
            analogIndex = 0;
            analogSampleCounter++;
        }

        setADCchannel(muxInPinArray[activeMux]);
    }

    //always set mux input
    setMuxInput();
}
<|endoftext|>