<commit_before>#ifndef MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#define MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/VelocityVerletIntegrator.hpp>
#include <mjolnir/core/UnderdampedLangevinIntegrator.hpp>
#include <mjolnir/core/BAOABLangevinIntegrator.hpp>
#include <mjolnir/core/SystemMotionRemover.hpp>
#include <mjolnir/input/utility.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/throw_exception.hpp>

namespace mjolnir
{

template<typename traitsT>
SystemMotionRemover<traitsT>
read_system_motion_remover(const toml::value& simulator)
{
    const auto& integrator = toml::find(simulator, "integrator");

    if(!integrator.contains("remove"))
    {
        return SystemMotionRemover<traitsT>(false, false, false);
    }
    const auto& remove = toml::find(integrator.at("remove"));

    const bool translation = toml::find_or(remove, "translation");
    const bool rotation    = toml::find_or(remove, "rotation");
    const bool rescale     = toml::find_or(remove, "rescale");

    return SystemMotionRemover<traitsT>(translation, rotation, rescale);
}

template<typename traitsT>
VelocityVerletIntegrator<traitsT>
read_velocity_verlet_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    return VelocityVerletIntegrator<traitsT>(delta_t,
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
UnderdampedLangevinIntegrator<traitsT>
read_underdamped_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx){gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return UnderdampedLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
BAOABLangevinIntegrator<traitsT>
read_BAOAB_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx) {gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return BAOABLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

// A mapping object from type information (template parameter) to the actual
// read_xxx_integrator function
template<typename T>
struct read_integrator_impl;

template<typename traitsT>
struct read_integrator_impl<VelocityVerletIntegrator<traitsT>>
{
    static VelocityVerletIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_velocity_verlet_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<UnderdampedLangevinIntegrator<traitsT>>
{
    static UnderdampedLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_underdamped_langevin_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<BAOABLangevinIntegrator<traitsT>>
{
    static BAOABLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_BAOAB_langevin_integrator<traitsT>(sim);
    }
};

template<typename integratorT>
integratorT read_integrator(const toml::value& sim)
{
    if(sim.as_table().count("integrator") == 0)
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_integrator: No integrator defined: ", sim, "here", {
            "expected value is one of the following.",
            "- \"VelocityVerlet\"     : simple and standard Velocity Verlet integrator.",
            "- \"UnderdampedLangevin\": simple Underdamped Langevin Integrator"
                                      " based on the Velocity Verlet",
            "- \"BAOABLangevin\"      : well-known BAOAB Langevin Integrator"
            }));
    }
    return read_integrator_impl<integratorT>::invoke(sim);
}

#ifdef MJOLNIR_SEPARATE_BUILD
extern template VelocityVerletIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);

extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);

extern template BAOABLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
#endif

} // mjolnir
#endif// MJOLNIR_READ_INTEGRATOR
<commit_msg>fix: integrator table can be omitted<commit_after>#ifndef MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#define MJOLNIR_INPUT_READ_INTEGRATOR_HPP
#include <extlib/toml/toml.hpp>
#include <mjolnir/core/VelocityVerletIntegrator.hpp>
#include <mjolnir/core/UnderdampedLangevinIntegrator.hpp>
#include <mjolnir/core/BAOABLangevinIntegrator.hpp>
#include <mjolnir/core/SystemMotionRemover.hpp>
#include <mjolnir/input/utility.hpp>
#include <mjolnir/util/logger.hpp>
#include <mjolnir/util/throw_exception.hpp>

namespace mjolnir
{

template<typename traitsT>
SystemMotionRemover<traitsT>
read_system_motion_remover(const toml::value& simulator)
{
    if(!simulator.contains("integrator") ||
       !simulator.at("integrator").contains("remove"))
    {
        return SystemMotionRemover<traitsT>(false, false, false);
    }

    const auto& remove = toml::find(simulator, "integrator", "remove");

    const bool translation = toml::find_or(remove, "translation", false);
    const bool rotation    = toml::find_or(remove, "rotation",    false);
    const bool rescale     = toml::find_or(remove, "rescale",     false);

    return SystemMotionRemover<traitsT>(translation, rotation, rescale);
}

template<typename traitsT>
VelocityVerletIntegrator<traitsT>
read_velocity_verlet_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    return VelocityVerletIntegrator<traitsT>(delta_t,
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
UnderdampedLangevinIntegrator<traitsT>
read_underdamped_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx){gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return UnderdampedLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

template<typename traitsT>
BAOABLangevinIntegrator<traitsT>
read_BAOAB_langevin_integrator(const toml::value& simulator)
{
    MJOLNIR_GET_DEFAULT_LOGGER();
    MJOLNIR_LOG_FUNCTION();
    using real_type = typename traitsT::real_type;

    const real_type delta_t = toml::find<real_type>(simulator, "delta_t");
    MJOLNIR_LOG_INFO("delta_t = ", delta_t);

    const auto& integrator = toml::find(simulator, "integrator");

    check_keys_available(integrator, {"type"_s, "seed"_s, "parameters"_s});

    const auto parameters = toml::find<toml::array  >(integrator, "parameters");

    std::vector<real_type> gamma(parameters.size());
    for(const auto& params : parameters)
    {
        const auto idx = toml::find<std::size_t>(params, "index");
        const auto  gm = toml::expect<real_type>(params, u8"γ").or_other(
                         toml::expect<real_type>(params, "gamma")).unwrap();
        if(gamma.size() <= idx) {gamma.resize(idx+1);}
        gamma.at(idx) = gm;

        MJOLNIR_LOG_INFO("idx = ", idx, ", gamma = ", gm);
    }
    return BAOABLangevinIntegrator<traitsT>(delta_t, std::move(gamma),
            read_system_motion_remover<traitsT>(simulator));
}

// A mapping object from type information (template parameter) to the actual
// read_xxx_integrator function
template<typename T>
struct read_integrator_impl;

template<typename traitsT>
struct read_integrator_impl<VelocityVerletIntegrator<traitsT>>
{
    static VelocityVerletIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_velocity_verlet_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<UnderdampedLangevinIntegrator<traitsT>>
{
    static UnderdampedLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_underdamped_langevin_integrator<traitsT>(sim);
    }
};

template<typename traitsT>
struct read_integrator_impl<BAOABLangevinIntegrator<traitsT>>
{
    static BAOABLangevinIntegrator<traitsT> invoke(const toml::value& sim)
    {
        return read_BAOAB_langevin_integrator<traitsT>(sim);
    }
};

template<typename integratorT>
integratorT read_integrator(const toml::value& sim)
{
    if(sim.as_table().count("integrator") == 0)
    {
        throw_exception<std::runtime_error>(toml::format_error("[error] "
            "mjolnir::read_integrator: No integrator defined: ", sim, "here", {
            "expected value is one of the following.",
            "- \"VelocityVerlet\"     : simple and standard Velocity Verlet integrator.",
            "- \"UnderdampedLangevin\": simple Underdamped Langevin Integrator"
                                      " based on the Velocity Verlet",
            "- \"BAOABLangevin\"      : well-known BAOAB Langevin Integrator"
            }));
    }
    return read_integrator_impl<integratorT>::invoke(sim);
}

#ifdef MJOLNIR_SEPARATE_BUILD
extern template VelocityVerletIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);
extern template VelocityVerletIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_velocity_verlet_integrator(const toml::value& simulator);

extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);
extern template UnderdampedLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_underdamped_langevin_integrator(const toml::value& simulator);

extern template BAOABLangevinIntegrator<SimulatorTraits<double, UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  UnlimitedBoundary>       > read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<double, CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
extern template BAOABLangevinIntegrator<SimulatorTraits<float,  CuboidalPeriodicBoundary>> read_BAOAB_langevin_integrator(const toml::value& simulator);
#endif

} // mjolnir
#endif// MJOLNIR_READ_INTEGRATOR
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkMaskPoints.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMaskPoints.h"

#include "vtkCellArray.h"
#include "vtkDataSet.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkMaskPoints, "1.41");
vtkStandardNewMacro(vtkMaskPoints);

//----------------------------------------------------------------------------
vtkMaskPoints::vtkMaskPoints()
{
  this->OnRatio = 2;
  this->Offset = 0;
  this->RandomMode = 0;
  this->MaximumNumberOfPoints = VTK_LARGE_ID;
  this->GenerateVertices = 0;
}

//----------------------------------------------------------------------------
void vtkMaskPoints::Execute()
{
  vtkPoints *newPts;
  vtkPointData *pd;
  vtkIdType numNewPts;
  float *x;
  vtkIdType ptId, id;
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();
  vtkDataSet *input= this->GetInput();
  vtkIdType numPts=input->GetNumberOfPoints();

  // Check input
  //
  vtkDebugMacro(<<"Masking points");

  if ( numPts < 1 )
    {
    vtkErrorMacro(<<"No data to mask!");
    return;
    }

  pd = input->GetPointData();
  id = 0;

  // Allocate space
  //
  numNewPts = numPts / this->OnRatio;
  if (numNewPts > this->MaximumNumberOfPoints)
    {
    numNewPts = this->MaximumNumberOfPoints;
    }
  newPts = vtkPoints::New();
  newPts->Allocate(numNewPts);
  outputPD->CopyAllocate(pd);

  // Traverse points and copy
  //
  int abort=0;
  vtkIdType progressInterval=numPts/20 +1;
  if ( this->RandomMode ) // retro mode
    {
    float cap;

    if (((float)numPts/this->OnRatio) > this->MaximumNumberOfPoints)
      {
      cap = 2.0*numPts/this->MaximumNumberOfPoints - 1;
      }
    else
      {
      cap = 2.0*this->OnRatio - 1;
      }

    for (ptId = this->Offset;
    (ptId < numPts) && (id < this->MaximumNumberOfPoints) && !abort;
    ptId += (1 + (int)((float)vtkMath::Random()*cap)) )
      {
      x =  input->GetPoint(ptId);
      id = newPts->InsertNextPoint(x);
      outputPD->CopyData(pd,ptId,id);
      if ( ! (id % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5*id/numPts);
        abort = this->GetAbortExecute();
        }
      }
    }
  else // a.r. mode
    {
    for ( ptId = this->Offset;
    (ptId < numPts) && (id < (this->MaximumNumberOfPoints-1)) && !abort;
    ptId += this->OnRatio )
      {
      x =  input->GetPoint(ptId);
      id = newPts->InsertNextPoint(x);
      outputPD->CopyData(pd,ptId,id);
      if ( ! (id % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5*id/numPts);
        abort = this->GetAbortExecute();
        }
      }
    }

  // Generate vertices if requested
  //
  if ( this->GenerateVertices )
    {
    vtkCellArray *verts = vtkCellArray::New();
    verts->Allocate(verts->EstimateSize(1,id+1));
    verts->InsertNextCell(id+1);
    for ( ptId=0; ptId<(id+1) && !abort; ptId++)
      {
      if ( ! (ptId % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5+0.5*ptId/(id+1));
        abort = this->GetAbortExecute();
        }
      verts->InsertCellPoint(ptId);
      }
    output->SetVerts(verts);
    verts->Delete();
    }

  // Update ourselves
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->Squeeze();

  vtkDebugMacro(<<"Masked " << numPts << " original points to "
                << id+1 << " points");
}

//----------------------------------------------------------------------------
void vtkMaskPoints::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Generate Vertices: "
     << (this->GenerateVertices ? "On\n" : "Off\n");
  os << indent << "MaximumNumberOfPoints: "
     << this->MaximumNumberOfPoints << "\n";
  os << indent << "On Ratio: " << this->OnRatio << "\n";
  os << indent << "Offset: " << this->Offset << "\n";
  os << indent << "Random Mode: " << (this->RandomMode ? "On\n" : "Off\n");
}
<commit_msg>Empty input should not produce an error, just an empty output<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkMaskPoints.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/
#include "vtkMaskPoints.h"

#include "vtkCellArray.h"
#include "vtkDataSet.h"
#include "vtkMath.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyData.h"

vtkCxxRevisionMacro(vtkMaskPoints, "1.42");
vtkStandardNewMacro(vtkMaskPoints);

//----------------------------------------------------------------------------
vtkMaskPoints::vtkMaskPoints()
{
  this->OnRatio = 2;
  this->Offset = 0;
  this->RandomMode = 0;
  this->MaximumNumberOfPoints = VTK_LARGE_ID;
  this->GenerateVertices = 0;
}

//----------------------------------------------------------------------------
void vtkMaskPoints::Execute()
{
  vtkPoints *newPts;
  vtkPointData *pd;
  vtkIdType numNewPts;
  float *x;
  vtkIdType ptId, id;
  vtkPolyData *output = this->GetOutput();
  vtkPointData *outputPD = output->GetPointData();
  vtkDataSet *input= this->GetInput();
  vtkIdType numPts=input->GetNumberOfPoints();

  // Check input
  //
  vtkDebugMacro(<<"Masking points");

  if ( numPts < 1 )
    {
    return;
    }

  pd = input->GetPointData();
  id = 0;

  // Allocate space
  //
  numNewPts = numPts / this->OnRatio;
  if (numNewPts > this->MaximumNumberOfPoints)
    {
    numNewPts = this->MaximumNumberOfPoints;
    }
  newPts = vtkPoints::New();
  newPts->Allocate(numNewPts);
  outputPD->CopyAllocate(pd);

  // Traverse points and copy
  //
  int abort=0;
  vtkIdType progressInterval=numPts/20 +1;
  if ( this->RandomMode ) // retro mode
    {
    float cap;

    if (((float)numPts/this->OnRatio) > this->MaximumNumberOfPoints)
      {
      cap = 2.0*numPts/this->MaximumNumberOfPoints - 1;
      }
    else
      {
      cap = 2.0*this->OnRatio - 1;
      }

    for (ptId = this->Offset;
    (ptId < numPts) && (id < this->MaximumNumberOfPoints) && !abort;
    ptId += (1 + (int)((float)vtkMath::Random()*cap)) )
      {
      x =  input->GetPoint(ptId);
      id = newPts->InsertNextPoint(x);
      outputPD->CopyData(pd,ptId,id);
      if ( ! (id % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5*id/numPts);
        abort = this->GetAbortExecute();
        }
      }
    }
  else // a.r. mode
    {
    for ( ptId = this->Offset;
    (ptId < numPts) && (id < (this->MaximumNumberOfPoints-1)) && !abort;
    ptId += this->OnRatio )
      {
      x =  input->GetPoint(ptId);
      id = newPts->InsertNextPoint(x);
      outputPD->CopyData(pd,ptId,id);
      if ( ! (id % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5*id/numPts);
        abort = this->GetAbortExecute();
        }
      }
    }

  // Generate vertices if requested
  //
  if ( this->GenerateVertices )
    {
    vtkCellArray *verts = vtkCellArray::New();
    verts->Allocate(verts->EstimateSize(1,id+1));
    verts->InsertNextCell(id+1);
    for ( ptId=0; ptId<(id+1) && !abort; ptId++)
      {
      if ( ! (ptId % progressInterval) ) //abort/progress
        {
        this->UpdateProgress (0.5+0.5*ptId/(id+1));
        abort = this->GetAbortExecute();
        }
      verts->InsertCellPoint(ptId);
      }
    output->SetVerts(verts);
    verts->Delete();
    }

  // Update ourselves
  //
  output->SetPoints(newPts);
  newPts->Delete();

  output->Squeeze();

  vtkDebugMacro(<<"Masked " << numPts << " original points to "
                << id+1 << " points");
}

//----------------------------------------------------------------------------
void vtkMaskPoints::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "Generate Vertices: "
     << (this->GenerateVertices ? "On\n" : "Off\n");
  os << indent << "MaximumNumberOfPoints: "
     << this->MaximumNumberOfPoints << "\n";
  os << indent << "On Ratio: " << this->OnRatio << "\n";
  os << indent << "Offset: " << this->Offset << "\n";
  os << indent << "Random Mode: " << (this->RandomMode ? "On\n" : "Off\n");
}
<|endoftext|>


<commit_before>#include <vector>
#include <iostream>

#include <SFML/Graphics.hpp>

#include "Universe.hpp"
#include "Body.hpp"

#define MASS 10
#define BASE_LINE 2

using namespace sf;
using namespace std;

int main()
{
	unsigned int width(800), height(600);
	RenderWindow window(VideoMode(width, height), "Gravity Simulation by Johan");
	View view(FloatRect(0, 0, width, height));

	// Drawable elements
	Universe universe;
	VertexArray line(Lines, 2);
	CircleShape base_line(BASE_LINE);

	// Logic vars
	Clock timer;
	float delta_t(0);
	int mass(MASS);
	Vector2f mousePosition;
	Vector2f start, end;
	bool running = true;
	bool is_placing = false;
	bool is_moving = false;
	bool trace = false;
	bool control = false;
	bool shift = false;

	// Some inits
	line[0].color = Color::Blue;
	line[1].color = Color::Green;
	base_line.setFillColor(Color::Blue);
	window.setView(view);

	while (running)
	{
		Event evt;
		while (window.pollEvent(evt))
		{
			if (evt.type == Event::Closed)
			{
				running = false;
			}

			if (evt.type == Event::Resized)
			{
				view.setSize(evt.size.width, evt.size.height);
				window.setView(view);
			}

			if (evt.type == Event::KeyPressed)
			{
				if (evt.key.code == Keyboard::Escape)
				{
					running = false;
				}

				switch (evt.key.code)
				{
                case Keyboard::PageUp:
				case Keyboard::Add:
					mass *= 10;
					if (mass < 0)
					{
						mass = MASS;
					}
					cout << "Mass is now " << mass << endl;
					break;

                case Keyboard::PageDown:
				case Keyboard::Subtract:
					if (mass > 10)
					{
						mass /= 10;
					}
					else
					{
						mass = MASS;
					}
					cout << "Mass is now " << mass << endl;
					break;

				case Keyboard::T:
					trace = !trace;
					cout << "Trace mode " << (trace ? "enabled" : "disabled") << endl;
					break;

				case Keyboard::Space:
                    if (is_placing)
                    {
                        cout << "Planet placement cancelled" << endl;
                    }

                    is_placing = false;
                    break;

                case Keyboard::LControl:
                	control = true;
                	break;

                case Keyboard::LShift:
                	shift = true;
                	break;
				default:
					break;
				}
			}

			if (evt.type == Event::KeyReleased)
			{
				switch (evt.key.code)
				{
				case Keyboard::LControl:
					control = false;

				case Keyboard::LShift:
					shift = false;

				default:
					break;
				}
			}

			if (evt.type == Event::MouseButtonPressed)
			{
                if (shift)
                {
                    universe.eraseAt(Vector2f(evt.mouseButton.x, evt.mouseButton.y));
                }
                else if (control)
                {
                	is_moving = true;
                }
                else
                {
                    is_placing = true;

                    line[0].position = window.mapPixelToCoords(Vector2i(evt.mouseButton.x, evt.mouseButton.y));
                    line[1].position = line[0].position;
                    start = Vector2f(evt.mouseButton.x, evt.mouseButton.y);
                    end = start;

                    Vector2f base =
                    	window.mapPixelToCoords(Vector2i(evt.mouseButton.x - BASE_LINE, evt.mouseButton.y - BASE_LINE));
                    base_line.setPosition(base);
                }
            }

			if (evt.type == Event::MouseMoved)
			{
				if (is_placing)
				{
					line[1].position = window.mapPixelToCoords(Vector2i(evt.mouseMove.x, evt.mouseMove.y));
					end = Vector2f(evt.mouseMove.x, evt.mouseMove.y);
				}

				if (is_moving)
				{
					view.move(mousePosition - Vector2f(evt.mouseMove.x, evt.mouseMove.y));
					window.setView(view);
				}

				mousePosition = Vector2f(evt.mouseMove.x, evt.mouseMove.y);
			}

			if (evt.type == Event::MouseButtonReleased)
			{
				if (is_placing)
				{
					is_placing = false;

					Vector2f direction = end - start;

					Body p(Vector2f(0, 0), mass, direction);

					p.position = Vector2f(line[0].position.x,
							line[0].position.y);;

					universe.addPlanet(p);
				}

				if (is_moving)
				{
					is_moving = false;
				}
			}

			if (evt.type == Event::MouseWheelMoved)
			{
				float factor = (evt.mouseWheel.delta < 1 ? 1.10 : 0.90);
				view.zoom(factor);
				window.setView(view);
			}
		}

		if (!trace)
		{
			window.clear();
		}

		// Delta T
		delta_t = timer.restart().asSeconds();

		// Vector Preview - wow - need an arrow - hard
		if (is_placing)
		{
			window.draw(line);
			window.draw(base_line);
		}

		// Planets
		universe.move(delta_t);
		universe.draw(window);

		window.display();

		sleep(milliseconds(3));
	}

	return 0;
}
<commit_msg>added protodisk generation (press C)<commit_after>#include <vector>
#include <iostream>
#include <random>

#include <SFML/Graphics.hpp>

#include "Universe.hpp"
#include "Body.hpp"

#define MASS 10
#define BASE_LINE 2
#define CLUSTER_RADIUS 150
#define CLUSTER_NUMBER 1000

#ifdef _WIN32
	#define M_PI 3.14
#endif

using namespace sf;
using namespace std;

float gen_random_float();

int main()
{
	unsigned int width(800), height(600);
	RenderWindow window(VideoMode(width, height), "Gravity Simulation by Johan");
	View view(FloatRect(0, 0, width, height));

	// Drawable elements
	Universe universe;
	VertexArray line(Lines, 2);
	CircleShape base_line(BASE_LINE);

	// Logic vars
	Clock timer;
	float delta_t(0);
	int mass(MASS);
	Vector2f mousePosition;
	Vector2f start, end;
	bool running = true;
	bool is_placing = false;
	bool is_moving = false;
	bool trace = false;
	bool control = false;
	bool shift = false;

	// Some inits
	srand(time(0));
	line[0].color = Color::Blue;
	line[1].color = Color::Green;
	base_line.setFillColor(Color::Blue);
	window.setView(view);

	while (running)
	{
		Event evt;
		while (window.pollEvent(evt))
		{
			if (evt.type == Event::Closed)
			{
				running = false;
			}

			if (evt.type == Event::Resized)
			{
				view.setSize(evt.size.width, evt.size.height);
				window.setView(view);
			}

			if (evt.type == Event::KeyPressed)
			{
				if (evt.key.code == Keyboard::Escape)
				{
					running = false;
				}

				switch (evt.key.code)
				{
				case Keyboard::PageUp:
				case Keyboard::Add:
					mass *= 10;
					if (mass < 0)
					{
						mass = MASS;
					}
					cout << "Mass is now " << mass << endl;
					break;

				case Keyboard::PageDown:
				case Keyboard::Subtract:
					if (mass > 10)
					{
						mass /= 10;
					}
					else
					{
						mass = MASS;
					}
					cout << "Mass is now " << mass << endl;
					break;

				case Keyboard::T:
					trace = !trace;
					cout << "Trace mode " << (trace ? "enabled" : "disabled") << endl;
					break;

				case Keyboard::Space:
					if (is_placing)
					{
						cout << "Planet placement cancelled" << endl;
					}

					is_placing = false;
					break;

				case Keyboard::LControl:
					control = true;
					break;

				case Keyboard::LShift:
					shift = true;
					break;

				case Keyboard::C:
					{
						Vector2f pos_circle(view.getCenter());

						for (int i = 0; i < CLUSTER_NUMBER; i++)
						{
							float a(gen_random_float());
							float b(gen_random_float());

							if (b > a)
							{
								float t(a);
								a = b;
								b = t;
							}

							Vector2f pos_p(b*CLUSTER_RADIUS*cos(2*M_PI*a/b), b*CLUSTER_RADIUS*sin(2*M_PI*a/b));
							pos_p += pos_circle;

							universe.addPlanet(pos_p, 1, Vector2f());
						}
					}
					break;

				default:
					break;
				}
			}

			if (evt.type == Event::KeyReleased)
			{
				switch (evt.key.code)
				{
				case Keyboard::LControl:
					control = false;

				case Keyboard::LShift:
					shift = false;

				default:
					break;
				}
			}

			if (evt.type == Event::MouseButtonPressed)
			{
				if (shift)
				{
					universe.eraseAt(Vector2f(evt.mouseButton.x, evt.mouseButton.y));
				}
				else if (control)
				{
					is_moving = true;
				}
				else
				{
					is_placing = true;

					line[0].position = window.mapPixelToCoords(Vector2i(evt.mouseButton.x, evt.mouseButton.y));
					line[1].position = line[0].position;
					start = Vector2f(evt.mouseButton.x, evt.mouseButton.y);
					end = start;

					Vector2f base =
						window.mapPixelToCoords(Vector2i(evt.mouseButton.x - BASE_LINE, evt.mouseButton.y - BASE_LINE));
					base_line.setPosition(base);
				}
			}

			if (evt.type == Event::MouseMoved)
			{
				if (is_placing)
				{
					line[1].position = window.mapPixelToCoords(Vector2i(evt.mouseMove.x, evt.mouseMove.y));
					end = Vector2f(evt.mouseMove.x, evt.mouseMove.y);
				}

				if (is_moving)
				{
					view.move(mousePosition - Vector2f(evt.mouseMove.x, evt.mouseMove.y));
					window.setView(view);
				}

				mousePosition = Vector2f(evt.mouseMove.x, evt.mouseMove.y);
			}

			if (evt.type == Event::MouseButtonReleased)
			{
				if (is_placing)
				{
					is_placing = false;

					Vector2f direction = end - start;

					Body p(Vector2f(0, 0), mass, direction);

					p.position = Vector2f(line[0].position.x,
							line[0].position.y);;

					universe.addPlanet(p);
				}

				if (is_moving)
				{
					is_moving = false;
				}
			}

			if (evt.type == Event::MouseWheelMoved)
			{
				float factor = (evt.mouseWheel.delta < 1 ? 1.10 : 0.90);
				view.zoom(factor);
				window.setView(view);
			}
		}

		if (!trace)
		{
			window.clear();
		}

		// Delta T
		delta_t = timer.restart().asSeconds();

		// Vector Preview - wow - need an arrow - hard
		if (is_placing)
		{
			window.draw(line);
			window.draw(base_line);
		}

		// Planets
		universe.move(delta_t);
		universe.draw(window);

		window.display();

		sleep(milliseconds(3));
	}

	return 0;
}

float gen_random_float()
{
	static mt19937 engine(time(nullptr));
	static uniform_real_distribution<float> distribution(0.0f, 1.0f);

	static auto gen = std::bind(distribution, engine);

	return gen();
}<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbTrainImagesClassifier.h"

#include <iostream>
#include "otbCommandLineArgumentParser.h"

//Image
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbListSampleGenerator.h"
//#include "otbTypeManager.h"

// ListSample
#include "itkListSample.h"
#include "itkVariableLengthVector.h"
#include "itkFixedArray.h"

// SVM estimator
#include "otbSVMSampleListModelEstimator.h"

// Statistic XML Reader
#include "otbStatisticsXMLFileReader.h"

// Validation
#include "otbSVMClassifier.h"
#include "otbConfusionMatrixCalculator.h"

#include "itkTimeProbe.h"
#include "otbStandardFilterWatcher.h"

// Normalize the samples
#include "otbShiftScaleSampleListFilter.h"

// List sample concatenation
#include "otbConcatenateSampleListFilter.h"

// Balancing ListSample
#include "otbListSampleToBalancedListSampleFilter.h"

namespace otb
{

int TrainImagesClassifier::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("TrainImagesClassifier");
  descriptor->SetDescription("Perform SVM training from multiple input images and multiple vector data.");
  descriptor->AddOptionNParams("InputImages", "A list of images",
                               "in", true, ApplicationDescriptor::InputImage);
  descriptor->AddOptionNParams("VectorDataSamples", "Vector Data of sample used to train the estimator",
                               "vd", true, ApplicationDescriptor::FileName);
  descriptor->AddOption("ImagesStatistics", "XML file containing mean and variance of input images.",
                        "is", 1, false, ApplicationDescriptor::FileName);
  descriptor->AddOption("Output", "Output SVM model",
                        "out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("Margin", "Margin for SVM learning.",
                        "m", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("Balancing", "Balance and grow the training set.",
                        "b", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("SVM_Kernel", "Type of kernel use to estimate SVM model : 0 = LINEAR (default), 1 = RBF,  2 = POLY, 3 = SIGMOID",
                        "k", 1, false, ApplicationDescriptor::Integer);
  return EXIT_SUCCESS;
}

int TrainImagesClassifier::Execute(otb::ApplicationOptionsResult* parseResult)
{
  // Input Image
  //typedef double                                          ValueType;
  //typedef unsigned short                                  PixelType; // def by manuel
  typedef float                                           PixelType;
  typedef otb::VectorImage<PixelType,2>                   VectorImageType;
  typedef otb::Image<PixelType,2>                         ImageType;
  typedef otb::ImageFileReader<VectorImageType>           ReaderType;

  // Training vectordata
  typedef otb::VectorData<>                               VectorDataType;
  typedef otb::VectorDataFileReader<VectorDataType>       VectorDataReaderType;
  typedef itk::VariableLengthVector<PixelType>            MeasurementType;

  // SampleList manipulation
  typedef otb::ListSampleGenerator<VectorImageType, VectorDataType> ListSampleGeneratorType;

  typedef ListSampleGeneratorType::ListSampleType           ListSampleType;
  typedef ListSampleGeneratorType::LabelType                LabelType;
  typedef ListSampleGeneratorType::ListLabelType            LabelListSampleType;
  typedef otb::Statistics::ConcatenateSampleListFilter
      <ListSampleType>                                      ConcatenateListSampleFilterType;
  typedef otb::Statistics::ConcatenateSampleListFilter
      <LabelListSampleType>                                 ConcatenateLabelListSampleFilterType;

  // Statistic XML file Reader
  typedef otb::StatisticsXMLFileReader<MeasurementType>     StatisticsReader;

  typedef otb::Statistics::ListSampleToBalancedListSampleFilter<
      ListSampleType, LabelListSampleType>                  BalancingListSampleFilterType;

  typedef otb::Statistics::ShiftScaleSampleListFilter<
      ListSampleType, ListSampleType>                       ShiftScaleFilterType;

  // SVM Estimator
  typedef otb::Functor::VariableLengthVectorToMeasurementVectorFunctor<
      MeasurementType>                                      MeasurementVectorFunctorType;
  typedef otb::SVMSampleListModelEstimator<
      ListSampleType,
      LabelListSampleType,
      MeasurementVectorFunctorType>                         SVMEstimatorType;
  typedef otb::SVMClassifier<ListSampleType, LabelType::ValueType>     ClassifierType;

  typedef otb::ConfusionMatrixCalculator<LabelListSampleType,
      LabelListSampleType>                                  ConfusionMatrixCalculatorType;
  typedef ClassifierType::OutputType ClassifierOutputType;

  //Create training and validation for list samples and label list samples
  ConcatenateLabelListSampleFilterType::Pointer concatenateTrainingLabels =
                                                  ConcatenateLabelListSampleFilterType::New();
  ConcatenateListSampleFilterType::Pointer concatenateTrainingSamples =
                                             ConcatenateListSampleFilterType::New();
  ConcatenateLabelListSampleFilterType::Pointer concatenateValidationLabels =
                                                  ConcatenateLabelListSampleFilterType::New();
  ConcatenateListSampleFilterType::Pointer concatenateValidationSamples =
                                            ConcatenateListSampleFilterType::New();

  //Set the size of training and validation set
  //TODO use default parameters of the filter?
  const long int maxTrainingSize = 100;
  const long int maxValidationSize = 100;
  const double validationTrainingProportion = 0.5;

  unsigned int nbBands = 0;
  //Iterate over all input images
  for(int imgIndex = 0; imgIndex<parseResult->GetNumberOfParameters("InputImages");++imgIndex)
    {
    // Read the image
    ReaderType::Pointer    reader  = ReaderType::New();
    reader->SetFileName(parseResult->GetParameterString("InputImages",imgIndex));
    reader->UpdateOutputInformation();

    std::cout<<"Processing image ("<<imgIndex<<"): "<<reader->GetFileName()<<std::endl;

    if (imgIndex == 0)
      {
      nbBands = reader->GetOutput()->GetNumberOfComponentsPerPixel();
      }

    // read the Vectordata
    VectorDataReaderType::Pointer vdreader = VectorDataReaderType::New();
    vdreader->SetFileName(parseResult->GetParameterString("VectorDataSamples",imgIndex));
    vdreader->Update();
    std::cout<<"Set VectorData filename: "<< parseResult->GetParameterString("VectorDataSamples",imgIndex) <<std::endl;

    //Sample list generator
    ListSampleGeneratorType::Pointer sampleGenerator = ListSampleGeneratorType::New();

    //Set inputs of the sample generator
    //TODO the ListSampleGenerator perform UpdateOutputData over the input image (need a persistent implementation)
    sampleGenerator->SetInput(reader->GetOutput());
    sampleGenerator->SetInputVectorData(vdreader->GetOutput());
    sampleGenerator->SetMaxTrainingSize(maxTrainingSize);
    sampleGenerator->SetMaxValidationSize(maxValidationSize);
    sampleGenerator->SetValidationTrainingProportion(validationTrainingProportion);

    sampleGenerator->SetClassKey("Class");

    sampleGenerator->Update();

    std::cout << "output size: " << sampleGenerator->GetTrainingListLabel()->GetMeasurementVectorSize() <<std::endl;

    //Concatenate training and validation samples from the image
    concatenateTrainingLabels->AddInput(sampleGenerator->GetTrainingListLabel());
    concatenateTrainingSamples->AddInput(sampleGenerator->GetTrainingListSample());
    concatenateValidationLabels->AddInput(sampleGenerator->GetValidationListLabel());
    concatenateValidationSamples->AddInput(sampleGenerator->GetValidationListSample());
    }

  // Update
  concatenateTrainingSamples->Update();
  concatenateTrainingLabels->Update();
  concatenateValidationSamples->Update();
  concatenateValidationLabels->Update();

  // Normalize the samples
  // Read the mean and variance form the XML file (estimate with the otbEstimateImagesStatistics application)
  MeasurementType  meanMeasurentVector;
  MeasurementType  varianceMeasurentVector;
  if(parseResult->IsOptionPresent("ImagesStatistics"))
    {
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    statisticsReader->SetFileName(parseResult->GetParameterString("ImagesStatistics").c_str());
    meanMeasurentVector     = statisticsReader->GetStatisticVectorByName("mean");
    varianceMeasurentVector = statisticsReader->GetStatisticVectorByName("variance");
    }
  else
    {
    meanMeasurentVector.SetSize(nbBands);
    meanMeasurentVector.Fill(0.);
    varianceMeasurentVector.SetSize(nbBands);
    varianceMeasurentVector.Fill(1.);
    }

  std::cout << "MeanVector: " << meanMeasurentVector  << std::endl;
  std::cout << "Variance Vector: " << varianceMeasurentVector  << std::endl;

  // Shift scale the samples
  ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New();
  trainingShiftScaleFilter->SetInput(concatenateTrainingSamples->GetOutput());
  trainingShiftScaleFilter->SetShifts(meanMeasurentVector);
  trainingShiftScaleFilter->SetScales(varianceMeasurentVector);
  trainingShiftScaleFilter->Update();

  ShiftScaleFilterType::Pointer validationShiftScaleFilter = ShiftScaleFilterType::New();
  validationShiftScaleFilter->SetInput(concatenateValidationSamples->GetOutput());
  validationShiftScaleFilter->SetShifts(meanMeasurentVector);
  validationShiftScaleFilter->SetScales(varianceMeasurentVector);
  validationShiftScaleFilter->Update();

  ListSampleType::Pointer listSample;
  LabelListSampleType::Pointer labelListSample;

  if(parseResult->IsOptionPresent("Balancing"))
    {
    // Balance the list sample.
    std::cout<<"Number of training samples before balancing: "<<concatenateTrainingSamples->GetOutputSampleList()->Size()<<std::endl;
    BalancingListSampleFilterType::Pointer balancingFilter = BalancingListSampleFilterType::New();
    balancingFilter->SetInput(trainingShiftScaleFilter->GetOutput()/*GetOutputSampleList()*/);
    balancingFilter->SetInputLabel(concatenateTrainingLabels->GetOutput()/*GetOutputSampleList()*/);
    balancingFilter->SetBalancingFactor(parseResult->GetParameterUInt("Balancing"));
    balancingFilter->Update();
    listSample = balancingFilter->GetOutputSampleList();
    labelListSample = balancingFilter->GetOutputLabelSampleList();
    std::cout<<"Number of samples after balancing: "<<balancingFilter->GetOutputSampleList()->Size()<<std::endl;
    }
  else
    {
    listSample = trainingShiftScaleFilter->GetOutputSampleList();
    labelListSample = concatenateTrainingLabels->GetOutputSampleList();
    std::cout<<"Number of training samples: "<<concatenateTrainingSamples->GetOutputSampleList()->Size()<<std::endl;
    }

  // split the data set into training/validation set
  ListSampleType::Pointer trainingListSample = listSample;
  ListSampleType::Pointer validationListSample = validationShiftScaleFilter->GetOutputSampleList();
  LabelListSampleType::Pointer trainingLabeledListSample = labelListSample;
  LabelListSampleType::Pointer validationLabeledListSample = concatenateValidationLabels->GetOutputSampleList();

  std::cout<<"Size of training set: "<<trainingListSample->Size()<<std::endl;
  std::cout<<"Size of validation set: "<<validationListSample->Size()<<std::endl;
  std::cout<<"Size of labeled training set: "<<trainingLabeledListSample->Size()<<std::endl;
  std::cout<<"Size of labeled validation set: "<<validationLabeledListSample->Size()<<std::endl;

  // Estimate SVM model
  SVMEstimatorType::Pointer svmestimator = SVMEstimatorType::New();
  svmestimator->SetInputSampleList(trainingListSample);
  svmestimator->SetTrainingSampleList(trainingLabeledListSample);
  svmestimator->SetParametersOptimization(true);

  //TODO : Add some other options

  if(parseResult->IsOptionPresent("Margin"))
    {
    svmestimator->SetC(parseResult->GetParameterDouble("Margin"));
    }

  if(parseResult->IsOptionPresent("Margin"))
    {
    switch (parseResult->GetParameterInt("SVM_Kernel"))
      {
      case 0: // LINEAR
        svmestimator->SetKernelType(LINEAR);
        break;
      case 1: // RBF
        svmestimator->SetKernelType(RBF);
        break;
      case 2: // POLY
        svmestimator->SetKernelType(POLY);
        break;
      case 3: // SIGMOID
        svmestimator->SetKernelType(SIGMOID);
        break;
      default: // DEFAULT = LINEAR
        svmestimator->SetKernelType(LINEAR);
        break;
      }
    }
  else
    {
    svmestimator->SetKernelType(LINEAR);
    }
  svmestimator->Update();
  svmestimator->GetModel()->SaveModel(parseResult->GetParameterString("Output"));

  std::cout<<"Learning done -> Final SVM accuracy: " << svmestimator->GetFinalCrossValidationAccuracy() <<std::endl;

  //--------------------------
  // Performances estimation
  ClassifierType::Pointer validationClassifier = ClassifierType::New();
  validationClassifier->SetSample(validationListSample);
  validationClassifier->SetNumberOfClasses(svmestimator->GetModel()->GetNumberOfClasses());
  validationClassifier->SetModel(svmestimator->GetModel());
  validationClassifier->Update();

  // Estimate performances
  ClassifierOutputType::ConstIterator it = validationClassifier->GetOutput()->Begin();
  ClassifierOutputType::ConstIterator itEnd = validationClassifier->GetOutput()->End();

  LabelListSampleType::Pointer classifierListLabel = LabelListSampleType::New();

  while (it != itEnd)
    {
    // Due to a bug in SVMClassifier, outlier in one-class SVM are labeled with unsigned int max
    classifierListLabel->PushBack(
        it.GetClassLabel() == itk::NumericTraits<unsigned int>::max() ? 2 : it.GetClassLabel()
                                 );
    ++it;
    }

  ConfusionMatrixCalculatorType::Pointer confMatCalc = ConfusionMatrixCalculatorType::New();

  confMatCalc->SetReferenceLabels(validationLabeledListSample);
  confMatCalc->SetProducedLabels(classifierListLabel);

  confMatCalc->Update();

  std::cout<< "confusion matrix: \n" << confMatCalc->GetConfusionMatrix() << std::endl;

  std::cout << "Precision of the different class: " << confMatCalc->GetPrecisions() << std::endl;
  std::cout << "Recall of the different class: " << confMatCalc->GetRecalls() << std::endl;
  std::cout << "F-score of the different class: " << confMatCalc->GetFScores() << std::endl;
  std::cout << "Kappa index: " << confMatCalc->GetKappaIndex() << std::endl;

  // TODO: implement hyperplan distance classifier and performance validation (cf. object detection) ?

  return EXIT_SUCCESS;
}

}
<commit_msg>STYLE: clean code and enhance comments<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbTrainImagesClassifier.h"

#include <iostream>
#include "otbCommandLineArgumentParser.h"

//Image
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbVectorData.h"
#include "otbVectorDataFileReader.h"
#include "otbListSampleGenerator.h"
//#include "otbTypeManager.h"

// ListSample
#include "itkListSample.h"
#include "itkVariableLengthVector.h"
#include "itkFixedArray.h"

// SVM estimator
#include "otbSVMSampleListModelEstimator.h"

// Statistic XML Reader
#include "otbStatisticsXMLFileReader.h"

// Validation
#include "otbSVMClassifier.h"
#include "otbConfusionMatrixCalculator.h"

#include "itkTimeProbe.h"
#include "otbStandardFilterWatcher.h"

// Normalize the samples
#include "otbShiftScaleSampleListFilter.h"

// List sample concatenation
#include "otbConcatenateSampleListFilter.h"

// Balancing ListSample
#include "otbListSampleToBalancedListSampleFilter.h"

namespace otb
{

int TrainImagesClassifier::Describe(ApplicationDescriptor* descriptor)
{
  descriptor->SetName("TrainImagesClassifier");
  descriptor->SetDescription("Perform SVM training from multiple input images and multiple vector data.");
  descriptor->AddOptionNParams("InputImages", "A list of images",
                               "in", true, ApplicationDescriptor::InputImage);
  descriptor->AddOptionNParams("VectorDataSamples", "Vector Data of sample used to train the estimator",
                               "vd", true, ApplicationDescriptor::FileName);
  descriptor->AddOption("ImagesStatistics", "XML file containing mean and variance of input images.",
                        "is", 1, false, ApplicationDescriptor::FileName);
  descriptor->AddOption("Output", "Output SVM model",
                        "out", 1, true, ApplicationDescriptor::FileName);
  descriptor->AddOption("Margin", "Margin for SVM learning.",
                        "m", 1, false, ApplicationDescriptor::Real);
  descriptor->AddOption("Balancing", "Balance and grow the training set.",
                        "b", 1, false, ApplicationDescriptor::Integer);
  descriptor->AddOption("SVM_Kernel", "Type of kernel use to estimate SVM model : 0 = LINEAR (default), 1 = RBF,  2 = POLY, 3 = SIGMOID",
                        "k", 1, false, ApplicationDescriptor::Integer);
  return EXIT_SUCCESS;
}

int TrainImagesClassifier::Execute(otb::ApplicationOptionsResult* parseResult)
{
  // Input Image
  //typedef double                                          ValueType;
  typedef float                                           PixelType;
  typedef otb::VectorImage<PixelType,2>                   VectorImageType;
  typedef otb::Image<PixelType,2>                         ImageType;
  typedef otb::ImageFileReader<VectorImageType>           ReaderType;

  // Training vectordata
  typedef otb::VectorData<>                               VectorDataType;
  typedef otb::VectorDataFileReader<VectorDataType>       VectorDataReaderType;
  typedef itk::VariableLengthVector<PixelType>            MeasurementType;

  // SampleList manipulation
  typedef otb::ListSampleGenerator<VectorImageType, VectorDataType> ListSampleGeneratorType;

  typedef ListSampleGeneratorType::ListSampleType           ListSampleType;
  typedef ListSampleGeneratorType::LabelType                LabelType;
  typedef ListSampleGeneratorType::ListLabelType            LabelListSampleType;
  typedef otb::Statistics::ConcatenateSampleListFilter
      <ListSampleType>                                      ConcatenateListSampleFilterType;
  typedef otb::Statistics::ConcatenateSampleListFilter
      <LabelListSampleType>                                 ConcatenateLabelListSampleFilterType;

  // Statistic XML file Reader
  typedef otb::StatisticsXMLFileReader<MeasurementType>     StatisticsReader;

  // Enhance List Sample
  typedef otb::Statistics::ListSampleToBalancedListSampleFilter<
      ListSampleType, LabelListSampleType>                  BalancingListSampleFilterType;
  typedef otb::Statistics::ShiftScaleSampleListFilter<
      ListSampleType, ListSampleType>                       ShiftScaleFilterType;

  // SVM Estimator
  typedef otb::Functor::VariableLengthVectorToMeasurementVectorFunctor<
      MeasurementType>                                      MeasurementVectorFunctorType;
  typedef otb::SVMSampleListModelEstimator<
      ListSampleType,
      LabelListSampleType,
      MeasurementVectorFunctorType>                         SVMEstimatorType;
  typedef otb::SVMClassifier<ListSampleType, LabelType::ValueType>     ClassifierType;

  // Estimate performance on validation sample
  typedef otb::ConfusionMatrixCalculator<LabelListSampleType,
      LabelListSampleType>                                  ConfusionMatrixCalculatorType;
  typedef ClassifierType::OutputType ClassifierOutputType;

  //Create training and validation for list samples and label list samples
  ConcatenateLabelListSampleFilterType::Pointer concatenateTrainingLabels =
                                                  ConcatenateLabelListSampleFilterType::New();
  ConcatenateListSampleFilterType::Pointer concatenateTrainingSamples =
                                             ConcatenateListSampleFilterType::New();
  ConcatenateLabelListSampleFilterType::Pointer concatenateValidationLabels =
                                                  ConcatenateLabelListSampleFilterType::New();
  ConcatenateListSampleFilterType::Pointer concatenateValidationSamples =
                                            ConcatenateListSampleFilterType::New();

  //Set the size of training and validation set
  //TODO use default parameters of the filter?
  const long int maxTrainingSize = 100;
  const long int maxValidationSize = 100;
  const double validationTrainingProportion = 0.5;

  //--------------------------
  // Load measurements from images
  unsigned int nbBands = 0;
  //Iterate over all input images
  for(int imgIndex = 0; imgIndex<parseResult->GetNumberOfParameters("InputImages");++imgIndex)
    {
    // Read the image
    ReaderType::Pointer    reader  = ReaderType::New();
    reader->SetFileName(parseResult->GetParameterString("InputImages",imgIndex));
    reader->UpdateOutputInformation();

    std::cout<<"Processing image ("<<imgIndex<<"): "<<reader->GetFileName()<<std::endl;

    if (imgIndex == 0)
      {
      nbBands = reader->GetOutput()->GetNumberOfComponentsPerPixel();
      }

    // read the Vectordata
    VectorDataReaderType::Pointer vdreader = VectorDataReaderType::New();
    vdreader->SetFileName(parseResult->GetParameterString("VectorDataSamples",imgIndex));
    vdreader->Update();
    std::cout<<"Set VectorData filename: "<< parseResult->GetParameterString("VectorDataSamples",imgIndex) <<std::endl;

    //Sample list generator
    ListSampleGeneratorType::Pointer sampleGenerator = ListSampleGeneratorType::New();

    //Set inputs of the sample generator
    //TODO the ListSampleGenerator perform UpdateOutputData over the input image (need a persistent implementation)
    sampleGenerator->SetInput(reader->GetOutput());
    sampleGenerator->SetInputVectorData(vdreader->GetOutput());
    sampleGenerator->SetMaxTrainingSize(maxTrainingSize);
    sampleGenerator->SetMaxValidationSize(maxValidationSize);
    sampleGenerator->SetValidationTrainingProportion(validationTrainingProportion);

    sampleGenerator->SetClassKey("Class");

    sampleGenerator->Update();

    std::cout << "output size: " << sampleGenerator->GetTrainingListLabel()->GetMeasurementVectorSize() <<std::endl;

    //Concatenate training and validation samples from the image
    concatenateTrainingLabels->AddInput(sampleGenerator->GetTrainingListLabel());
    concatenateTrainingSamples->AddInput(sampleGenerator->GetTrainingListSample());
    concatenateValidationLabels->AddInput(sampleGenerator->GetValidationListLabel());
    concatenateValidationSamples->AddInput(sampleGenerator->GetValidationListSample());
    }

  // Update
  concatenateTrainingSamples->Update();
  concatenateTrainingLabels->Update();
  concatenateValidationSamples->Update();
  concatenateValidationLabels->Update();

  //--------------------------
  // Normalize the samples
  // Read the mean and variance form the XML file (estimate with the otbEstimateImagesStatistics application)
  MeasurementType  meanMeasurentVector;
  MeasurementType  varianceMeasurentVector;
  if(parseResult->IsOptionPresent("ImagesStatistics"))
    {
    StatisticsReader::Pointer  statisticsReader = StatisticsReader::New();
    statisticsReader->SetFileName(parseResult->GetParameterString("ImagesStatistics").c_str());
    meanMeasurentVector     = statisticsReader->GetStatisticVectorByName("mean");
    varianceMeasurentVector = statisticsReader->GetStatisticVectorByName("variance");
    }
  else
    {
    meanMeasurentVector.SetSize(nbBands);
    meanMeasurentVector.Fill(0.);
    varianceMeasurentVector.SetSize(nbBands);
    varianceMeasurentVector.Fill(1.);
    }

  std::cout << "MeanVector: " << meanMeasurentVector  << std::endl;
  std::cout << "Variance Vector: " << varianceMeasurentVector  << std::endl;

  // Shift scale the samples
  ShiftScaleFilterType::Pointer trainingShiftScaleFilter = ShiftScaleFilterType::New();
  trainingShiftScaleFilter->SetInput(concatenateTrainingSamples->GetOutput());
  trainingShiftScaleFilter->SetShifts(meanMeasurentVector);
  trainingShiftScaleFilter->SetScales(varianceMeasurentVector);
  trainingShiftScaleFilter->Update();

  ShiftScaleFilterType::Pointer validationShiftScaleFilter = ShiftScaleFilterType::New();
  validationShiftScaleFilter->SetInput(concatenateValidationSamples->GetOutput());
  validationShiftScaleFilter->SetShifts(meanMeasurentVector);
  validationShiftScaleFilter->SetScales(varianceMeasurentVector);
  validationShiftScaleFilter->Update();

  ListSampleType::Pointer listSample;
  LabelListSampleType::Pointer labelListSample;

  //--------------------------
  // Balancing training sample (if needed)
  if(parseResult->IsOptionPresent("Balancing"))
    {
    // Balance the list sample.
    std::cout<<"Number of training samples before balancing: "<<concatenateTrainingSamples->GetOutputSampleList()->Size()<<std::endl;
    BalancingListSampleFilterType::Pointer balancingFilter = BalancingListSampleFilterType::New();
    balancingFilter->SetInput(trainingShiftScaleFilter->GetOutput()/*GetOutputSampleList()*/);
    balancingFilter->SetInputLabel(concatenateTrainingLabels->GetOutput()/*GetOutputSampleList()*/);
    balancingFilter->SetBalancingFactor(parseResult->GetParameterUInt("Balancing"));
    balancingFilter->Update();
    listSample = balancingFilter->GetOutputSampleList();
    labelListSample = balancingFilter->GetOutputLabelSampleList();
    std::cout<<"Number of samples after balancing: "<<balancingFilter->GetOutputSampleList()->Size()<<std::endl;
    }
  else
    {
    listSample = trainingShiftScaleFilter->GetOutputSampleList();
    labelListSample = concatenateTrainingLabels->GetOutputSampleList();
    std::cout<<"Number of training samples: "<<concatenateTrainingSamples->GetOutputSampleList()->Size()<<std::endl;
    }

  //--------------------------
  // Split the data set into training/validation set
  ListSampleType::Pointer trainingListSample = listSample;
  ListSampleType::Pointer validationListSample = validationShiftScaleFilter->GetOutputSampleList();
  LabelListSampleType::Pointer trainingLabeledListSample = labelListSample;
  LabelListSampleType::Pointer validationLabeledListSample = concatenateValidationLabels->GetOutputSampleList();

  std::cout<<"Size of training set: "<<trainingListSample->Size()<<std::endl;
  std::cout<<"Size of validation set: "<<validationListSample->Size()<<std::endl;
  std::cout<<"Size of labeled training set: "<<trainingLabeledListSample->Size()<<std::endl;
  std::cout<<"Size of labeled validation set: "<<validationLabeledListSample->Size()<<std::endl;

  //--------------------------
  // Estimate SVM model
  SVMEstimatorType::Pointer svmestimator = SVMEstimatorType::New();
  svmestimator->SetInputSampleList(trainingListSample);
  svmestimator->SetTrainingSampleList(trainingLabeledListSample);
  svmestimator->SetParametersOptimization(true);

  //TODO : Add some other options

  if(parseResult->IsOptionPresent("Margin"))
    {
    svmestimator->SetC(parseResult->GetParameterDouble("Margin"));
    }

  if(parseResult->IsOptionPresent("Margin"))
    {
    switch (parseResult->GetParameterInt("SVM_Kernel"))
      {
      case 0: // LINEAR
        svmestimator->SetKernelType(LINEAR);
        break;
      case 1: // RBF
        svmestimator->SetKernelType(RBF);
        break;
      case 2: // POLY
        svmestimator->SetKernelType(POLY);
        break;
      case 3: // SIGMOID
        svmestimator->SetKernelType(SIGMOID);
        break;
      default: // DEFAULT = LINEAR
        svmestimator->SetKernelType(LINEAR);
        break;
      }
    }
  else
    {
    svmestimator->SetKernelType(LINEAR);
    }
  svmestimator->Update();
  svmestimator->GetModel()->SaveModel(parseResult->GetParameterString("Output"));

  std::cout<<"Learning done -> Final SVM accuracy: " << svmestimator->GetFinalCrossValidationAccuracy() <<std::endl;

  //--------------------------
  // Performances estimation
  ClassifierType::Pointer validationClassifier = ClassifierType::New();
  validationClassifier->SetSample(validationListSample);
  validationClassifier->SetNumberOfClasses(svmestimator->GetModel()->GetNumberOfClasses());
  validationClassifier->SetModel(svmestimator->GetModel());
  validationClassifier->Update();

  // Estimate performances
  ClassifierOutputType::ConstIterator it = validationClassifier->GetOutput()->Begin();
  ClassifierOutputType::ConstIterator itEnd = validationClassifier->GetOutput()->End();

  LabelListSampleType::Pointer classifierListLabel = LabelListSampleType::New();

  while (it != itEnd)
    {
    // Due to a bug in SVMClassifier, outlier in one-class SVM are labeled with unsigned int max
    classifierListLabel->PushBack(
        it.GetClassLabel() == itk::NumericTraits<unsigned int>::max() ? 2 : it.GetClassLabel()
                                 );
    ++it;
    }

  ConfusionMatrixCalculatorType::Pointer confMatCalc = ConfusionMatrixCalculatorType::New();

  confMatCalc->SetReferenceLabels(validationLabeledListSample);
  confMatCalc->SetProducedLabels(classifierListLabel);

  confMatCalc->Update();

  std::cout<< "confusion matrix: \n" << confMatCalc->GetConfusionMatrix() << std::endl;

  std::cout << "Precision of the different class: " << confMatCalc->GetPrecisions() << std::endl;
  std::cout << "Recall of the different class: " << confMatCalc->GetRecalls() << std::endl;
  std::cout << "F-score of the different class: " << confMatCalc->GetFScores() << std::endl;
  std::cout << "Kappa index: " << confMatCalc->GetKappaIndex() << std::endl;

  // TODO: implement hyperplan distance classifier and performance validation (cf. object detection) ?

  return EXIT_SUCCESS;
}

}
<|endoftext|>


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

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

//  Software Guide : BeginLatex
//
//  Isosurface extraction has attracted continuous interest since the early
//  days of image analysis. Although it is commonly associated with image
//  segmentation, isosurface extraction is not in itself a segmentation
//  technique, instead it is a transformation that changes the way a
//  segmentation is represented. In its most common form, isosurface extraction
//  is the equivalent of image thresholding followed by surface extraction.
//
//  Probably the most widely known method of surface extraction is the
//  \emph{Marching Cubes} algorithm~\cite{MarchingCubes}. Although it has been
//  followed by a number of variants~\cite{VTKBook}, Marching Cubes has become
//  an icon on medical image processing. The following example illustrates how
//  to perform isosurface extraction in ITK using an algorithm similar to
//  Marching Cubes~\footnote{Note that the Marching Cubes algorithm is covered
//  by a patent that expired on June 5th 2005}.
//
//  Software Guide : EndLatex

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageRegionIterator.h"

// Software Guide : BeginLatex
//
// The representation of unstructured data in ITK is done with the
// \doxygen{Mesh}, that allows to represent N-Dimensional grids of varied
// topology. It is natural then that the filter that extracts isosurfaces from
// an Image will produce a Mesh as output.
//
// We initiate our example by including the header files of the isosurface
// extraction filter and the Mesh.
//
// \index{Marching Cubes}
// \index{Isosurface extraction!Mesh}
// \index{BinaryMask3DMeshSource!Header}
// \index{Mesh!Isosurface extraction}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkBinaryMask3DMeshSource.h"
#include "itkMesh.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[] )
{

  if( argc < 3 )
    {
    std::cerr << "Usage: IsoSurfaceExtraction  inputImageFile   isoValue " << std::endl;
    return EXIT_FAILURE;
    }

// Software Guide : BeginLatex
//
// We define then the pixel type and dimension of the image from which we are
// going to extract the isosurface.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const unsigned int Dimension = 3;
  typedef unsigned short  PixelType;

  typedef itk::Image< PixelType, Dimension >   ImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// With the same image type we instantiate the type of an ImageFileReader and
// construct one with the purpose of reading in the input image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< ImageType >    ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
// Software Guide : EndCodeSnippet

  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & exp )
    {
    std::cerr << "Exception thrown while reading the input file " << std::endl;
    std::cerr << exp << std::endl;
    return EXIT_FAILURE;
    }

// Software Guide : BeginLatex
//
// The type of the \doxygen{Mesh} is instantiated by specifying the type to be
// associated with the pixel value of the Mesh nodes. Having declared the Image
// type and the Mesh type we can also instantiate the isosurface extraction
// filter, and construct one by invoking its \code{New()} method.
//
// \index{BinaryMask3DMeshSource!Instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::Mesh<double>                         MeshType;

  typedef itk::BinaryMask3DMeshSource< ImageType, MeshType >   MeshSourceType;

  MeshSourceType::Pointer meshSource = MeshSourceType::New();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// In this particular example, the value to be used for selecting the
// isosurface is read from the command line arguments and passed to the filter
// by using the \code{SetObjectValue()} method. Note that at this point this is
// equivalent to performing thresholding on the input image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const PixelType isovalue = static_cast<PixelType>( atof( argv[2] ) );

  meshSource->SetObjectValue( isovalue );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The input to the isosurface extraction filter is taken from the output of
// the image reader.
//
// \index{BinaryMask3DMeshSource!SetInput}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  meshSource->SetInput( reader->GetOutput() );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Finally we trigger the execution of the pipeline by invoking the
// \code{Update()} method. Note that given that the pipeline may throw
// exception, this call must be place inside a \code{try/catch} block.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  try
    {
    meshSource->Update();
    }
  catch( itk::ExceptionObject & exp )
    {
    std::cerr << "Exception thrown during Update() " << std::endl;
    std::cerr << exp << std::endl;
    return EXIT_FAILURE;
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// As a way of taking a look at the output Mesh we print out here its number of
// Nodes and Cells.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "Nodes = " << meshSource->GetNumberOfNodes() << std::endl;
  std::cout << "Cells = " << meshSource->GetNumberOfCells() << std::endl;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// This resulting Mesh could be used as input for a deformable model
// segmentation algorithm, or it could be converted to a format suitable for
// visualization in an interactive application.
//
// Software Guide : EndLatex

  return EXIT_SUCCESS;
}

<commit_msg>STYLE: Clarifying that this filter does not expect an isovalue but an object value.<commit_after>/*=========================================================================

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

//  Software Guide : BeginLatex
//
//  Surface extraction has attracted continuous interest since the early days
//  of image analysis, in particular on the context of medical applications.
//  Although it is commonly associated with image segmentation, surface
//  extraction is not in itself a segmentation technique, instead it is a
//  transformation that changes the way a segmentation is represented. In its
//  most common form, isosurface extraction is the equivalent of image
//  thresholding followed by surface extraction.
//
//  Probably the most widely known method of surface extraction is the
//  \emph{Marching Cubes} algorithm~\cite{MarchingCubes}. Although it has been
//  followed by a number of variants~\cite{VTKBook}, Marching Cubes has become
//  an icon on medical image processing. The following example illustrates how
//  to perform surface extraction in ITK using an algorithm similar to Marching
//  Cubes~\footnote{Note that the Marching Cubes algorithm is covered by a
//  patent that expired on June 5th 2005.}.
//
//  Software Guide : EndLatex

#include "itkImageFileReader.h"

// Software Guide : BeginLatex
//
// The representation of unstructured data in ITK is done with the
// \doxygen{Mesh}, that allows to represent N-Dimensional grids of varied
// topology. It is natural then that the filter that extracts surfaces from
// an Image will produce a Mesh as output.
//
// We initiate our example by including the header files of the surface
// extraction filter, the image and the Mesh.
//
// \index{Marching Cubes}
// \index{Isosurface extraction!Mesh}
// \index{BinaryMask3DMeshSource!Header}
// \index{Mesh!Isosurface extraction}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
#include "itkBinaryMask3DMeshSource.h"
#include "itkImage.h"
#include "itkMesh.h"
// Software Guide : EndCodeSnippet

int main(int argc, char * argv[] )
{

  if( argc < 3 )
    {
    std::cerr << "Usage: IsoSurfaceExtraction  inputImageFile   objectValue " << std::endl;
    return EXIT_FAILURE;
    }

// Software Guide : BeginLatex
//
// We define then the pixel type and dimension of the image from which we are
// going to extract the surface.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const unsigned int Dimension = 3;
  typedef unsigned char  PixelType;

  typedef itk::Image< PixelType, Dimension >   ImageType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// With the same image type we instantiate the type of an ImageFileReader and
// construct one with the purpose of reading in the input image.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::ImageFileReader< ImageType >    ReaderType;
  ReaderType::Pointer reader = ReaderType::New();
  reader->SetFileName( argv[1] );
// Software Guide : EndCodeSnippet

  try
    {
    reader->Update();
    }
  catch( itk::ExceptionObject & exp )
    {
    std::cerr << "Exception thrown while reading the input file " << std::endl;
    std::cerr << exp << std::endl;
    return EXIT_FAILURE;
    }

// Software Guide : BeginLatex
//
// The type of the \doxygen{Mesh} is instantiated by specifying the type to be
// associated with the pixel value of the Mesh nodes. This particular pixel
// type happens to be irrelevant for the purpose of extracting the surface.
//
// \index{BinaryMask3DMeshSource!Instantiation}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::Mesh<double>                         MeshType;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Having declared the Image and Mesh types we can now instantiate the
// surface extraction filter, and construct one by invoking its \code{New()}
// method.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  typedef itk::BinaryMask3DMeshSource< ImageType, MeshType >   MeshSourceType;

  MeshSourceType::Pointer meshSource = MeshSourceType::New();
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// In this particular example, the pixel value to be associated to the object
// to be extracted is read from the command line arguments and it is passed to
// the filter by using the \code{SetObjectValue()} method. Note that this is
// different from the traditional isovalue used in the Marching Cubes
// algorithm.  In the case of the \code{BinaryMask3DMeshSource} filter, the
// object values defines the membership of pixels to the object from which the
// surface will be extracted. In other words, the surface will be surrounding
// all pixels with value equal to the ObjectValue parameter.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  const PixelType objectValue = static_cast<PixelType>( atof( argv[2] ) );

  meshSource->SetObjectValue( objectValue );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// The input to the surface extraction filter is taken from the output of
// the image reader.
//
// \index{BinaryMask3DMeshSource!SetInput}
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  meshSource->SetInput( reader->GetOutput() );
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// Finally we trigger the execution of the pipeline by invoking the
// \code{Update()} method. Note that given that the pipeline may throw
// exception, this call must be place inside a \code{try/catch} block.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  try
    {
    meshSource->Update();
    }
  catch( itk::ExceptionObject & exp )
    {
    std::cerr << "Exception thrown during Update() " << std::endl;
    std::cerr << exp << std::endl;
    return EXIT_FAILURE;
    }
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// As a way of taking a look at the output Mesh we print out here its number of
// Nodes and Cells.
//
// Software Guide : EndLatex

// Software Guide : BeginCodeSnippet
  std::cout << "Nodes = " << meshSource->GetNumberOfNodes() << std::endl;
  std::cout << "Cells = " << meshSource->GetNumberOfCells() << std::endl;
// Software Guide : EndCodeSnippet

// Software Guide : BeginLatex
//
// This resulting Mesh could be used as input for a deformable model
// segmentation algorithm, or it could be converted to a format suitable for
// visualization in an interactive application.
//
// Software Guide : EndLatex

  return EXIT_SUCCESS;
}

<|endoftext|>


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

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginLatex
//
//  Resampling can also be performed in multi-component images.
//  This example compares nearest neighbor resampling using the Nearest
//  neighbor and the linear interpolators for vector images.
//
//  Try
//    ResampleImageFilter9 Examples/Data/VisibleWomanEyeSlice.png
//        SliceNearestNeighbor.png SliceLinear.png
//
//  \index{itk::VectorResampleImageFilter!Image internal transform}
//
//  Software Guide : EndLatex

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkVectorResampleImageFilter.h"
#include "itkIdentityTransform.h"
#include "itkVectorNearestNeighborInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkRGBPixel.h"

int main( int argc, char * argv[] )
{
  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] <<
      "  inputImageFile  outputImageFile_NearestNeighbor" <<
      "  outputImageFile_Linear " << std::endl;
    return EXIT_FAILURE;
    }

  const     unsigned int   Dimension = 2;
  typedef   unsigned char  PixelComponentType;
  typedef   itk::RGBPixel< PixelComponentType > PixelType;

  typedef itk::Image< PixelType,  Dimension >   ImageType;

  typedef itk::ImageFileReader< ImageType >  ReaderType;
  typedef itk::ImageFileWriter< ImageType >  WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writerNearest = WriterType::New(); // writer for nearest neighbor
  WriterType::Pointer writerLinear = WriterType::New(); // writer for linear

  reader->SetFileName( argv[1] );
  writerNearest->SetFileName( argv[2] );
  writerLinear->SetFileName( argv[3] );

  typedef itk::VectorResampleImageFilter<
                            ImageType, ImageType >  FilterType;

  FilterType::Pointer nearestFilter = FilterType::New();
  FilterType::Pointer linearFilter = FilterType::New();

  //Interpolators
  typedef itk::VectorNearestNeighborInterpolateImageFunction<
                       ImageType, double >  NearestInterpolatorType;
  NearestInterpolatorType::Pointer interpolatorNearest = NearestInterpolatorType::New();

  typedef itk::VectorLinearInterpolateImageFunction<
                       ImageType, double >  LinearInterpolatorType;
  LinearInterpolatorType::Pointer interpolatorLinear = LinearInterpolatorType::New();

  nearestFilter->SetInterpolator( interpolatorNearest );
  linearFilter->SetInterpolator( interpolatorLinear );

  typedef itk::IdentityTransform< double, Dimension >  TransformType;
  TransformType::Pointer transform = TransformType::New();

  nearestFilter->SetTransform( transform );
  linearFilter->SetTransform( transform );

  // Software Guide : BeginCodeSnippet
  nearestFilter->SetDefaultPixelValue( 50 );
  linearFilter->SetDefaultPixelValue( 50 );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  ImageType::SpacingType spacing;
  spacing[0] = .35; // pixel spacing in millimeters along X
  spacing[1] = .35; // pixel spacing in millimeters along Y

  nearestFilter->SetOutputSpacing( spacing );
  linearFilter->SetOutputSpacing( spacing );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  ImageType::PointType origin;
  origin[0] = 0.4;  // X space coordinate of origin
  origin[1] = 0.4;  // Y space coordinate of origin
  nearestFilter->SetOutputOrigin( origin );
  linearFilter->SetOutputOrigin( origin );
  // Software Guide : EndCodeSnippet

  ImageType::SizeType   size;

  size[0] = 300;  // number of pixels along X
  size[1] = 300;  // number of pixels along Y

  nearestFilter->SetSize( size );
  linearFilter->SetSize( size );

  nearestFilter->SetInput( reader->GetOutput() );
  linearFilter->SetInput( reader->GetOutput() );
  writerNearest->SetInput( nearestFilter->GetOutput() );
  writerLinear->SetInput( linearFilter->GetOutput() );

  try
    {
    writerNearest->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown " << std::endl;
    std::cerr << excp << std::endl;
    }

  try
    {
    writerLinear->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown " << std::endl;
    std::cerr << excp << std::endl;
    }

  return EXIT_SUCCESS;

}

<commit_msg>COMP: set threads to 1 to see if test passes on Borland.<commit_after>/*=========================================================================

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

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#if defined(_MSC_VER)
#pragma warning ( disable : 4786 )
#endif

#ifdef __BORLANDC__
#define ITK_LEAN_AND_MEAN
#endif

//  Software Guide : BeginLatex
//
//  Resampling can also be performed in multi-component images.
//  This example compares nearest neighbor resampling using the Nearest
//  neighbor and the linear interpolators for vector images.
//
//  Try
//    ResampleImageFilter9 Examples/Data/VisibleWomanEyeSlice.png
//        SliceNearestNeighbor.png SliceLinear.png
//
//  \index{itk::VectorResampleImageFilter!Image internal transform}
//
//  Software Guide : EndLatex

#include "itkImage.h"
#include "itkImageFileReader.h"
#include "itkImageFileWriter.h"
#include "itkVectorResampleImageFilter.h"
#include "itkIdentityTransform.h"
#include "itkVectorNearestNeighborInterpolateImageFunction.h"
#include "itkLinearInterpolateImageFunction.h"
#include "itkRGBPixel.h"

int main( int argc, char * argv[] )
{
  if( argc < 4 )
    {
    std::cerr << "Usage: " << std::endl;
    std::cerr << argv[0] <<
      "  inputImageFile  outputImageFile_NearestNeighbor" <<
      "  outputImageFile_Linear " << std::endl;
    return EXIT_FAILURE;
    }

  const     unsigned int   Dimension = 2;
  typedef   unsigned char  PixelComponentType;
  typedef   itk::RGBPixel< PixelComponentType > PixelType;

  typedef itk::Image< PixelType,  Dimension >   ImageType;

  typedef itk::ImageFileReader< ImageType >  ReaderType;
  typedef itk::ImageFileWriter< ImageType >  WriterType;

  ReaderType::Pointer reader = ReaderType::New();
  WriterType::Pointer writerNearest = WriterType::New(); // writer for nearest neighbor
  WriterType::Pointer writerLinear = WriterType::New(); // writer for linear

  reader->SetFileName( argv[1] );
  writerNearest->SetFileName( argv[2] );
  writerLinear->SetFileName( argv[3] );

  typedef itk::VectorResampleImageFilter<
                            ImageType, ImageType >  FilterType;

  FilterType::Pointer nearestFilter = FilterType::New();
  FilterType::Pointer linearFilter = FilterType::New();

  //Interpolators
  typedef itk::VectorNearestNeighborInterpolateImageFunction<
                       ImageType, double >  NearestInterpolatorType;
  NearestInterpolatorType::Pointer interpolatorNearest = NearestInterpolatorType::New();

  typedef itk::VectorLinearInterpolateImageFunction<
                       ImageType, double >  LinearInterpolatorType;
  LinearInterpolatorType::Pointer interpolatorLinear = LinearInterpolatorType::New();

  nearestFilter->SetInterpolator( interpolatorNearest );
  linearFilter->SetInterpolator( interpolatorLinear );

  typedef itk::IdentityTransform< double, Dimension >  TransformType;
  TransformType::Pointer transform = TransformType::New();

  nearestFilter->SetTransform( transform );
  linearFilter->SetTransform( transform );

  // Software Guide : BeginCodeSnippet
  nearestFilter->SetDefaultPixelValue( 50 );
  nearestFilter->SetNumberOfThreads(1);
  linearFilter->SetDefaultPixelValue( 50 );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  ImageType::SpacingType spacing;
  spacing[0] = .35; // pixel spacing in millimeters along X
  spacing[1] = .35; // pixel spacing in millimeters along Y

  nearestFilter->SetOutputSpacing( spacing );
  linearFilter->SetOutputSpacing( spacing );
  // Software Guide : EndCodeSnippet

  // Software Guide : BeginCodeSnippet
  ImageType::PointType origin;
  origin[0] = 0.4;  // X space coordinate of origin
  origin[1] = 0.4;  // Y space coordinate of origin
  nearestFilter->SetOutputOrigin( origin );
  linearFilter->SetOutputOrigin( origin );
  // Software Guide : EndCodeSnippet

  ImageType::SizeType   size;

  size[0] = 300;  // number of pixels along X
  size[1] = 300;  // number of pixels along Y

  nearestFilter->SetSize( size );
  linearFilter->SetSize( size );

  nearestFilter->SetInput( reader->GetOutput() );
  linearFilter->SetInput( reader->GetOutput() );
  writerNearest->SetInput( nearestFilter->GetOutput() );
  writerLinear->SetInput( linearFilter->GetOutput() );

  try
    {
    writerNearest->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown " << std::endl;
    std::cerr << excp << std::endl;
    }

  try
    {
    writerLinear->Update();
    }
  catch( itk::ExceptionObject & excp )
    {
    std::cerr << "Exception thrown " << std::endl;
    std::cerr << excp << std::endl;
    }

  return EXIT_SUCCESS;

}

<|endoftext|>


<commit_before>#include "HPRecType.h"
#include "Util.h"
#include <set>
#include <vector>

using namespace std;

atomic<HazardPointer::Node*> HazardPointer::s_head;

thread_local std::vector<void*> _retiredList;

void HazardPointer::Retire(void* pOld) {
    _retiredList.push_back(pOld);
    if (_retiredList.size() >= 100) { // Maximum retired list size
        Scan();
    }
}

void HazardPointer::Scan() {
    // Stage 1: Scan the hazard pointers list, collecting all nonnull ptrs
    std::set<void*> hazardPointers;
    for (auto* node = s_head.load(); node != nullptr; node = node->next) {
        if (node->ptr) hazardPointers.insert(node->ptr);
    }

    // Stage 2 (sort the list) isn't required when using std::set.

    // Stage 3: Search for them!
    for (auto it = _retiredList.begin(); it != _retiredList.end(); ) {
        if (hazardPointers.find(*it) != hazardPointers.end()) {
            delete *it;
            it = _retiredList.erase(it);
        } else {
            ++it;
        }
    }
}

HazardPointer::HazardPointer() {
    // Try to reuse a retired node
    for (_node = s_head.load(); _node != nullptr; _node = _node->next) {
        if (!CAS(_node->active, false, true)) continue;
        return;
    }

    // Else, there are no free nodes, create a new one
    _node = new HazardPointer::Node();
    HazardPointer::Node* old;
    do {
        old = s_head.load();
        _node->next = old;
    } while (!CAS(s_head, old, _node));
    return;
}

HazardPointer::HazardPointer(HazardPointer&& other) noexcept {
    std::swap(_node, other._node);
}

HazardPointer::~HazardPointer() {
    if (_node) {
        _node->ptr = nullptr;
        _node->active = false;
    }
}

HazardPointer& HazardPointer::operator=(HazardPointer&& other) noexcept {
    std::swap(_node, other._node);
    return other;
}
<commit_msg>Need to always scan to avoid leaking.<commit_after>#include "HPRecType.h"
#include "Util.h"
#include <set>
#include <vector>

using namespace std;

atomic<HazardPointer::Node*> HazardPointer::s_head;

thread_local std::vector<void*> _retiredList;

void HazardPointer::Retire(void* pOld) {
    _retiredList.push_back(pOld);
    Scan();
}

void HazardPointer::Scan() {
    // Stage 1: Scan the hazard pointers list, collecting all nonnull ptrs
    std::set<void*> hazardPointers;
    for (auto* node = s_head.load(); node != nullptr; node = node->next) {
        if (node->ptr) hazardPointers.insert(node->ptr);
    }

    // Stage 2 (sort the list) isn't required when using std::set.

    // Stage 3: Search for them!
    for (auto it = _retiredList.begin(); it != _retiredList.end(); ) {
        if (hazardPointers.find(*it) != hazardPointers.end()) {
            delete *it;
            it = _retiredList.erase(it);
        } else {
            ++it;
        }
    }
}

HazardPointer::HazardPointer() {
    // Try to reuse a retired node
    for (_node = s_head.load(); _node != nullptr; _node = _node->next) {
        if (!CAS(_node->active, false, true)) continue;
        return;
    }

    // Else, there are no free nodes, create a new one
    _node = new HazardPointer::Node();
    HazardPointer::Node* old;
    do {
        old = s_head.load();
        _node->next = old;
    } while (!CAS(s_head, old, _node));
    return;
}

HazardPointer::HazardPointer(HazardPointer&& other) noexcept {
    std::swap(_node, other._node);
}

HazardPointer::~HazardPointer() {
    if (_node) {
        _node->ptr = nullptr;
        _node->active = false;
    }
}

HazardPointer& HazardPointer::operator=(HazardPointer&& other) noexcept {
    std::swap(_node, other._node);
    return other;
}
<|endoftext|>