<commit_before>/****************************************************************************/
/**
 *  @file   CellByCellUniformSampling.cpp
 *  @author Naohisa Sakamoto
 */
/*----------------------------------------------------------------------------
 *
 *  Copyright (c) Visualization Laboratory, Kyoto University.
 *  All rights reserved.
 *  See http://www.viz.media.kyoto-u.ac.jp/kvs/copyright/ for details.
 *
 *  $Id: CellByCellUniformSampling.cpp 1792 2014-07-31 04:50:42Z naohisa.sakamoto@gmail.com $
 */
/****************************************************************************/
#include "CellByCellUniformSampling.h"
#include <vector>
#include <kvs/OpenMP>
#include <kvs/DebugNew>
#include <kvs/Camera>
#include <kvs/TrilinearInterpolator>
#include <kvs/Value>
#include <kvs/CellBase>
#include "CellByCellSampling.h"

namespace kvs
{

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling():
    kvs::MapperBase(),
    kvs::PointObject(),
    m_camera( 0 )
{
}

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 *  @param  volume [in] pointer to the volume object
 *  @param  repetition_level [in] repetition level
 *  @param  sampling_step [in] sapling step
 *  @param  transfer_function [in] transfer function
 *  @param  object_depth [in] depth value of the input volume at the CoG
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling(
    const kvs::VolumeObjectBase* volume,
    const size_t repetition_level,
    const float sampling_step,
    const kvs::TransferFunction& transfer_function,
    const float object_depth ):
    kvs::MapperBase( transfer_function ),
    kvs::PointObject(),
    m_camera( 0 )
{
    this->setRepetitionLevel( repetition_level );
    this->setSamplingStep( sampling_step );
    this->setObjectDepth( object_depth );
    this->exec( volume );
}

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 *  @param  camera [in] pointer to the camera
 *  @param  volume [in] pointer to the volume object
 *  @param  repetition_level [in] repetition level
 *  @param  sampling_step [in] sapling step
 *  @param  transfer_function [in] transfer function
 *  @param  object_depth [in] depth value of the input volume at the CoG
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling(
    const kvs::Camera* camera,
    const kvs::VolumeObjectBase* volume,
    const size_t repetition_level,
    const float sampling_step,
    const kvs::TransferFunction& transfer_function,
    const float object_depth ):
    kvs::MapperBase( transfer_function ),
    kvs::PointObject()
{
    this->attachCamera( camera ),
    this->setRepetitionLevel( repetition_level );
    this->setSamplingStep( sampling_step );
    this->setObjectDepth( object_depth );
    this->exec( volume );
}

/*===========================================================================*/
/**
 *  @brief  Executes the mapper process.
 *  @param  object [in] pointer to the volume object
 *  @return pointer to the point object
 */
/*===========================================================================*/
CellByCellUniformSampling::SuperClass* CellByCellUniformSampling::exec( const kvs::ObjectBase* object )
{
    if ( !object )
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Input object is NULL.");
        return NULL;
    }

    const kvs::VolumeObjectBase* volume = kvs::VolumeObjectBase::DownCast( object );
    if ( !volume )
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Input object is not volume dat.");
        return NULL;
    }

    bool delete_camera = false;
    if ( !m_camera )
    {
        m_camera = new kvs::Camera();
        delete_camera = true;
    }

    const kvs::VolumeObjectBase::VolumeType volume_type = volume->volumeType();
    if ( volume_type == kvs::VolumeObjectBase::Structured )
    {
        this->mapping( kvs::StructuredVolumeObject::DownCast( object ) );
    }
    else // volume_type == kvs::VolumeObjectBase::Unstructured
    {
        this->mapping( kvs::UnstructuredVolumeObject::DownCast( object ) );
    }

    if ( delete_camera )
    {
        delete m_camera;
        m_camera = 0;
    }

    return this;
}

/*===========================================================================*/
/**
 *  @brief  Mapping for the structured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::mapping( const kvs::StructuredVolumeObject* volume )
{
    // Attach the pointer to the volume object and set the min/max coordinates.
    BaseClass::attachVolume( volume );
    BaseClass::setRange( volume );
    BaseClass::setMinMaxCoords( volume, this );

    // Generate the particles.
    const std::type_info& type = volume->values().typeInfo()->type();
    if (      type == typeid( kvs::Int8   ) ) this->generate_particles<kvs::Int8>( volume );
    else if ( type == typeid( kvs::Int16  ) ) this->generate_particles<kvs::Int16>( volume );
    else if ( type == typeid( kvs::Int32  ) ) this->generate_particles<kvs::Int32>( volume );
    else if ( type == typeid( kvs::UInt8  ) ) this->generate_particles<kvs::UInt8>( volume );
    else if ( type == typeid( kvs::UInt16 ) ) this->generate_particles<kvs::UInt16>( volume );
    else if ( type == typeid( kvs::UInt32 ) ) this->generate_particles<kvs::UInt32>( volume );
    else if ( type == typeid( kvs::Real32 ) ) this->generate_particles<kvs::Real32>( volume );
    else if ( type == typeid( kvs::Real64 ) ) this->generate_particles<kvs::Real64>( volume );
    else
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Unsupported data type '%s'.", volume->values().typeInfo()->typeName() );
    }
}

/*===========================================================================*/
/**
 *  @brief  Mapping for the unstructured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::mapping( const kvs::UnstructuredVolumeObject* volume )
{
    // Attach the pointer to the volume object and set the min/max coordinates.
    BaseClass::attachVolume( volume );
    BaseClass::setRange( volume );
    BaseClass::setMinMaxCoords( volume, this );

    // Generate the particles.
    this->generate_particles( volume );
}

/*===========================================================================*/
/**
 *  @brief  Generates particles for the structured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
template <typename T>
void CellByCellUniformSampling::generate_particles( const kvs::StructuredVolumeObject* volume )
{
    CellByCellSampling::ParticleDensityMap density_map;
    density_map.setSamplingStep( m_sampling_step );
    density_map.attachCamera( m_camera );
    density_map.attachObject( volume );
    density_map.create( BaseClass::transferFunction().opacityMap() );

    const kvs::Vec3ui ncells( volume->resolution() - kvs::Vector3ui::All(1) );
    const kvs::ColorMap color_map( BaseClass::transferFunction().colorMap() );

    // Calculate number of particles.
    size_t N = 0;
    kvs::ValueArray<kvs::UInt32> nparticles( ncells.x() * ncells.y() * ncells.z() );
    KVS_OMP_PARALLEL()
    {
        kvs::TrilinearInterpolator interpolator( volume );
        CellByCellSampling::GridSampler<T> sampler( &interpolator, &density_map );

        KVS_OMP_FOR( reduction(+:N) )
        for ( kvs::UInt32 z = 0; z < ncells.z(); ++z )
        {
            size_t cell_index_counter = z * ncells.x() * ncells.y();
            for ( kvs::UInt32 y = 0; y < ncells.y(); ++y )
            {
                for ( kvs::UInt32 x = 0; x < ncells.x(); ++x )
                {
                    sampler.bind( kvs::Vec3ui( x, y, z ) );
                    const size_t n = sampler.numberOfParticles();
                    const kvs::UInt32 index = cell_index_counter++;
                    nparticles[index] = n;
                    N += n;
                }
            }
        }
    }

    // Genrate a set of particles.
    const kvs::UInt32 repetitions = m_repetition_level;
    kvs::ValueArray<kvs::Real32> coords( 3 * N * repetitions );
    kvs::ValueArray<kvs::Real32> normals( 3 * N * repetitions );
    kvs::ValueArray<kvs::UInt8> colors( 3 * N * repetitions );
    KVS_OMP_PARALLEL()
    {
        kvs::TrilinearInterpolator interpolator( volume );
        CellByCellSampling::GridSampler<T> sampler( &interpolator, &density_map );

        KVS_OMP_FOR( schedule(dynamic) )
        for ( kvs::UInt32 r = 0; r < repetitions; ++r )
        {
            size_t cell_index_counter = 0;
            size_t particle_index_counter = N * r;
            for ( kvs::UInt32 z = 0; z < ncells.z(); ++z )
            {
                for ( kvs::UInt32 y = 0; y < ncells.y(); ++y )
                {
                    for ( kvs::UInt32 x = 0; x < ncells.x(); ++x )
                    {
                        const kvs::UInt32 index = cell_index_counter++;
                        const size_t n = nparticles[index];
                        if ( n == 0 ) continue;

                        sampler.bind( kvs::Vec3ui( x, y, z ) );
                        for ( size_t i = 0; i < n; ++i )
                        {
                            sampler.sample();
                            const CellByCellSampling::Particle& p = sampler.accept();
                            const kvs::RGBColor color = color_map.at( p.scalar );
                            const size_t index3 = ( particle_index_counter++ ) * 3;
                            coords[ index3 + 0 ] = p.coord.x();
                            coords[ index3 + 1 ] = p.coord.y();
                            coords[ index3 + 2 ] = p.coord.z();
                            normals[ index3 + 0 ] = p.normal.x();
                            normals[ index3 + 1 ] = p.normal.y();
                            normals[ index3 + 2 ] = p.normal.z();
                            colors[ index3 + 0 ] = color.r();
                            colors[ index3 + 1 ] = color.g();
                            colors[ index3 + 2 ] = color.b();
                        }
                    }
                }
            }
        }
    }

    SuperClass::setCoords( coords );
    SuperClass::setColors( colors );
    SuperClass::setNormals( normals );
    SuperClass::setSize( 1.0f );
}

/*===========================================================================*/
/**
 *  @brief  Generates particles for the unstructured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::generate_particles( const kvs::UnstructuredVolumeObject* volume )
{
    CellByCellSampling::ParticleDensityMap density_map;
    density_map.setSamplingStep( m_sampling_step );
    density_map.attachCamera( m_camera );
    density_map.attachObject( volume );
    density_map.create( BaseClass::transferFunction().opacityMap() );

    const size_t ncells = volume->numberOfCells();
    const kvs::ColorMap color_map( BaseClass::transferFunction().colorMap() );

    // Calculate number of particles
    size_t N = 0;
    kvs::ValueArray<kvs::UInt32> nparticles( ncells );
    KVS_OMP_PARALLEL()
    {
        kvs::CellBase* cell = CellByCellSampling::Cell( volume );
        CellByCellSampling::CellSampler sampler( cell, &density_map );

        KVS_OMP_FOR( reduction(+:N) )
        for ( size_t index = 0; index < ncells; ++index )
        {
            sampler.bind( index );
            const size_t n = sampler.numberOfParticles();
            nparticles[index] = n;

            N += n;
        }

        delete cell;
    }

    // Generate particles
    const kvs::UInt32 repetitions = m_repetition_level;
    kvs::ValueArray<kvs::Real32> coords( 3 * N * repetitions );
    kvs::ValueArray<kvs::Real32> normals( 3 * N * repetitions );
    kvs::ValueArray<kvs::UInt8> colors( 3 * N * repetitions );
    KVS_OMP_PARALLEL()
    {
        kvs::CellBase* cell = CellByCellSampling::Cell( volume );
        CellByCellSampling::CellSampler sampler( cell, &density_map );

        KVS_OMP_FOR( schedule(dynamic) )
        for ( kvs::UInt32 r = 0; r < repetitions; ++r )
        {
            size_t particle_index_counter = N * r;
            for ( size_t index = 0; index < ncells; ++index )
            {
                const size_t n = nparticles[index];
                if ( n == 0 ) continue;

                sampler.bind( index );
                for ( size_t i = 0; i < n; ++i )
                {
                    sampler.sample();
                    const CellByCellSampling::Particle& p = sampler.accept();
                    const kvs::RGBColor color = color_map.at( p.scalar );
                    const size_t index3 = ( particle_index_counter++ ) * 3;
                    coords[ index3 + 0 ] = p.coord.x();
                    coords[ index3 + 1 ] = p.coord.y();
                    coords[ index3 + 2 ] = p.coord.z();
                    normals[ index3 + 0 ] = p.normal.x();
                    normals[ index3 + 1 ] = p.normal.y();
                    normals[ index3 + 2 ] = p.normal.z();
                    colors[ index3 + 0 ] = color.r();
                    colors[ index3 + 1 ] = color.g();
                    colors[ index3 + 2 ] = color.b();
                }
            }
        }

        delete cell;
    }

    SuperClass::setCoords( coords );
    SuperClass::setColors( colors );
    SuperClass::setNormals( normals );
    SuperClass::setSize( 1.0f );
}

} // end of namespace kvs
<commit_msg>Modified.<commit_after>/****************************************************************************/
/**
 *  @file   CellByCellUniformSampling.cpp
 *  @author Naohisa Sakamoto
 */
/*----------------------------------------------------------------------------
 *
 *  Copyright (c) Visualization Laboratory, Kyoto University.
 *  All rights reserved.
 *  See http://www.viz.media.kyoto-u.ac.jp/kvs/copyright/ for details.
 *
 *  $Id: CellByCellUniformSampling.cpp 1792 2014-07-31 04:50:42Z naohisa.sakamoto@gmail.com $
 */
/****************************************************************************/
#include "CellByCellUniformSampling.h"
#include <vector>
#include <kvs/OpenMP>
#include <kvs/DebugNew>
#include <kvs/Camera>
#include <kvs/TrilinearInterpolator>
#include <kvs/Value>
#include <kvs/CellBase>
#include "CellByCellSampling.h"

namespace kvs
{

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling():
    kvs::MapperBase(),
    kvs::PointObject(),
    m_camera( 0 )
{
}

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 *  @param  volume [in] pointer to the volume object
 *  @param  repetition_level [in] repetition level
 *  @param  sampling_step [in] sapling step
 *  @param  transfer_function [in] transfer function
 *  @param  object_depth [in] depth value of the input volume at the CoG
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling(
    const kvs::VolumeObjectBase* volume,
    const size_t repetition_level,
    const float sampling_step,
    const kvs::TransferFunction& transfer_function,
    const float object_depth ):
    kvs::MapperBase( transfer_function ),
    kvs::PointObject(),
    m_camera( 0 )
{
    this->setRepetitionLevel( repetition_level );
    this->setSamplingStep( sampling_step );
    this->setObjectDepth( object_depth );
    this->exec( volume );
}

/*===========================================================================*/
/**
 *  @brief  Constructs a new CellByCellUniformSampling class.
 *  @param  camera [in] pointer to the camera
 *  @param  volume [in] pointer to the volume object
 *  @param  repetition_level [in] repetition level
 *  @param  sampling_step [in] sapling step
 *  @param  transfer_function [in] transfer function
 *  @param  object_depth [in] depth value of the input volume at the CoG
 */
/*===========================================================================*/
CellByCellUniformSampling::CellByCellUniformSampling(
    const kvs::Camera* camera,
    const kvs::VolumeObjectBase* volume,
    const size_t repetition_level,
    const float sampling_step,
    const kvs::TransferFunction& transfer_function,
    const float object_depth ):
    kvs::MapperBase( transfer_function ),
    kvs::PointObject()
{
    this->attachCamera( camera ),
    this->setRepetitionLevel( repetition_level );
    this->setSamplingStep( sampling_step );
    this->setObjectDepth( object_depth );
    this->exec( volume );
}

/*===========================================================================*/
/**
 *  @brief  Executes the mapper process.
 *  @param  object [in] pointer to the volume object
 *  @return pointer to the point object
 */
/*===========================================================================*/
CellByCellUniformSampling::SuperClass* CellByCellUniformSampling::exec( const kvs::ObjectBase* object )
{
    if ( !object )
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Input object is NULL.");
        return NULL;
    }

    const kvs::VolumeObjectBase* volume = kvs::VolumeObjectBase::DownCast( object );
    if ( !volume )
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Input object is not volume dat.");
        return NULL;
    }

    bool delete_camera = false;
    if ( !m_camera )
    {
        m_camera = new kvs::Camera();
        delete_camera = true;
    }

    const kvs::VolumeObjectBase::VolumeType volume_type = volume->volumeType();
    if ( volume_type == kvs::VolumeObjectBase::Structured )
    {
        this->mapping( kvs::StructuredVolumeObject::DownCast( object ) );
    }
    else // volume_type == kvs::VolumeObjectBase::Unstructured
    {
        this->mapping( kvs::UnstructuredVolumeObject::DownCast( object ) );
    }

    if ( delete_camera )
    {
        delete m_camera;
        m_camera = 0;
    }

    return this;
}

/*===========================================================================*/
/**
 *  @brief  Mapping for the structured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::mapping( const kvs::StructuredVolumeObject* volume )
{
    // Attach the pointer to the volume object and set the min/max coordinates.
    BaseClass::attachVolume( volume );
    BaseClass::setRange( volume );
    BaseClass::setMinMaxCoords( volume, this );

    // Generate the particles.
    const std::type_info& type = volume->values().typeInfo()->type();
    if (      type == typeid( kvs::Int8   ) ) this->generate_particles<kvs::Int8>( volume );
    else if ( type == typeid( kvs::Int16  ) ) this->generate_particles<kvs::Int16>( volume );
    else if ( type == typeid( kvs::Int32  ) ) this->generate_particles<kvs::Int32>( volume );
    else if ( type == typeid( kvs::UInt8  ) ) this->generate_particles<kvs::UInt8>( volume );
    else if ( type == typeid( kvs::UInt16 ) ) this->generate_particles<kvs::UInt16>( volume );
    else if ( type == typeid( kvs::UInt32 ) ) this->generate_particles<kvs::UInt32>( volume );
    else if ( type == typeid( kvs::Real32 ) ) this->generate_particles<kvs::Real32>( volume );
    else if ( type == typeid( kvs::Real64 ) ) this->generate_particles<kvs::Real64>( volume );
    else
    {
        BaseClass::setSuccess( false );
        kvsMessageError("Unsupported data type '%s'.", volume->values().typeInfo()->typeName() );
    }
}

/*===========================================================================*/
/**
 *  @brief  Mapping for the unstructured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::mapping( const kvs::UnstructuredVolumeObject* volume )
{
    // Attach the pointer to the volume object and set the min/max coordinates.
    BaseClass::attachVolume( volume );
    BaseClass::setRange( volume );
    BaseClass::setMinMaxCoords( volume, this );

    // Generate the particles.
    this->generate_particles( volume );
}

/*===========================================================================*/
/**
 *  @brief  Generates particles for the structured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
template <typename T>
void CellByCellUniformSampling::generate_particles( const kvs::StructuredVolumeObject* volume )
{
    CellByCellSampling::ParticleDensityMap density_map;
    density_map.setSamplingStep( m_sampling_step );
    density_map.attachCamera( m_camera );
    density_map.attachObject( volume );
    density_map.create( BaseClass::transferFunction().opacityMap() );

    const kvs::Vec3ui ncells( volume->resolution() - kvs::Vector3ui::All(1) );
    const kvs::ColorMap color_map( BaseClass::transferFunction().colorMap() );

    kvs::TrilinearInterpolator interpolator( volume );
    CellByCellSampling::GridSampler<T> sampler( &interpolator, &density_map );

    // Calculate number of particles.
    size_t N = 0;
    kvs::ValueArray<kvs::UInt32> nparticles( ncells.x() * ncells.y() * ncells.z() );
    KVS_OMP_PARALLEL()
    {
//        kvs::TrilinearInterpolator interpolator( volume );
//        CellByCellSampling::GridSampler<T> sampler( &interpolator, &density_map );

        KVS_OMP_FOR( reduction(+:N) )
        for ( kvs::UInt32 z = 0; z < ncells.z(); ++z )
        {
            size_t cell_index_counter = z * ncells.x() * ncells.y();
            for ( kvs::UInt32 y = 0; y < ncells.y(); ++y )
            {
                for ( kvs::UInt32 x = 0; x < ncells.x(); ++x )
                {
                    sampler.bind( kvs::Vec3ui( x, y, z ) );
                    const size_t n = sampler.numberOfParticles();
                    const kvs::UInt32 index = cell_index_counter++;
                    nparticles[index] = n;
                    N += n;
                }
            }
        }
    }

    // Genrate a set of particles.
    const kvs::UInt32 repetitions = m_repetition_level;
    kvs::ValueArray<kvs::Real32> coords( 3 * N * repetitions );
    kvs::ValueArray<kvs::Real32> normals( 3 * N * repetitions );
    kvs::ValueArray<kvs::UInt8> colors( 3 * N * repetitions );
    KVS_OMP_PARALLEL()
    {
//        kvs::TrilinearInterpolator interpolator( volume );
//        CellByCellSampling::GridSampler<T> sampler( &interpolator, &density_map );

        KVS_OMP_FOR( schedule(dynamic) )
        for ( kvs::UInt32 r = 0; r < repetitions; ++r )
        {
            size_t cell_index_counter = 0;
            size_t particle_index_counter = N * r;
            for ( kvs::UInt32 z = 0; z < ncells.z(); ++z )
            {
                for ( kvs::UInt32 y = 0; y < ncells.y(); ++y )
                {
                    for ( kvs::UInt32 x = 0; x < ncells.x(); ++x )
                    {
                        const kvs::UInt32 index = cell_index_counter++;
                        const size_t n = nparticles[index];
                        if ( n == 0 ) continue;

                        sampler.bind( kvs::Vec3ui( x, y, z ) );
                        for ( size_t i = 0; i < n; ++i )
                        {
                            sampler.sample();
                            const CellByCellSampling::Particle& p = sampler.accept();
                            const kvs::RGBColor color = color_map.at( p.scalar );
                            const size_t index3 = ( particle_index_counter++ ) * 3;
                            coords[ index3 + 0 ] = p.coord.x();
                            coords[ index3 + 1 ] = p.coord.y();
                            coords[ index3 + 2 ] = p.coord.z();
                            normals[ index3 + 0 ] = p.normal.x();
                            normals[ index3 + 1 ] = p.normal.y();
                            normals[ index3 + 2 ] = p.normal.z();
                            colors[ index3 + 0 ] = color.r();
                            colors[ index3 + 1 ] = color.g();
                            colors[ index3 + 2 ] = color.b();
                        }
                    }
                }
            }
        }
    }

    SuperClass::setCoords( coords );
    SuperClass::setColors( colors );
    SuperClass::setNormals( normals );
    SuperClass::setSize( 1.0f );
}

/*===========================================================================*/
/**
 *  @brief  Generates particles for the unstructured volume object.
 *  @param  volume [in] pointer to the input volume object
 */
/*===========================================================================*/
void CellByCellUniformSampling::generate_particles( const kvs::UnstructuredVolumeObject* volume )
{
    CellByCellSampling::ParticleDensityMap density_map;
    density_map.setSamplingStep( m_sampling_step );
    density_map.attachCamera( m_camera );
    density_map.attachObject( volume );
    density_map.create( BaseClass::transferFunction().opacityMap() );

    const size_t ncells = volume->numberOfCells();
    const kvs::ColorMap color_map( BaseClass::transferFunction().colorMap() );

    kvs::CellBase* cell = CellByCellSampling::Cell( volume );
    CellByCellSampling::CellSampler sampler( cell, &density_map );

    // Calculate number of particles
    size_t N = 0;
    kvs::ValueArray<kvs::UInt32> nparticles( ncells );
    KVS_OMP_PARALLEL()
    {
//        kvs::CellBase* cell = CellByCellSampling::Cell( volume );
//        CellByCellSampling::CellSampler sampler( cell, &density_map );

        KVS_OMP_FOR( reduction(+:N) )
        for ( size_t index = 0; index < ncells; ++index )
        {
            sampler.bind( index );
            const size_t n = sampler.numberOfParticles();
            nparticles[index] = n;

            N += n;
        }

//        delete cell;
    }

    // Generate particles
    const kvs::UInt32 repetitions = m_repetition_level;
    kvs::ValueArray<kvs::Real32> coords( 3 * N * repetitions );
    kvs::ValueArray<kvs::Real32> normals( 3 * N * repetitions );
    kvs::ValueArray<kvs::UInt8> colors( 3 * N * repetitions );
    KVS_OMP_PARALLEL()
    {
//        kvs::CellBase* cell = CellByCellSampling::Cell( volume );
//        CellByCellSampling::CellSampler sampler( cell, &density_map );

        KVS_OMP_FOR( schedule(dynamic) )
        for ( kvs::UInt32 r = 0; r < repetitions; ++r )
        {
            size_t particle_index_counter = N * r;
            for ( size_t index = 0; index < ncells; ++index )
            {
                const size_t n = nparticles[index];
                if ( n == 0 ) continue;

                sampler.bind( index );
                for ( size_t i = 0; i < n; ++i )
                {
                    sampler.sample();
                    const CellByCellSampling::Particle& p = sampler.accept();
                    const kvs::RGBColor color = color_map.at( p.scalar );
                    const size_t index3 = ( particle_index_counter++ ) * 3;
                    coords[ index3 + 0 ] = p.coord.x();
                    coords[ index3 + 1 ] = p.coord.y();
                    coords[ index3 + 2 ] = p.coord.z();
                    normals[ index3 + 0 ] = p.normal.x();
                    normals[ index3 + 1 ] = p.normal.y();
                    normals[ index3 + 2 ] = p.normal.z();
                    colors[ index3 + 0 ] = color.r();
                    colors[ index3 + 1 ] = color.g();
                    colors[ index3 + 2 ] = color.b();
                }
            }
        }

//        delete cell;
    }

    delete cell;

    SuperClass::setCoords( coords );
    SuperClass::setColors( colors );
    SuperClass::setNormals( normals );
    SuperClass::setSize( 1.0f );
}

} // end of namespace kvs
<|endoftext|>


<commit_before>#pragma once
#include <cstdint>
#include <memory>
#include <Utility/Utilities/Include/Memory/Circlebuffer/StaticData.hpp>
#include <Utility/Utilities/Include/PointerArithmetic/PointerArithmetic.hpp>
#include <mutex>
#include <Utility/Utilities/Include/IO/Mutex/Mutex.hpp>
#include <Utility/Utilities/Include/Memory/Circlebuffer/CircleBufferHeader.hpp>
#include <string>

namespace Doremi
{
    namespace Utilities
    {
        namespace Memory
        {
            template <typename T> class CircleBuffer
            {
            public:
                /**
                TODO docs
                */
                CircleBuffer()
                    : m_data(nullptr),
                      m_rawBufferPointerStart(nullptr),
                      m_rawBufferPointerEnd(nullptr),
                      m_adjustedBufferPointerStart(nullptr),
                      m_adjustedBufferPointerEnd(nullptr),
                      m_rawBufferSize(0),
                      m_adjustedBufferSize(0),
                      m_internalMemoryManagement(true),
                      m_alreadyInitialized(false),
                      m_maxContainedObjects(0),
                      m_mutex(nullptr),
                      m_sizeOfOneObject(0)
                {
                }

                /**
                TODO docs
                */
                virtual ~CircleBuffer()
                {
                    if(m_internalMemoryManagement)
                    {
                        free(m_rawBufferPointerStart);
                    }
                }

                /**
                The useable size of the buffer will be p_bufferSize - sizeof(StaticData).
                Each object will allocate sizeof(T) + sizeof(CircleBufferHeader) each
                */
                void Initialize(const size_t& p_bufferSize, IO::Mutex* p_mutex = nullptr)
                {
                    AssertInitialize(p_bufferSize);
                    m_rawBufferSize = p_bufferSize;
                    m_mutex = p_mutex;
                    m_rawBufferPointerStart = malloc(m_rawBufferSize);
                    SetupVariables();
                }
                /**
                The useable size of the buffer will be p_bufferSize - sizeof(StaticData)
                Each object will allocate sizeof(T) + sizeof(CircleBufferHeader) each
                */
                void Initialize(void* const p_preAllocatedBuffer, const size_t& p_bufferSize, IO::Mutex* p_mutex = nullptr)
                {
                    AssertInitialize(p_bufferSize);
                    m_rawBufferSize = p_bufferSize;
                    m_rawBufferPointerStart = p_preAllocatedBuffer;
                    m_mutex = p_mutex;
                    m_internalMemoryManagement = false;
                    SetupVariables();
                }

                /**
                Threadsafe, internal loackage
                */
                bool Produce(const CircleBufferHeader& p_Header, const T* const p_data) // TODORT, does this not trigger
                {
                    //// Internal lockage
                    // std::lock_guard<std::mutex> lock(m_produceLock);

                    //// Find if it is possible to produce more
                    //// Does not require to lock metadata under the assumption that when circlebuffers communicate via IPC one side is only producer
                    //// and the other side is only comsumer.
                    //// And as this part is already locked with internal lockage above
                    // if(m_data->currentObjectCount < m_maxContainedObjects)
                    //{
                    //    // Local head
                    //    void* head = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_data->currentHeadOffset);

                    //    // Check if current pointer is outside our scope.
                    //    if(PointerArithmetic::AssertAdresstInside(head, m_adjustedBufferPointerStart, m_adjustedBufferPointerEnd) == false)
                    //    {
                    //        head = m_adjustedBufferPointerStart; // If so, reset to first part.
                    //    }

                    //    //// Produce is ok
                    //    // Copy metaheader to current_head
                    //    memcpy(head, &p_Header, sizeof(CircleBufferHeader));

                    //    // Move head to after metaheader
                    //    head = PointerArithmetic::Addition(head, sizeof(CircleBufferHeader));

                    //    // Copy data to head
                    //    memcpy(head, p_data, p_Header.packageSize);

                    //    // Move head to after data
                    //    head = PointerArithmetic::Addition(head, p_Header.packageSize);

                    //    // Update global head
                    //    m_data->currentHeadOffset = PointerArithmetic::Difference(m_adjustedBufferPointerStart, head);

                    //    // Filemap lock
                    //    LockMetaData();

                    //    // Update object count
                    //    m_data->currentObjectCount++;

                    //    // Unlock filemap
                    //    UnLockMetaData();

                    //    // Complete
                    //    return true;
                    //}
                    // else
                    //{
                    //    // Failed
                    //    return false;
                    //}
                    return true;
                }

                /**
                Not threadsafe
                */
                bool Consume(CircleBufferHeader*& out_header, T*& out_data)
                {
                    //// Internal lockage
                    // std::lock_guard<std::mutex> lock(m_consumeLock);

                    //// Find if it is possible to consume anything
                    //// Does not require to lock metadata under the assumption that when circlebuffers communicate via IPC one side is only producer
                    //// and the other side is only comsumer.
                    //// And as this part is already locked with internal lockage above
                    // if(m_data->currentObjectCount > 0)
                    //{
                    //    // Local tail
                    //    void* tail = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_data->currentTailOffset);

                    //    // Check if current pointer is outside our scope.
                    //    if(PointerArithmetic::AssertAdresstInside(tail, m_adjustedBufferPointerStart, m_adjustedBufferPointerEnd) == false)
                    //    {
                    //        tail = m_adjustedBufferPointerStart; // If so, reset to first part.
                    //    }

                    //    //// Produce is ok
                    //    // Copy metaheader to current_head
                    //    memcpy(out_header, tail, sizeof(CircleBufferHeader));

                    //    // Move header to after metaheader
                    //    tail = PointerArithmetic::Addition(tail, sizeof(CircleBufferHeader));

                    //    // Copy data to current:_head
                    //    memcpy(out_data, tail, out_header->packageSize);

                    //    // Move header to after data
                    //    tail = PointerArithmetic::Addition(tail, out_header->packageSize);

                    //    // Update global tail
                    //    m_data->currentTailOffset = PointerArithmetic::Difference(m_adjustedBufferPointerStart, tail);

                    //    // Filemap lock
                    //    LockMetaData();

                    //    // Update object count
                    //    m_data->currentObjectCount--;

                    //    // Unlock filemap
                    //    UnLockMetaData();

                    //    return true;
                    //}
                    // else
                    //{
                    //    // Nothing to do
                    //    return false;
                    //}
                    return true;
                }

            protected:
                void CircleBuffer::AssertInitialize(const size_t& p_bufferSize)
                {
                    m_sizeOfOneObject = sizeof(T) + sizeof(CircleBufferHeader);
                    if(m_sizeOfOneObject > (p_bufferSize - sizeof(StaticData)))
                    {
                        const std::string errorMessage =
                            std::string("Not enough space. Each object will take up sizeof(T) + sizeof(CircleBufferHeader) which is " +
                                        std::to_string(sizeof(T)) + "+" + std::to_string(sizeof(CircleBufferHeader)) + "=" +
                                        std::to_string(m_sizeOfOneObject) + ". This buffer only has access to " + std::to_string(p_bufferSize) + "-" +
                                        std::to_string(sizeof(StaticData)) + "=" + std::to_string(p_bufferSize - sizeof(StaticData)));
                        throw std::runtime_error(errorMessage);
                    }
                    if(m_alreadyInitialized)
                    {
                        throw std::runtime_error("Already initialized.");
                    }
                }

                void CircleBuffer::LockMetaData()
                {
                    if(m_mutex != nullptr)
                    {
                        m_mutex->AttemptLock();
                    }
                }

                void CircleBuffer::UnLockMetaData()
                {
                    if(m_mutex != nullptr)
                    {
                        m_mutex->Unlock();
                    }
                }

                void CircleBuffer::ComputeAdjustments()
                {
                    m_adjustedBufferSize = m_rawBufferSize - sizeof(StaticData);
                    m_adjustedBufferSize = (m_adjustedBufferSize / m_sizeOfOneObject) * m_sizeOfOneObject;

                    m_adjustedBufferPointerStart = PointerArithmetic::Addition(m_rawBufferPointerStart, sizeof(StaticData));
                    m_adjustedBufferPointerEnd = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_adjustedBufferSize);
                }

                void CircleBuffer::ComputeMaxObjects() { m_maxContainedObjects = m_adjustedBufferSize / m_sizeOfOneObject; }

                void CircleBuffer::SetupVariables()
                {
                    m_alreadyInitialized = true;
                    m_rawBufferPointerEnd = PointerArithmetic::Addition(m_rawBufferPointerStart, m_rawBufferSize);
                    ComputeAdjustments();
                    ComputeMaxObjects();
                    m_data = static_cast<StaticData*>(m_rawBufferPointerStart);

                    // TODORT
                    // LockMetaData In a very specific state both processes may come here at about the same time.
                    // However, that should not be a problem. If they're almost here at the same no data should be lost.
                    if(m_data->started != STARTED)
                    {
                        *m_data = StaticData();
                        m_data->currentTailOffset = 0;
                        m_data->currentHeadOffset = 0;
                    }
                    // TODORT
                    // UnLockMetaData
                }

                StaticData* m_data;
                void* m_rawBufferPointerStart;
                void* m_rawBufferPointerEnd;
                void* m_adjustedBufferPointerStart;
                void* m_adjustedBufferPointerEnd;
                size_t m_rawBufferSize;
                size_t m_adjustedBufferSize;
                bool m_internalMemoryManagement;
                std::mutex m_produceLock;
                std::mutex m_consumeLock;
                bool m_alreadyInitialized;
                size_t m_maxContainedObjects;
                IO::Mutex* m_mutex;
                size_t m_sizeOfOneObject;
            };
        }
    }
}<commit_msg>Readded circlebuffer code ;_;<commit_after>#pragma once
#include <cstdint>
#include <memory>
#include <Utility/Utilities/Include/Memory/Circlebuffer/StaticData.hpp>
#include <Utility/Utilities/Include/PointerArithmetic/PointerArithmetic.hpp>
#include <mutex>
#include <Utility/Utilities/Include/IO/Mutex/Mutex.hpp>
#include <Utility/Utilities/Include/Memory/Circlebuffer/CircleBufferHeader.hpp>
#include <string>

namespace Doremi
{
    namespace Utilities
    {
        namespace Memory
        {
            template <typename T> class CircleBuffer
            {
            public:
                /**
                TODO docs
                */
                CircleBuffer()
                    : m_data(nullptr),
                      m_rawBufferPointerStart(nullptr),
                      m_rawBufferPointerEnd(nullptr),
                      m_adjustedBufferPointerStart(nullptr),
                      m_adjustedBufferPointerEnd(nullptr),
                      m_rawBufferSize(0),
                      m_adjustedBufferSize(0),
                      m_internalMemoryManagement(true),
                      m_alreadyInitialized(false),
                      m_maxContainedObjects(0),
                      m_mutex(nullptr),
                      m_sizeOfOneObject(0)
                {
                }

                /**
                TODO docs
                */
                virtual ~CircleBuffer()
                {
                    if(m_internalMemoryManagement)
                    {
                        free(m_rawBufferPointerStart);
                    }
                }

                /**
                The useable size of the buffer will be p_bufferSize - sizeof(StaticData).
                Each object will allocate sizeof(T) + sizeof(CircleBufferHeader) each
                */
                void Initialize(const size_t& p_bufferSize, IO::Mutex* p_mutex = nullptr)
                {
                    AssertInitialize(p_bufferSize);
                    m_rawBufferSize = p_bufferSize;
                    m_mutex = p_mutex;
                    m_rawBufferPointerStart = malloc(m_rawBufferSize);
                    SetupVariables();
                }
                /**
                The useable size of the buffer will be p_bufferSize - sizeof(StaticData)
                Each object will allocate sizeof(T) + sizeof(CircleBufferHeader) each
                */
                void Initialize(void* const p_preAllocatedBuffer, const size_t& p_bufferSize, IO::Mutex* p_mutex = nullptr)
                {
                    AssertInitialize(p_bufferSize);
                    m_rawBufferSize = p_bufferSize;
                    m_rawBufferPointerStart = p_preAllocatedBuffer;
                    m_mutex = p_mutex;
                    m_internalMemoryManagement = false;
                    SetupVariables();
                }

                /**
                Threadsafe, internal loackage
                */
                bool Produce(const CircleBufferHeader& p_Header, const T* const p_data) // TODORT, does this not trigger
                {
                    // Internal lockage
                    std::lock_guard<std::mutex> lock(m_produceLock);

                    // Find if it is possible to produce more
                    // Does not require to lock metadata under the assumption that when circlebuffers communicate via IPC one side is only producer
                    // and the other side is only comsumer.
                    // And as this part is already locked with internal lockage above
                    if(m_data->currentObjectCount < m_maxContainedObjects)
                    {
                        // Local head
                        void* head = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_data->currentHeadOffset);

                        // Check if current pointer is outside our scope.
                        if(PointerArithmetic::AssertAdresstInside(head, m_adjustedBufferPointerStart, m_adjustedBufferPointerEnd) == false)
                        {
                            head = m_adjustedBufferPointerStart; // If so, reset to first part.
                        }

                        //// Produce is ok
                        // Copy metaheader to current_head
                        memcpy(head, &p_Header, sizeof(CircleBufferHeader));

                        // Move head to after metaheader
                        head = PointerArithmetic::Addition(head, sizeof(CircleBufferHeader));

                        // Copy data to head
                        memcpy(head, p_data, p_Header.packageSize);

                        // Move head to after data
                        head = PointerArithmetic::Addition(head, p_Header.packageSize);

                        // Update global head
                        m_data->currentHeadOffset = PointerArithmetic::Difference(m_adjustedBufferPointerStart, head);

                        // Filemap lock
                        LockMetaData();

                        // Update object count
                        m_data->currentObjectCount++;

                        // Unlock filemap
                        UnLockMetaData();

                        // Complete
                        return true;
                    }
                    else
                    {
                        // Failed
                        return false;
                    }
                    return true;
                }

                /**
                Not threadsafe
                */
                bool Consume(CircleBufferHeader*& out_header, T*& out_data)
                {
                    // Internal lockage
                    std::lock_guard<std::mutex> lock(m_consumeLock);

                    // Find if it is possible to consume anything
                    // Does not require to lock metadata under the assumption that when circlebuffers communicate via IPC one side is only producer
                    // and the other side is only comsumer.
                    // And as this part is already locked with internal lockage above
                    if(m_data->currentObjectCount > 0)
                    {
                        // Local tail
                        void* tail = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_data->currentTailOffset);

                        // Check if current pointer is outside our scope.
                        if(PointerArithmetic::AssertAdresstInside(tail, m_adjustedBufferPointerStart, m_adjustedBufferPointerEnd) == false)
                        {
                            tail = m_adjustedBufferPointerStart; // If so, reset to first part.
                        }

                        //// Produce is ok
                        // Copy metaheader to current_head
                        memcpy(out_header, tail, sizeof(CircleBufferHeader));

                        // Move header to after metaheader
                        tail = PointerArithmetic::Addition(tail, sizeof(CircleBufferHeader));

                        // Copy data to current:_head
                        memcpy(out_data, tail, out_header->packageSize);

                        // Move header to after data
                        tail = PointerArithmetic::Addition(tail, out_header->packageSize);

                        // Update global tail
                        m_data->currentTailOffset = PointerArithmetic::Difference(m_adjustedBufferPointerStart, tail);

                        // Filemap lock
                        LockMetaData();

                        // Update object count
                        m_data->currentObjectCount--;

                        // Unlock filemap
                        UnLockMetaData();

                        return true;
                    }
                    else
                    {
                        // Nothing to do
                        return false;
                    }
                    return true;
                }

            protected:
                void CircleBuffer::AssertInitialize(const size_t& p_bufferSize)
                {
                    m_sizeOfOneObject = sizeof(T) + sizeof(CircleBufferHeader);
                    if(m_sizeOfOneObject > (p_bufferSize - sizeof(StaticData)))
                    {
                        const std::string errorMessage =
                            std::string("Not enough space. Each object will take up sizeof(T) + sizeof(CircleBufferHeader) which is " +
                                        std::to_string(sizeof(T)) + "+" + std::to_string(sizeof(CircleBufferHeader)) + "=" +
                                        std::to_string(m_sizeOfOneObject) + ". This buffer only has access to " + std::to_string(p_bufferSize) + "-" +
                                        std::to_string(sizeof(StaticData)) + "=" + std::to_string(p_bufferSize - sizeof(StaticData)));
                        throw std::runtime_error(errorMessage);
                    }
                    if(m_alreadyInitialized)
                    {
                        throw std::runtime_error("Already initialized.");
                    }
                }

                void CircleBuffer::LockMetaData()
                {
                    if(m_mutex != nullptr)
                    {
                        m_mutex->AttemptLock();
                    }
                }

                void CircleBuffer::UnLockMetaData()
                {
                    if(m_mutex != nullptr)
                    {
                        m_mutex->Unlock();
                    }
                }

                void CircleBuffer::ComputeAdjustments()
                {
                    m_adjustedBufferSize = m_rawBufferSize - sizeof(StaticData);
                    m_adjustedBufferSize = (m_adjustedBufferSize / m_sizeOfOneObject) * m_sizeOfOneObject;

                    m_adjustedBufferPointerStart = PointerArithmetic::Addition(m_rawBufferPointerStart, sizeof(StaticData));
                    m_adjustedBufferPointerEnd = PointerArithmetic::Addition(m_adjustedBufferPointerStart, m_adjustedBufferSize);
                }

                void CircleBuffer::ComputeMaxObjects() { m_maxContainedObjects = m_adjustedBufferSize / m_sizeOfOneObject; }

                void CircleBuffer::SetupVariables()
                {
                    m_alreadyInitialized = true;
                    m_rawBufferPointerEnd = PointerArithmetic::Addition(m_rawBufferPointerStart, m_rawBufferSize);
                    ComputeAdjustments();
                    ComputeMaxObjects();
                    m_data = static_cast<StaticData*>(m_rawBufferPointerStart);

                    // TODORT
                    // LockMetaData In a very specific state both processes may come here at about the same time.
                    // However, that should not be a problem. If they're almost here at the same no data should be lost.
                    if(m_data->started != STARTED)
                    {
                        *m_data = StaticData();
                        m_data->currentTailOffset = 0;
                        m_data->currentHeadOffset = 0;
                    }
                    // TODORT
                    // UnLockMetaData
                }

                StaticData* m_data;
                void* m_rawBufferPointerStart;
                void* m_rawBufferPointerEnd;
                void* m_adjustedBufferPointerStart;
                void* m_adjustedBufferPointerEnd;
                size_t m_rawBufferSize;
                size_t m_adjustedBufferSize;
                bool m_internalMemoryManagement;
                std::mutex m_produceLock;
                std::mutex m_consumeLock;
                bool m_alreadyInitialized;
                size_t m_maxContainedObjects;
                IO::Mutex* m_mutex;
                size_t m_sizeOfOneObject;
            };
        }
    }
}<|endoftext|>


<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/mlp.h"

#include <memory>

#include "elm/core/debug_utils.h"

#include "elm/core/boost/translators/transl_str_cvtermcriteria.h"
#include "elm/core/boost/translators/transl_str_veci.h"
#include "elm/core/cv/mat_utils_inl.h"
#include "elm/core/exception.h"
#include "elm/core/layerconfig.h"
#include "elm/core/percentile.h"
#include "elm/core/signal.h"
#include "elm/ts/layer_assertions.h"

using namespace std;
using namespace cv;
using namespace elm;

namespace {

ELM_INSTANTIATE_LAYER_TYPED_TEST_CASE_P(MLP);

const string NAME_IN             = "in";
const string NAME_OUT_PREDICTION = "out";

class MLPInitTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        config_ = LayerConfig();

        // params
        {
            PTree params;

            VecI arch = {2, 2, 1};

            params.add(MLP::PARAM_ARCH, arch);
            params.add(MLP::PARAM_BP_DW_SCALE, 0.05f);
            params.add(MLP::PARAM_BP_MOMENT_SCALE, 0.05f);

            CvTermCriteria criteria;
            criteria.max_iter = 1000;
            criteria.epsilon = 0.00001f;
            criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;

            params.add(MLP::PARAM_TERM_CRITERIA, criteria);

            config_.Params(params);
        }

        io_ = LayerIONames();
        io_.Input(MLP::KEY_INPUT_STIMULUS, NAME_IN);
        io_.Output(MLP::KEY_OUTPUT_RESPONSE, NAME_OUT_PREDICTION);

        to_.reset(new MLP(config_));
        to_->IONames(io_);
    }

    shared_ptr<base_Layer> to_; ///< test object
    LayerConfig config_;        ///< default config for tests
    LayerIONames io_;
};

TEST_F(MLPInitTest, Reset_EmptyConfig)
{
    EXPECT_THROW(to_->Reset(LayerConfig()), boost::property_tree::ptree_bad_path);
}

TEST_F(MLPInitTest, Param_invalid_layers_too_few)
{
    PTree params = config_.Params();
    {
        VecI arch = {2};
        params.put(MLP::PARAM_ARCH, arch);
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
    {
        VecI arch = {200};
        params.put(MLP::PARAM_ARCH, arch);
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
}

TEST_F(MLPInitTest, Param_invalid_layers_none)
{
    PTree params = config_.Params();
    {
        params.put(MLP::PARAM_ARCH, VecI());
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
}

class MLPTrainTest : public MLPInitTest
{
public:
    void GenerateSeparableBinary(int n, int feat_dims, cv::Mat1f &feat, cv::Mat1f &labels)
    {
        const float NEG_CLASS = -1.f;
        const float POS_CLASS = 1.f;

        feat = Mat1f(n, feat_dims);
        labels = Mat1f(n, 1);

        Mat1f feat_neg(n/2, feat_dims);
        cv::randn(feat_neg, -1.f, 1.f);
        Mat1f labels_neg(feat_neg.rows, 1, NEG_CLASS);

        Mat1f feat_pos(n/2, feat_dims);
        cv::randn(feat_pos, 1.f, 1.f);
        Mat1f labels_pos(feat_pos.rows, 1, POS_CLASS);

        Mat1f feat_concat, labels_concat;

        vconcat(feat_neg, feat_pos, feat_concat);
        vconcat(labels_neg, labels_pos, labels_concat);

        Mat1i idx = ARange_<int>(0, feat_concat.rows, 1);
        cv::randShuffle(idx);

        for (int src_idx=0; src_idx<n; src_idx++) {

            int dst_idx = idx(src_idx);
            feat_concat.row(src_idx).copyTo(feat.row(dst_idx));
            labels_concat.row(src_idx).copyTo(labels.row(dst_idx));
        }
    }

protected:
    virtual void SetUp()
    {
        MLPInitTest::SetUp();

        // params
        {
            PTree params = config_.Params();

            VecI arch = {2, 2, 1};
            params.put(MLP::PARAM_ARCH, arch);

            config_.Params(params);
        }

        to_.reset(new MLP(config_));
        to_->IONames(io_);
    }
};

TEST_F(MLPTrainTest, Train_separable_binary)
{
    const int NB_TRAIN=100;
    const int FEAT_DIMS=2;

    Mat1f train_feat, train_labels;
    GenerateSeparableBinary(NB_TRAIN, FEAT_DIMS,
                            train_feat, train_labels);

    ELM_DYN_CAST(base_LearningLayer, to_)->Learn(train_feat, train_labels);

    const int NB_TEST=100;
    Mat1f test_feat, test_labels;
    GenerateSeparableBinary(NB_TEST, FEAT_DIMS,
                            test_feat, test_labels);

    Mat1i confusion = Mat1i::zeros(2, 2);
    const int TP = 0;
    const int FN = 1;
    const int FP = 2;
    const int TN = 3;

    Mat1f result(NB_TEST, 2);

    for (int i=0; i<NB_TEST; i++) {

        Mat1f test_feat_sample = test_feat.row(i);

        float target_label = test_labels.row(i)(0);

        Signal sig;
        sig.Append(NAME_IN, test_feat_sample);

        EXPECT_FALSE(sig.Exists(NAME_OUT_PREDICTION));

        to_->Activate(sig);
        to_->Response(sig);

        EXPECT_TRUE(sig.Exists(NAME_OUT_PREDICTION));

        Mat1f response = sig.MostRecentMat1f(NAME_OUT_PREDICTION);

        EXPECT_MAT_DIMS_EQ(response, Size2i(1, 1));

        float predicted = response(0);

        result(i, 0) = target_label;
        result(i, 1) = predicted;

        if(target_label >= 0.f && predicted >= 0.f) {

            confusion(TP)++;
        }
        else if(target_label < 0.f && predicted < 0.f) {

            confusion(TN)++;
        }
        else {

            confusion(target_label < 0.f? FP : FN)++;
        }
    }

    //ELM_COUT_VAR(confusion);

    ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(0))[0]);
    ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(1))[0]);

    EXPECT_GT(confusion(TP), confusion(FP));
    EXPECT_GT(confusion(TN), confusion(FN));
}

} // annonymous namespace for test fixtures and test cases
<commit_msg>start testing for multi-class classification<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2015, Youssef Kashef
// Copyright (c) 2015, ELM Library Project
// 3-clause BSD License
//
//M*/
#include "elm/layers/mlp.h"

#include <memory>

#include "elm/core/debug_utils.h"

#include "elm/core/boost/translators/transl_str_cvtermcriteria.h"
#include "elm/core/boost/translators/transl_str_veci.h"
#include "elm/core/cv/mat_utils_inl.h"
#include "elm/core/exception.h"
#include "elm/core/layerconfig.h"
#include "elm/core/percentile.h"
#include "elm/core/signal.h"
#include "elm/ts/layer_assertions.h"

using namespace std;
using namespace cv;
using namespace elm;

namespace {

ELM_INSTANTIATE_LAYER_TYPED_TEST_CASE_P(MLP);

const string NAME_IN             = "in";
const string NAME_OUT_PREDICTION = "out";

class MLPInitTest : public ::testing::Test
{
protected:
    virtual void SetUp()
    {
        config_ = LayerConfig();

        // params
        {
            PTree params;

            VecI arch = {2, 2, 1};

            params.add(MLP::PARAM_ARCH, arch);
            params.add(MLP::PARAM_BP_DW_SCALE, 0.05f);
            params.add(MLP::PARAM_BP_MOMENT_SCALE, 0.05f);

            CvTermCriteria criteria;
            criteria.max_iter = 1000;
            criteria.epsilon = 0.00001f;
            criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;

            params.add(MLP::PARAM_TERM_CRITERIA, criteria);

            config_.Params(params);
        }

        io_ = LayerIONames();
        io_.Input(MLP::KEY_INPUT_STIMULUS, NAME_IN);
        io_.Output(MLP::KEY_OUTPUT_RESPONSE, NAME_OUT_PREDICTION);

        to_.reset(new MLP(config_));
        to_->IONames(io_);
    }

    shared_ptr<base_Layer> to_; ///< test object
    LayerConfig config_;        ///< default config for tests
    LayerIONames io_;
};

TEST_F(MLPInitTest, Reset_EmptyConfig)
{
    EXPECT_THROW(to_->Reset(LayerConfig()), boost::property_tree::ptree_bad_path);
}

TEST_F(MLPInitTest, Param_invalid_layers_too_few)
{
    PTree params = config_.Params();
    {
        VecI arch = {2};
        params.put(MLP::PARAM_ARCH, arch);
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
    {
        VecI arch = {200};
        params.put(MLP::PARAM_ARCH, arch);
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
}

TEST_F(MLPInitTest, Param_invalid_layers_none)
{
    PTree params = config_.Params();
    {
        params.put(MLP::PARAM_ARCH, VecI());
        config_.Params(params);
        EXPECT_THROW(to_.reset(new MLP(config_)), ExceptionBadDims);
    }
}

class MLPTrainTest : public MLPInitTest
{
public:
    void GenerateSeparableBinary(int n, int feat_dims, cv::Mat1f &feat, cv::Mat1f &labels)
    {
        const float NEG_CLASS = -1.f;
        const float POS_CLASS = 1.f;

        feat = Mat1f(n, feat_dims);
        labels = Mat1f(n, 1);

        Mat1f feat_neg(n/2, feat_dims);
        cv::randn(feat_neg, -1.f, 1.f);
        Mat1f labels_neg(feat_neg.rows, 1, NEG_CLASS);

        Mat1f feat_pos(n/2, feat_dims);
        cv::randn(feat_pos, 1.f, 1.f);
        Mat1f labels_pos(feat_pos.rows, 1, POS_CLASS);

        Mat1f feat_concat, labels_concat;

        vconcat(feat_neg, feat_pos, feat_concat);
        vconcat(labels_neg, labels_pos, labels_concat);

        Mat1i idx = ARange_<int>(0, feat_concat.rows, 1);
        cv::randShuffle(idx);

        for (int src_idx=0; src_idx<n; src_idx++) {

            int dst_idx = idx(src_idx);
            feat_concat.row(src_idx).copyTo(feat.row(dst_idx));
            labels_concat.row(src_idx).copyTo(labels.row(dst_idx));
        }
    }

    void GenerateSeparableMultiClass(int nb_classes, int n, int feat_dims, cv::Mat1f &feat, cv::Mat1f &labels)
    {
        const float NEG_CLASS = -1.f;
        const float POS_CLASS = 1.f;

        feat = Mat1f(n, feat_dims);
        labels = Mat1f(n, 1);

        float mu_start = -2.f;
        float mu_incr = 1.f;

        Mat1f feat_concat, labels_concat;

        for (int i=0; i<; i++) {

            Mat1f feati(n/, feat_dims);
            cv::randn(feati, -2.f, 1.f);
            Mat1f labelsi(feati.rows, 1, 0.f);
            labelsi.col(0).setTo(1.f);

            if(i > 0) {

                vconcat(feat_concat, feati, feat_concat);
                vconcat(labels_concat, labelsi, labels_concat);
            }
            else {

                feat_concat = feati;
                labels_concat = labelsi;
            }
        }

        Mat1i idx = ARange_<int>(0, feat_concat.rows, 1);
        cv::randShuffle(idx);

        for (int src_idx=0; src_idx<n; src_idx++) {

            int dst_idx = idx(src_idx);
            feat_concat.row(src_idx).copyTo(feat.row(dst_idx));
            labels_concat.row(src_idx).copyTo(labels.row(dst_idx));
        }
    }

protected:
    virtual void SetUp()
    {
        MLPInitTest::SetUp();

        // params
        {
            PTree params = config_.Params();

            VecI arch = {2, 2, 1};
            params.put(MLP::PARAM_ARCH, arch);

            config_.Params(params);
        }

        to_.reset(new MLP(config_));
        to_->IONames(io_);
    }
};

TEST_F(MLPTrainTest, Train_separable_binary)
{
    const int NB_TRAIN=100;
    const int FEAT_DIMS=2;

    Mat1f train_feat, train_labels;
    GenerateSeparableBinary(NB_TRAIN, FEAT_DIMS,
                            train_feat, train_labels);

    ELM_DYN_CAST(base_LearningLayer, to_)->Learn(train_feat, train_labels);

    const int NB_TEST=100;
    Mat1f test_feat, test_labels;
    GenerateSeparableBinary(NB_TEST, FEAT_DIMS,
                            test_feat, test_labels);

    Mat1i confusion = Mat1i::zeros(2, 2);
    const int TP = 0;
    const int FN = 1;
    const int FP = 2;
    const int TN = 3;

    Mat1f result(NB_TEST, 2);

    for (int i=0; i<NB_TEST; i++) {

        Mat1f test_feat_sample = test_feat.row(i);

        float target_label = test_labels.row(i)(0);

        Signal sig;
        sig.Append(NAME_IN, test_feat_sample);

        EXPECT_FALSE(sig.Exists(NAME_OUT_PREDICTION));

        to_->Activate(sig);
        to_->Response(sig);

        EXPECT_TRUE(sig.Exists(NAME_OUT_PREDICTION));

        Mat1f response = sig.MostRecentMat1f(NAME_OUT_PREDICTION);

        EXPECT_MAT_DIMS_EQ(response, Size2i(1, 1));

        float predicted = response(0);

        result(i, 0) = target_label;
        result(i, 1) = predicted;

        if(target_label >= 0.f && predicted >= 0.f) {

            confusion(TP)++;
        }
        else if(target_label < 0.f && predicted < 0.f) {

            confusion(TN)++;
        }
        else {

            confusion(target_label < 0.f? FP : FN)++;
        }
    }

    //ELM_COUT_VAR(confusion);

    ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(0))[0]);
    ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(1))[0]);

    EXPECT_GT(confusion(TP), confusion(FP));
    EXPECT_GT(confusion(TN), confusion(FN));
}

TEST_F(MLPTrainTest, Train_separable_multiclass)
{
    const int NB_CLASSES=4;
    const int NB_TRAIN=120;
    const int FEAT_DIMS=2;

    Mat1f train_feat, train_labels;
    GenerateSeparableMultiClass(NB_CLASSES, NB_TRAIN, FEAT_DIMS,
                                train_feat, train_labels);

    ELM_DYN_CAST(base_LearningLayer, to_)->Learn(train_feat, train_labels);

    const int NB_TEST=120;
    Mat1f test_feat, test_labels;
    GenerateSeparableBinary(NB_CLASSES, NB_TEST, FEAT_DIMS,
                            test_feat, test_labels);

//    for(int c=0; c<NB_CLASSES; c++) {

//        Mat1i confusion = Mat1i::zeros(2, 2);
//        const int TP = 0;
//        const int FN = 1;
//        const int FP = 2;
//        const int TN = 3;

//        Mat1f result(NB_TEST, 2);

//        for (int i=0; i<NB_TEST; i++) {

//            Mat1f test_feat_sample = test_feat.row(i);

//            float target_label = test_labels.row(i)(0);

//            Signal sig;
//            sig.Append(NAME_IN, test_feat_sample);

//            EXPECT_FALSE(sig.Exists(NAME_OUT_PREDICTION));

//            to_->Activate(sig);
//            to_->Response(sig);

//            EXPECT_TRUE(sig.Exists(NAME_OUT_PREDICTION));

//            Mat1f response = sig.MostRecentMat1f(NAME_OUT_PREDICTION);

//            EXPECT_MAT_DIMS_EQ(response, Size2i(1, 1));

//            float predicted = response(0);

//            result(i, 0) = target_label;
//            result(i, 1) = predicted;

//            if(target_label >= 0.f && predicted >= 0.f) {

//                confusion(TP)++;
//            }
//            else if(target_label < 0.f && predicted < 0.f) {

//                confusion(TN)++;
//            }
//            else {

//                confusion(target_label < 0.f? FP : FN)++;
//            }
//        }

//        //ELM_COUT_VAR(confusion);

//        ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(0))[0]);
//        ASSERT_EQ(NB_TEST/2, cv::sum(confusion.row(1))[0]);

//        EXPECT_GT(confusion(TP), confusion(FP));
//        EXPECT_GT(confusion(TN), confusion(FN));
//    }
}

} // annonymous namespace for test fixtures and test cases
<|endoftext|>


<commit_before>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /castor/cern.ch/alice/phos/2007/10/04/18/07000008249001.1000.root
run type: STANDALONE
DA type: MON
number of events needed: 1000
input files: RCU0.data  RCU1.data  RCU2.data  RCU3.data
Output files: PHOS_Module2_LED.root
Trigger types used: CALIBRATION_EVENT
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawDecoder.h"
#include "AliCaloAltroMapping.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[4] = {"RCU0.data","RCU1.data","RCU2.data","RCU3.data"};

  for(Int_t iFile=0; iFile<4; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = "./";
  path += "RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  Int_t fMod = 2; // module 2!
  AliRawReader *rawReader = NULL;

  AliPHOSRcuDA1 da1(fMod,-1,0); // DA1 for module2, no input/output file

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t gain = -1;
  Int_t X = -1;
  Int_t Z = -1;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    e[iX][iZ][iGain] = 0.;
	    t[iX][iZ][iGain] = 0.;
	  }
	}
      }

      rawReader = new AliRawReaderDate((void*)event);
//       AliPHOSRawDecoderv1 dc(rawReader,mapping);
      AliPHOSRawDecoder dc(rawReader,mapping);
      dc.SubtractPedestals(kTRUE);

      while(dc.NextDigit()) {

	X = dc.GetRow() - 1;
	Z = dc.GetColumn() - 1;

	if(dc.IsLowGain()) gain = 0;
	else
	  gain = 1;

	e[X][Z][gain] = dc.GetEnergy();
	t[X][Z][gain] = dc.GetTime();

      }

      da1.FillHistograms(e,t);

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  char localfile[128];
  sprintf(localfile,"PHOS_Module%d_LED.root",fMod);
  TFile* f = new TFile(localfile,"recreate");

  const TH2F* h2=0;
  const TH1F* h1=0;

  Int_t nGood=0;    // >10 entries in peak
  Int_t nMax=-111;  // max. number of entries in peak
  Int_t iXmax=-1;
  Int_t iZmax=-1;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {

      h1 = da1.GetHgLgRatioHistogram(iX,iZ); // High Gain/Low Gain ratio
      if(h1) {
	if(h1->GetMaximum()>10.) nGood++;
	if(h1->GetMaximum()>nMax) {nMax = (Int_t)h1->GetMaximum(); iXmax=iX; iZmax=iZ;}
	h1->Write();
      }

      for(Int_t iGain=0; iGain<2; iGain++) {
	h2 = da1.GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	if(h2) h2->Write();
      }

    }
  }

  f->Close();

  /* Store output files to the File Exchange Server */
  char fesfileid[128];

  for(Int_t iMod=0; iMod<5; iMod++) {
    sprintf(localfile,"PHOS_Module%d_LED.root",iMod);
    sprintf(fesfileid,"PHOS_Module%d_LED",iMod);
    daqDA_FES_storeFile(localfile,fesfileid);
  }

  printf("%d physics events of %d total processed.\n",nevents_physics,nevents_total);
  printf("%d histograms has >10 entries in maximum, max. is %d entries ",nGood,nMax);
  printf("(module,iX,iZ)=(%d,%d,%d)",fMod,iXmax,iZmax);
  printf("\n");

  return status;
}
<commit_msg>File Exchange Server file Id (fesfileid) corrected.<commit_after>/*
contact: Boris.Polishchuk@cern.ch
link: see comments in the $ALICE_ROOT/PHOS/AliPHOSRcuDA1.cxx
reference run: /castor/cern.ch/alice/phos/2007/10/04/18/07000008249001.1000.root
run type: STANDALONE
DA type: MON
number of events needed: 1000
input files: RCU0.data  RCU1.data  RCU2.data  RCU3.data
Output files: PHOS_Module2_LED.root
Trigger types used: CALIBRATION_EVENT
*/

#include "event.h"
#include "monitor.h"
extern "C" {
#include "daqDA.h"
}

#include <stdio.h>
#include <stdlib.h>

#include <TSystem.h>
#include <TROOT.h>
#include <TPluginManager.h>

#include "AliRawReader.h"
#include "AliRawReaderDate.h"
#include "AliPHOSRcuDA1.h"
#include "AliPHOSRawDecoder.h"
#include "AliCaloAltroMapping.h"

/* Main routine
      Arguments:
      1- monitoring data source
*/
int main(int argc, char **argv) {

  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
					"*",
					"TStreamerInfo",
					"RIO",
					"TStreamerInfo()");

  int status;

  if (argc!=2) {
    printf("Wrong number of arguments\n");
    return -1;
  }

  /* Retrieve mapping files from DAQ DB */
  const char* mapFiles[4] = {"RCU0.data","RCU1.data","RCU2.data","RCU3.data"};

  for(Int_t iFile=0; iFile<4; iFile++) {
    int failed = daqDA_DB_getFile(mapFiles[iFile], mapFiles[iFile]);
    if(failed) {
      printf("Cannot retrieve file %s from DAQ DB. Exit.\n",mapFiles[iFile]);
      return -1;
    }
  }

  /* Open mapping files */
  AliAltroMapping *mapping[4];
  TString path = "./";
  path += "RCU";
  TString path2;
  for(Int_t i = 0; i < 4; i++) {
    path2 = path;
    path2 += i;
    path2 += ".data";
    mapping[i] = new AliCaloAltroMapping(path2.Data());
  }

  /* define data source : this is argument 1 */
  status=monitorSetDataSource( argv[1] );
  if (status!=0) {
    printf("monitorSetDataSource() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* declare monitoring program */
  status=monitorDeclareMp( __FILE__ );
  if (status!=0) {
    printf("monitorDeclareMp() failed : %s\n",monitorDecodeError(status));
    return -1;
  }

  /* define wait event timeout - 1s max */
  monitorSetNowait();
  monitorSetNoWaitNetworkTimeout(1000);

   /* init some counters */
  int nevents_physics=0;
  int nevents_total=0;

  Int_t fMod = 2; // module 2!
  AliRawReader *rawReader = NULL;

  AliPHOSRcuDA1 da1(fMod,-1,0); // DA1 for module2, no input/output file

  Float_t e[64][56][2];
  Float_t t[64][56][2];

  Int_t gain = -1;
  Int_t X = -1;
  Int_t Z = -1;

  /* main loop (infinite) */
  for(;;) {
    struct eventHeaderStruct *event;
    eventTypeType eventT;

    /* check shutdown condition */
    if (daqDA_checkShutdown()) {break;}

    /* get next event (blocking call until timeout) */
    status=monitorGetEventDynamic((void **)&event);
    if (status==MON_ERR_EOF) {
      printf ("End of File detected\n");
      break; /* end of monitoring file has been reached */
    }

    if (status!=0) {
      printf("monitorGetEventDynamic() failed : %s\n",monitorDecodeError(status));
      break;
    }

    /* retry if got no event */
    if (event==NULL) {
      continue;
    }

    /* use event - here, just write event id to result file */
    eventT=event->eventType;

    if (eventT==PHYSICS_EVENT) {

      for(Int_t iX=0; iX<64; iX++) {
	for(Int_t iZ=0; iZ<56; iZ++) {
	  for(Int_t iGain=0; iGain<2; iGain++) {
	    e[iX][iZ][iGain] = 0.;
	    t[iX][iZ][iGain] = 0.;
	  }
	}
      }

      rawReader = new AliRawReaderDate((void*)event);
//       AliPHOSRawDecoderv1 dc(rawReader,mapping);
      AliPHOSRawDecoder dc(rawReader,mapping);
      dc.SubtractPedestals(kTRUE);

      while(dc.NextDigit()) {

	X = dc.GetRow() - 1;
	Z = dc.GetColumn() - 1;

	if(dc.IsLowGain()) gain = 0;
	else
	  gain = 1;

	e[X][Z][gain] = dc.GetEnergy();
	t[X][Z][gain] = dc.GetTime();

      }

      da1.FillHistograms(e,t);

      delete rawReader;
      nevents_physics++;
    }

    nevents_total++;

    /* free resources */
    free(event);

    /* exit when last event received, no need to wait for TERM signal */
    if (eventT==END_OF_RUN) {
      printf("EOR event detected\n");
      break;
    }
  }

  for(Int_t i = 0; i < 4; i++) delete mapping[i];

  /* Be sure that all histograms are saved */

  char localfile[128];
  sprintf(localfile,"PHOS_Module%d_LED.root",fMod);
  TFile* f = new TFile(localfile,"recreate");

  const TH2F* h2=0;
  const TH1F* h1=0;

  Int_t nGood=0;    // >10 entries in peak
  Int_t nMax=-111;  // max. number of entries in peak
  Int_t iXmax=-1;
  Int_t iZmax=-1;

  for(Int_t iX=0; iX<64; iX++) {
    for(Int_t iZ=0; iZ<56; iZ++) {

      h1 = da1.GetHgLgRatioHistogram(iX,iZ); // High Gain/Low Gain ratio
      if(h1) {
	if(h1->GetMaximum()>10.) nGood++;
	if(h1->GetMaximum()>nMax) {nMax = (Int_t)h1->GetMaximum(); iXmax=iX; iZmax=iZ;}
	h1->Write();
      }

      for(Int_t iGain=0; iGain<2; iGain++) {
	h2 = da1.GetTimeEnergyHistogram(iX,iZ,iGain); // Time vs Energy
	if(h2) h2->Write();
      }

    }
  }

  f->Close();

  /* Store output files to the File Exchange Server */

  for(Int_t iMod=0; iMod<5; iMod++) {
    sprintf(localfile,"PHOS_Module%d_LED.root",iMod);
    daqDA_FES_storeFile(localfile,"LED");
  }

  printf("%d physics events of %d total processed.\n",nevents_physics,nevents_total);
  printf("%d histograms has >10 entries in maximum, max. is %d entries ",nGood,nMax);
  printf("(module,iX,iZ)=(%d,%d,%d)",fMod,iXmax,iZmax);
  printf("\n");

  return status;
}
<|endoftext|>


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

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

  Copyright (c) 2002 Insight 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.

=========================================================================*/
#include "itkIOCommon.h"
#include <sys/stat.h>

namespace itk
{
  // CODE STOLEN STRAIGHT FROM CMAKE
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
#include <string.h>
#include <windows.h>
#include <direct.h>
#define _unlink unlink
inline int Mkdir(const char* dir)
{
  return _mkdir(dir);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return _getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  #if defined(__BORLANDC__)
  return chdir(dir);
  #else
  return _chdir(dir);
  #endif
}
#else
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
inline int Mkdir(const char* dir)
{
  return mkdir(dir, 00777);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  return chdir(dir);
}
#endif

std::string IOCommon
::AtomicPixelTypeToString(const AtomicPixelType pixelType)
{
  switch(pixelType)
    {
    case ITK_UCHAR:
      return "unsigned char";
      break;
    case ITK_CHAR:
      return "char";
      break;
    case ITK_USHORT:
      return "unsigned short";
      break;
    case ITK_SHORT:
      return "short";
      break;
    case ITK_UINT:
      return "unsigned int";
      break;
    case ITK_INT:
      return "int";
      break;
    case ITK_ULONG:
      return "unsigned long";
      break;
    case ITK_LONG:
      return "long";
      break;
    case ITK_FLOAT:
      return "float";
      break;
    case ITK_DOUBLE:
      return "double";
      break;
    default:
      return "unknown";
      break;
    }
}

unsigned int IOCommon
::ComputeSizeOfAtomicPixelType(const AtomicPixelType pixelType)
{
  switch (pixelType)
    {
    case ITK_CHAR:
      return sizeof(char);
      break;
    case ITK_UCHAR:
      return sizeof(unsigned char);
      break;
    case ITK_SHORT:
      return sizeof(short);
      break;
    case ITK_USHORT:
      return sizeof(unsigned short);
      break;
    case ITK_INT:
      return sizeof(int);
      break;
    case ITK_UINT:
      return sizeof(unsigned int);
      break;
    case ITK_LONG:
      return sizeof(long);
      break;
    case ITK_ULONG:
      return sizeof(unsigned long);
      break;
    case ITK_FLOAT:
      return sizeof(float);
      break;
    case ITK_DOUBLE:
      return sizeof(double);
      break;
    default:
      return sizeof(char);
      break;
    }
}

int IOCommon
::Strucmp(const char *s1, const char *s2)
{
  char* s1_up = new char[strlen(s1)+1];
  char* s2_up = new char[strlen(s2)+1];
  int i;

  strcpy(s1_up, s1);
  strcpy(s2_up, s2);

  for (i = 0; s1_up[i]; i++)
    {
    s1_up[i] = islower(s1_up[i]) ? toupper(s1_up[i]) : s1_up[i];
    }
  for (i = 0; s2_up[i]; i++)
    {
    s2_up[i] = islower(s2_up[i]) ? toupper(s2_up[i]) : s2_up[i];
    }
  int rc = strcmp(s1_up, s2_up);
  delete [] s1_up;
  delete [] s2_up;
  return rc;
}

char* IOCommon
::ExtractFileName (const char* fileName)
{
  const char* dot;
  const char* slash;
  char* fName = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      slash = (const char*) fileName;
      }
    else
      {
      slash++;
      }
    dot = strrchr(fileName, '.');
    if (dot == NULL)
      {
      dot = (const char*) fileName + strlen(fileName);
      }
    fName = new char[strlen(slash) - strlen(dot) + 1];
    strncpy(fName, slash, strlen(slash) - strlen(dot));
    fName[strlen(slash) - strlen(dot)] = '\0';
  }

  return fName;
}

char* IOCommon
::ExtractFileExtension (const char* fileName)
{
  const char* dot;
  char* fExtension = NULL;

  dot = strrchr(fileName, '.');
  if (dot != NULL)
    {
    dot++;
    fExtension = new char[strlen(dot)+1];
    strcpy(fExtension, dot);
    fExtension[strlen(dot)] = '\0';
    }

  return fExtension;
}

char* IOCommon
::ExtractFilePath (const char* fileName)
{
  const char* slash;
  char* fPath = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      fPath = NULL;
      }
    else
      {
      slash++;
      fPath = new char[strlen(fileName) - strlen(slash) + 1];
      strncpy(fPath, fileName, strlen(fileName) - strlen(slash));
      fPath[strlen(fileName) - strlen(slash)] = '\0';
      }
    }

  return fPath;
}

// return true if the file exists
bool IOCommon
::FileExists(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
    return false;
    }
  else
    {
    return true;
    }
}
// return size of file; also returns zero if no file exists
unsigned long IOCommon
::FileLength(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
      return 0;
    }
  else
    {
      return fs.st_size;
    }
}

char *IOCommon
::RealPath(const char *path, char *resolved_path)
{
#if defined(_WIN32)
  char pathpart[MAXPATHLEN];
  std::strcpy(pathpart,path);
  char fnamepart[MAXPATHLEN];
  char *slash;

  if((slash = std::strrchr(pathpart,'/')) == NULL)
    {
      slash = std::strrchr(pathpart,'\\');
    }

  if(slash == NULL) // no path part, so just use current dir.
    {
      Getcwd(pathpart,sizeof(pathpart));
      std::strcpy(fnamepart,path);
    }
  else // change directory to path part, getcwd to find OS resolved path
    {
      *slash = '\0';
      strcpy(fnamepart,slash+1);

      char savedir[MAXPATHLEN];
      Getcwd(savedir,sizeof(savedir));
      Chdir(pathpart);
      Getcwd(pathpart,sizeof(pathpart));
      Chdir(savedir);
    }
  std::strcpy(resolved_path,pathpart);
  std::strcat(resolved_path,"/");
  std::strcat(resolved_path,fnamepart);
  return resolved_path;
#else
  return realpath(path,resolved_path);
#endif
}

} // namespace itk
<commit_msg>ERR: strcat,strcpy are not in std::.<commit_after>/*=========================================================================

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

  Copyright (c) 2002 Insight 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.

=========================================================================*/
#include "itkIOCommon.h"
#include <sys/stat.h>

namespace itk
{
  // CODE STOLEN STRAIGHT FROM CMAKE
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__BORLANDC__))
#include <string.h>
#include <windows.h>
#include <direct.h>
#define _unlink unlink
inline int Mkdir(const char* dir)
{
  return _mkdir(dir);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return _getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  #if defined(__BORLANDC__)
  return chdir(dir);
  #else
  return _chdir(dir);
  #endif
}
#else
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
inline int Mkdir(const char* dir)
{
  return mkdir(dir, 00777);
}
inline const char* Getcwd(char* buf, unsigned int len)
{
  return getcwd(buf, len);
}
inline int Chdir(const char* dir)
{
  return chdir(dir);
}
#endif

::std::string IOCommon
::AtomicPixelTypeToString(const AtomicPixelType pixelType)
{
  switch(pixelType)
    {
    case ITK_UCHAR:
      return "unsigned char";
      break;
    case ITK_CHAR:
      return "char";
      break;
    case ITK_USHORT:
      return "unsigned short";
      break;
    case ITK_SHORT:
      return "short";
      break;
    case ITK_UINT:
      return "unsigned int";
      break;
    case ITK_INT:
      return "int";
      break;
    case ITK_ULONG:
      return "unsigned long";
      break;
    case ITK_LONG:
      return "long";
      break;
    case ITK_FLOAT:
      return "float";
      break;
    case ITK_DOUBLE:
      return "double";
      break;
    default:
      return "unknown";
      break;
    }
}

unsigned int IOCommon
::ComputeSizeOfAtomicPixelType(const AtomicPixelType pixelType)
{
  switch (pixelType)
    {
    case ITK_CHAR:
      return sizeof(char);
      break;
    case ITK_UCHAR:
      return sizeof(unsigned char);
      break;
    case ITK_SHORT:
      return sizeof(short);
      break;
    case ITK_USHORT:
      return sizeof(unsigned short);
      break;
    case ITK_INT:
      return sizeof(int);
      break;
    case ITK_UINT:
      return sizeof(unsigned int);
      break;
    case ITK_LONG:
      return sizeof(long);
      break;
    case ITK_ULONG:
      return sizeof(unsigned long);
      break;
    case ITK_FLOAT:
      return sizeof(float);
      break;
    case ITK_DOUBLE:
      return sizeof(double);
      break;
    default:
      return sizeof(char);
      break;
    }
}

int IOCommon
::Strucmp(const char *s1, const char *s2)
{
  char* s1_up = new char[strlen(s1)+1];
  char* s2_up = new char[strlen(s2)+1];
  int i;

  strcpy(s1_up, s1);
  strcpy(s2_up, s2);

  for (i = 0; s1_up[i]; i++)
    {
    s1_up[i] = islower(s1_up[i]) ? toupper(s1_up[i]) : s1_up[i];
    }
  for (i = 0; s2_up[i]; i++)
    {
    s2_up[i] = islower(s2_up[i]) ? toupper(s2_up[i]) : s2_up[i];
    }
  int rc = strcmp(s1_up, s2_up);
  delete [] s1_up;
  delete [] s2_up;
  return rc;
}

char* IOCommon
::ExtractFileName (const char* fileName)
{
  const char* dot;
  const char* slash;
  char* fName = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      slash = (const char*) fileName;
      }
    else
      {
      slash++;
      }
    dot = strrchr(fileName, '.');
    if (dot == NULL)
      {
      dot = (const char*) fileName + strlen(fileName);
      }
    fName = new char[strlen(slash) - strlen(dot) + 1];
    strncpy(fName, slash, strlen(slash) - strlen(dot));
    fName[strlen(slash) - strlen(dot)] = '\0';
  }

  return fName;
}

char* IOCommon
::ExtractFileExtension (const char* fileName)
{
  const char* dot;
  char* fExtension = NULL;

  dot = strrchr(fileName, '.');
  if (dot != NULL)
    {
    dot++;
    fExtension = new char[strlen(dot)+1];
    strcpy(fExtension, dot);
    fExtension[strlen(dot)] = '\0';
    }

  return fExtension;
}

char* IOCommon
::ExtractFilePath (const char* fileName)
{
  const char* slash;
  char* fPath = NULL;

  if (fileName != NULL)
    {
    slash = strrchr(fileName, '/');
    if (slash == NULL)
      {
      slash = strrchr(fileName, '\\');
      }
    if (slash == NULL)
      {
      fPath = NULL;
      }
    else
      {
      slash++;
      fPath = new char[strlen(fileName) - strlen(slash) + 1];
      strncpy(fPath, fileName, strlen(fileName) - strlen(slash));
      fPath[strlen(fileName) - strlen(slash)] = '\0';
      }
    }

  return fPath;
}

// return true if the file exists
bool IOCommon
::FileExists(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
    return false;
    }
  else
    {
    return true;
    }
}
// return size of file; also returns zero if no file exists
unsigned long IOCommon
::FileLength(const char* filename)
{
  struct stat fs;
  if (stat(filename, &fs) != 0)
    {
      return 0;
    }
  else
    {
      return fs.st_size;
    }
}

char *IOCommon
::RealPath(const char *path, char *resolved_path)
{
#if defined(_WIN32)
  char pathpart[MAXPATHLEN];
  strcpy(pathpart,path);
  char fnamepart[MAXPATHLEN];
  char *slash;

  if((slash = strrchr(pathpart,'/')) == NULL)
    {
      slash = strrchr(pathpart,'\\');
    }

  if(slash == NULL) // no path part, so just use current dir.
    {
      Getcwd(pathpart,sizeof(pathpart));
      strcpy(fnamepart,path);
    }
  else // change directory to path part, getcwd to find OS resolved path
    {
      *slash = '\0';
      strcpy(fnamepart,slash+1);

      char savedir[MAXPATHLEN];
      Getcwd(savedir,sizeof(savedir));
      Chdir(pathpart);
      Getcwd(pathpart,sizeof(pathpart));
      Chdir(savedir);
    }
  strcpy(resolved_path,pathpart);
  strcat(resolved_path,"/");
  strcat(resolved_path,fnamepart);
  return resolved_path;
#else
  return realpath(path,resolved_path);
#endif
}

} // namespace itk
<|endoftext|>


<commit_before>/*=============================================================================
 Copyright (c) 2012-2014 Richard Otis

 Distributed under the Boost Software License, Version 1.0. (See accompanying
 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/

// Deep copy/rename (DCR) implementation for EnergyModel

#include "libgibbs/include/libgibbs_pch.hpp"
#include "libgibbs/include/utils/ast_container_rename.hpp"
#include "libgibbs/include/utils/ast_variable_rename.hpp"
#include "libgibbs/include/models.hpp"
#include "libtdb/include/logging.hpp"
#include <memory>

std::unique_ptr<EnergyModel> EnergyModel::clone_with_renamed_phase (
    const std::string &old_phase_name,
    const std::string &new_phase_name
) const
{
    BOOST_LOG_NAMED_SCOPE ( "EnergyModel::clone_with_renamed_phase" );
    logger opto_log ( journal::keywords::channel = "optimizer" );
    BOOST_LOG_SEV( opto_log, debug ) << "entered";
    auto copymodel = std::unique_ptr<EnergyModel> ( new EnergyModel ( *this ) );
    BOOST_LOG_SEV( opto_log, debug ) << "created EnergyModel copy tethered to unique_ptr";
    // Deep copy and rename the ast_symbol_table
    ASTSymbolMap new_map ( ast_copy_with_renamed_phase ( ast_symbol_table, old_phase_name, new_phase_name ) );
    BOOST_LOG_SEV( opto_log, debug ) << "DCR ASTSymbolMap";
    // Perform a deep rename on model_ast
    ast_variable_rename ( copymodel->model_ast, old_phase_name, new_phase_name );
    BOOST_LOG_SEV( opto_log, debug ) << "DCR model_ast";
    copymodel->ast_symbol_table = std::move ( new_map );
    BOOST_LOG_SEV( opto_log, debug ) << "returning";
    return std::move ( copymodel );
}
<commit_msg>More verbose logging for EnergyModel::clone_with_renamed_phase().<commit_after>/*=============================================================================
 Copyright (c) 2012-2014 Richard Otis

 Distributed under the Boost Software License, Version 1.0. (See accompanying
 file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
 =============================================================================*/

// Deep copy/rename (DCR) implementation for EnergyModel

#include "libgibbs/include/libgibbs_pch.hpp"
#include "libgibbs/include/utils/ast_container_rename.hpp"
#include "libgibbs/include/utils/ast_variable_rename.hpp"
#include "libgibbs/include/models.hpp"
#include "libtdb/include/logging.hpp"
#include <memory>

std::unique_ptr<EnergyModel> EnergyModel::clone_with_renamed_phase (
    const std::string &old_phase_name,
    const std::string &new_phase_name
) const
{
    BOOST_LOG_NAMED_SCOPE ( "EnergyModel::clone_with_renamed_phase" );
    logger opto_log ( journal::keywords::channel = "optimizer" );
    BOOST_LOG_SEV( opto_log, debug ) << "entered";
    auto copymodel = std::unique_ptr<EnergyModel> ( new EnergyModel ( *this ) );
    BOOST_LOG_SEV( opto_log, debug ) << "created EnergyModel copy tethered to unique_ptr";
    // Deep copy and rename the ast_symbol_table
    ASTSymbolMap new_map ( ast_copy_with_renamed_phase ( ast_symbol_table, old_phase_name, new_phase_name ) );
    BOOST_LOG_SEV( opto_log, debug ) << "DCR ASTSymbolMap";
    // Perform a deep rename on model_ast
    ast_variable_rename ( copymodel->model_ast, old_phase_name, new_phase_name );
    BOOST_LOG_SEV( opto_log, debug ) << "DCR model_ast("
        << old_phase_name << " -> " << new_phase_name << ") = " << copymodel->model_ast;
    copymodel->ast_symbol_table = std::move ( new_map );
    BOOST_LOG_SEV( opto_log, debug ) << "returning";
    return std::move ( copymodel );
}
<|endoftext|>