<commit_before>/*
 This file is part of the Marble Virtual Globe.

 This program is free software licensed under the GNU LGPL. You can
 find a copy of this license in LICENSE.txt in the top directory of
 the source code.

 Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
*/

#include "VectorTileMapper.h"

#include <QtCore/QRunnable>

#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "GeoPainter.h"
#include "GeoDataPolygon.h"
#include "Quaternion.h"
#include "ScanlineTextureMapperContext.h"
#include "StackedTileLoader.h"
#include "StackedTile.h"
#include "TextureColorizer.h"

#include "ViewportParams.h"
#include "MathHelper.h"

using namespace Marble;

VectorTileMapper::~VectorTileMapper()
{
}

VectorTileMapper::VectorTileMapper( StackedTileLoader *tileLoader )
    : TextureMapperInterface()
    , m_tileLoader( tileLoader )
    , m_threadPool()
{
}

void VectorTileMapper::mapTexture( GeoPainter *painter,
                                   const ViewportParams *viewport,
                                   int tileZoomLevel,
                                   const QRect &dirtyRect,
                                   TextureColorizer *texColorizer )
{
    Q_UNUSED( painter );
    Q_UNUSED( texColorizer );
    Q_UNUSED( dirtyRect );

    const unsigned int maxTileX = 2 << tileZoomLevel;
    const unsigned int maxTileY = 2 << tileZoomLevel;

    /** LOGIC FOR DOWNLOADING ALL THE TILES THAT ARE INSIDE THE SCREEN AT THE CURRENT ZOOM LEVEL **/

    // New tiles X and Y for moved screen coordinates
    // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Subtiles
    // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#C.2FC.2B.2B
    // Sometimes the formula returns wrong huge values, x and y have to be between 0 and 2^ZoomLevel
    unsigned int minX = qMin<unsigned int>( maxTileX,
                              qMax<unsigned int>( lon2tileX( viewport->viewLatLonAltBox().west(GeoDataCoordinates::Degree), maxTileX ),
                                    0 ) );

    unsigned int minY = qMin<unsigned int>( maxTileY,
                              qMax<unsigned int>( lat2tileY( viewport->viewLatLonAltBox().north(GeoDataCoordinates::Degree), maxTileY ),
                                    0 ) );

    unsigned int maxX = qMax<unsigned int>( 0,
                              qMin<unsigned int>( lon2tileX( viewport->viewLatLonAltBox().east(GeoDataCoordinates::Degree), maxTileX ),
                                    maxTileX ) );

    unsigned int maxY = qMax<unsigned int>( 0,
                              qMin<unsigned int>( lat2tileY( viewport->viewLatLonAltBox().south(GeoDataCoordinates::Degree), maxTileY ),
                                    maxTileY ) );

    bool left  = minX < maxTileX;
    bool right = maxX > 0;
    bool up    = minY < maxTileY;
    bool down  = maxY > 0 ;

    // Download tiles and send them to VectorTileLayer
    // When changing zoom, download everything inside the screen
    if ( left && right && up && down )

                mapTexture( viewport, tileZoomLevel, minX, minY, maxX, maxY );

    // When only moving screen, just download the new tiles
    else if ( left || right || up || down ){

        if ( left )
            mapTexture( viewport, tileZoomLevel, minX, maxTileY, maxTileX, 0 );
        if ( right )
            mapTexture( viewport, tileZoomLevel, 0, maxTileY, maxX, 0 );
        if ( up )
            mapTexture( viewport, tileZoomLevel, maxTileX, minY, 0, maxTileY );
        if ( down )
            mapTexture( viewport, tileZoomLevel, maxTileX, 0, 0, maxY );

        // During testing discovered that this code above does not request the "corner" tiles

    }
}

void VectorTileMapper::mapTexture( const ViewportParams *viewport, int tileZoomLevel,
                                   unsigned int minTileX, unsigned int minTileY, unsigned int maxTileX, unsigned int maxTileY )
{
    // Reset backend
    m_tileLoader->resetTilehash();

    // Create render thread
    RenderJob *const job = new RenderJob( m_tileLoader, tileZoomLevel, viewport,
                                          minTileX, minTileY, maxTileX, maxTileY);

    // Connect the parser thread to the VectorTileMapper for recieving tiles
    connect( job, SIGNAL(tileCompleted(TileId,GeoDataDocument*,QString)),
             this, SLOT(updateTile(TileId,GeoDataDocument*,QString)) );

    // Start thread
    m_threadPool.start( job );

    // Aparently there is not needed to wait for it to finish but
    // waiting prevents having crashes with TileLoader's cache
    // when cleaning tile hash (duplicated node errors and double free errors)
    m_threadPool.waitForDone();

    m_tileLoader->cleanupTilehash();
}

void VectorTileMapper::updateTile(TileId const & tileId, GeoDataDocument * document, QString const &format )
{
    // We received a vector tile, send it to the VectorTileLayer
    emit tileCompleted( tileId, document, format );
}

unsigned int VectorTileMapper::lon2tileX( qreal lon, unsigned int maxTileX )
{
    return (unsigned int)floor((lon + 180.0) / 360.0 * maxTileX);
}

unsigned int VectorTileMapper::lat2tileY( qreal lat, unsigned int maxTileY )
{
    return (unsigned int)floor((1.0 - log( tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * maxTileY);
}

VectorTileMapper::RenderJob::RenderJob( StackedTileLoader *tileLoader, int tileLevel, const ViewportParams *viewport,
                                        unsigned int minTileX, unsigned int minTileY, unsigned int maxTileX, unsigned int maxTileY )
    : m_tileLoader( tileLoader ),
      m_tileLevel( tileLevel ),
      m_viewport( viewport ),
      m_minTileX( minTileX ),
      m_minTileY( minTileY ),
      m_maxTileX( maxTileX ),
      m_maxTileY( maxTileY )

{
}

void VectorTileMapper::RenderJob::run()
{
    // Download all the tiles inside the given indexes
    for (unsigned int x = m_minTileX; x <= m_maxTileX; x++)
        for (unsigned int y = m_minTileY; y <= m_maxTileY; y++)
        {
           const TileId tileId = TileId( 0, m_tileLevel, x, y );
           const StackedTile * tile = m_tileLoader->loadTile( tileId );

           // When tile has vectorData send it to the VectorTileLayer for it to insert
           // it in the treeModel
           if ( tile->resultVectorData()->size() > 0 )
                emit tileCompleted( tileId, tile->resultVectorData(), "JS" );
        }
}

#include "VectorTileMapper.moc"
<commit_msg>respect level zero layout from .dgml file<commit_after>/*
 This file is part of the Marble Virtual Globe.

 This program is free software licensed under the GNU LGPL. You can
 find a copy of this license in LICENSE.txt in the top directory of
 the source code.

 Copyright 2012 Ander Pijoan <ander.pijoan@deusto.es>
*/

#include "VectorTileMapper.h"

#include <QtCore/QRunnable>

#include "MarbleGlobal.h"
#include "MarbleDebug.h"
#include "GeoPainter.h"
#include "GeoDataPolygon.h"
#include "Quaternion.h"
#include "ScanlineTextureMapperContext.h"
#include "StackedTileLoader.h"
#include "StackedTile.h"
#include "TileLoaderHelper.h"

#include "ViewportParams.h"
#include "MathHelper.h"

using namespace Marble;

VectorTileMapper::~VectorTileMapper()
{
}

VectorTileMapper::VectorTileMapper( StackedTileLoader *tileLoader )
    : TextureMapperInterface()
    , m_tileLoader( tileLoader )
    , m_threadPool()
{
}

void VectorTileMapper::mapTexture( GeoPainter *painter,
                                   const ViewportParams *viewport,
                                   int tileZoomLevel,
                                   const QRect &dirtyRect,
                                   TextureColorizer *texColorizer )
{
    Q_UNUSED( painter );
    Q_UNUSED( texColorizer );
    Q_UNUSED( dirtyRect );

    const unsigned int maxTileX = m_tileLoader->tileColumnCount( tileZoomLevel );
    const unsigned int maxTileY = m_tileLoader->tileRowCount( tileZoomLevel );

    /** LOGIC FOR DOWNLOADING ALL THE TILES THAT ARE INSIDE THE SCREEN AT THE CURRENT ZOOM LEVEL **/

    // New tiles X and Y for moved screen coordinates
    // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#Subtiles
    // More info: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames#C.2FC.2B.2B
    // Sometimes the formula returns wrong huge values, x and y have to be between 0 and 2^ZoomLevel
    unsigned int minX = qMin<unsigned int>( maxTileX,
                              qMax<unsigned int>( lon2tileX( viewport->viewLatLonAltBox().west(GeoDataCoordinates::Degree), maxTileX ),
                                    0 ) );

    unsigned int minY = qMin<unsigned int>( maxTileY,
                              qMax<unsigned int>( lat2tileY( viewport->viewLatLonAltBox().north(GeoDataCoordinates::Degree), maxTileY ),
                                    0 ) );

    unsigned int maxX = qMax<unsigned int>( 0,
                              qMin<unsigned int>( lon2tileX( viewport->viewLatLonAltBox().east(GeoDataCoordinates::Degree), maxTileX ),
                                    maxTileX ) );

    unsigned int maxY = qMax<unsigned int>( 0,
                              qMin<unsigned int>( lat2tileY( viewport->viewLatLonAltBox().south(GeoDataCoordinates::Degree), maxTileY ),
                                    maxTileY ) );

    bool left  = minX < maxTileX;
    bool right = maxX > 0;
    bool up    = minY < maxTileY;
    bool down  = maxY > 0 ;

    // Download tiles and send them to VectorTileLayer
    // When changing zoom, download everything inside the screen
    if ( left && right && up && down )

                mapTexture( viewport, tileZoomLevel, minX, minY, maxX, maxY );

    // When only moving screen, just download the new tiles
    else if ( left || right || up || down ){

        if ( left )
            mapTexture( viewport, tileZoomLevel, minX, maxTileY, maxTileX, 0 );
        if ( right )
            mapTexture( viewport, tileZoomLevel, 0, maxTileY, maxX, 0 );
        if ( up )
            mapTexture( viewport, tileZoomLevel, maxTileX, minY, 0, maxTileY );
        if ( down )
            mapTexture( viewport, tileZoomLevel, maxTileX, 0, 0, maxY );

        // During testing discovered that this code above does not request the "corner" tiles

    }
}

void VectorTileMapper::mapTexture( const ViewportParams *viewport, int tileZoomLevel,
                                   unsigned int minTileX, unsigned int minTileY, unsigned int maxTileX, unsigned int maxTileY )
{
    // Reset backend
    m_tileLoader->resetTilehash();

    // Create render thread
    RenderJob *const job = new RenderJob( m_tileLoader, tileZoomLevel, viewport,
                                          minTileX, minTileY, maxTileX, maxTileY);

    // Connect the parser thread to the VectorTileMapper for recieving tiles
    connect( job, SIGNAL(tileCompleted(TileId,GeoDataDocument*,QString)),
             this, SLOT(updateTile(TileId,GeoDataDocument*,QString)) );

    // Start thread
    m_threadPool.start( job );

    // Aparently there is not needed to wait for it to finish but
    // waiting prevents having crashes with TileLoader's cache
    // when cleaning tile hash (duplicated node errors and double free errors)
    m_threadPool.waitForDone();

    m_tileLoader->cleanupTilehash();
}

void VectorTileMapper::updateTile(TileId const & tileId, GeoDataDocument * document, QString const &format )
{
    // We received a vector tile, send it to the VectorTileLayer
    emit tileCompleted( tileId, document, format );
}

unsigned int VectorTileMapper::lon2tileX( qreal lon, unsigned int maxTileX )
{
    return (unsigned int)floor((lon + 180.0) / 360.0 * maxTileX);
}

unsigned int VectorTileMapper::lat2tileY( qreal lat, unsigned int maxTileY )
{
    return (unsigned int)floor((1.0 - log( tan(lat * M_PI/180.0) + 1.0 / cos(lat * M_PI/180.0)) / M_PI) / 2.0 * maxTileY);
}

VectorTileMapper::RenderJob::RenderJob( StackedTileLoader *tileLoader, int tileLevel, const ViewportParams *viewport,
                                        unsigned int minTileX, unsigned int minTileY, unsigned int maxTileX, unsigned int maxTileY )
    : m_tileLoader( tileLoader ),
      m_tileLevel( tileLevel ),
      m_viewport( viewport ),
      m_minTileX( minTileX ),
      m_minTileY( minTileY ),
      m_maxTileX( maxTileX ),
      m_maxTileY( maxTileY )

{
}

void VectorTileMapper::RenderJob::run()
{
    // Download all the tiles inside the given indexes
    for (unsigned int x = m_minTileX; x <= m_maxTileX; x++)
        for (unsigned int y = m_minTileY; y <= m_maxTileY; y++)
        {
           const TileId tileId = TileId( 0, m_tileLevel, x, y );
           const StackedTile * tile = m_tileLoader->loadTile( tileId );

           // When tile has vectorData send it to the VectorTileLayer for it to insert
           // it in the treeModel
           if ( tile->resultVectorData()->size() > 0 )
                emit tileCompleted( tileId, tile->resultVectorData(), "JS" );
        }
}

#include "VectorTileMapper.moc"
<|endoftext|>


<commit_before><commit_msg>specify 4.0 core profile usage. see: https://en.wikipedia.org/wiki/OpenGL_Shading_Language#Versions<commit_after><|endoftext|>


<commit_before>/// @brief provides CORDIC for ln function
/// @ref see C. Baumann, "A simple and fast look-up table method to compute the
/// exp(x) and ln(x) functions", 2004

#include "./../../fixed_point_lib/src/CORDIC/lut/lut.hpp"

#include <boost/foreach.hpp>
#include <boost/range/irange.hpp>

namespace std {
    template<typename T, size_t n, size_t f, class op, class up>
    typename core::fixed_point<T, n, f, op, up>::exp_type exp(core::fixed_point<T, n, f, op, up> const& val)
    {
        typedef core::fixed_point<T, n, f, op, up> fp;
        typedef core::get_<fp>::max_signed_type work_type;
        typedef core::cordic::lut<f, fp> lut;

        // reduces argument to interval [0.0, 1.0]
        int power(0);
        work_type arg(val * fp::CONST_LOG2E);
        while (arg >= fp(1.0)) {
            arg = arg - 1u;
            power++;
        }
        while (arg < fp(0.0)) {
            arg = arg + 1u;
            power--;
        }

        static lut const pow2_lut = lut::pow2();
        work_type result(1.0);
        BOOST_FOREACH(size_t i, boost::irange<size_t>(0, f, 1))
        {
            if (work_type(arg - work_type::wrap(T(1u) << (f - i - 1u))) >= work_type(0.0)) {
                arg = arg - work_type::wrap(T(1u) << (f- i -1u));

                result = work_type(result * pow2_lut[i]);
            }
        }

        //result = result * (work_type::wrap(T(1u) << (f + power)));
        if (power >= 0) {
            as_native(result) <<= power;
        }
        else {
            as_native(result) >>= (-power);
        }
        return fp::exp_type(result);
    }
}
<commit_msg>exp.inl: more precise range for CONST_LOG2E constant<commit_after>/// @brief provides CORDIC for ln function
/// @ref see C. Baumann, "A simple and fast look-up table method to compute the
/// exp(x) and ln(x) functions", 2004

#include "./../../fixed_point_lib/src/CORDIC/lut/lut.hpp"

#include <boost/foreach.hpp>
#include <boost/range/irange.hpp>

namespace std {
    template<typename T, size_t n, size_t f, class op, class up>
    typename core::fixed_point<T, n, f, op, up>::exp_type exp(core::fixed_point<T, n, f, op, up> const& val)
    {
        typedef core::fixed_point<T, n, f, op, up> fp;
        typedef core::get_<fp>::max_signed_type work_type;
        typedef core::cordic::lut<f, fp> lut;

        // reduces argument to interval [0.0, 1.0]
        int power(0);
        work_type arg(val * core::U_fixed_point<f+1u, f>::type::CONST_LOG2E);
        while (arg >= fp(1.0)) {
            arg = arg - 1u;
            power++;
        }
        while (arg < fp(0.0)) {
            arg = arg + 1u;
            power--;
        }

        static lut const pow2_lut = lut::pow2();
        work_type result(1.0);
        BOOST_FOREACH(size_t i, boost::irange<size_t>(0, f, 1))
        {
            if (work_type(arg - work_type::wrap(T(1u) << (f - i - 1u))) >= work_type(0.0)) {
                arg = arg - work_type::wrap(T(1u) << (f- i -1u));

                result = work_type(result * pow2_lut[i]);
            }
        }

        //result = result * (work_type::wrap(T(1u) << (f + power)));
        if (power >= 0) {
            as_native(result) <<= power;
        }
        else {
            as_native(result) >>= (-power);
        }
        return fp::exp_type(result);
    }
}
<|endoftext|>


<commit_before>#include "pic_utils.h"

#include <algorithm>
#include <assert.h>
#include <boost/filesystem.hpp>
#include <cuda_runtime_api.h>
#include <fstream>
#include <stdio.h>

#include "commandline_options.h"
#include "host_mem.h"
#include "simulation_state.h"

void checkForCudaError(const char *errorMsg)
{
   cudaError_t error = cudaGetLastError();
   if(error != cudaSuccess)
   {
      FILE *file;
      SimulationState &simState(SimulationState::getRef());
      fprintf(stderr,"ERROR on iteration %u: %s: %s\n",
         simState.iterationNum, errorMsg, cudaGetErrorString(error) );
      file = fopen(errorLogName.c_str(), "w");
      fprintf(file,"ERROR on iteration %u: %s\n", simState.iterationNum,
         cudaGetErrorString(error) );
      fclose(file);
      assert(error == cudaSuccess);
      exit(1);
   }
}

void checkForCudaErrorSync(const char *errorMsg)
{
   cudaThreadSynchronize();
   checkForCudaError(errorMsg);
}

void checkForCudaError(const char *errorMsg, cudaError_t error)
{
   if(error != cudaSuccess)
   {
      SimulationState &simState(SimulationState::getRef());
      fprintf(stderr,"ERROR on iteration %u: %s: %s\n", simState.iterationNum,
         errorMsg, cudaGetErrorString(error) );
      assert(error == cudaSuccess);
      exit(1);
   }
}

void errExit(const char *errorString)
{
   FILE *file;
   file = fopen(errorLogName.c_str(), "w");
   fprintf(stderr,"ERROR: %s\n", errorString);
   fprintf(file,"ERROR: %s\n", errorString);
   fclose(file);
   assert(false);
   exit(1);
}

void resizeDim3(dim3 &rhs, std::size_t x, std::size_t y, std::size_t z)
{
   rhs.x = static_cast<unsigned int>(x);
   rhs.y = static_cast<unsigned int>(y);
   rhs.z = static_cast<unsigned int>(z);
}

//*****************************************************************************
// Name: outinfo
// Purpose: Output info files that are used to periodically report
//          on the iteration number, simulation time, number of
//          electrons and the number of ions
// Parameters:
// ---------------------
// fname  - Filename to output
// idx_nm - Index to append to fname
// time   - TODO *** Find a better description ***
// need   - The number of electrons
// niid   - The number of ions
// first  - Flag which governs overwriting the info file
//*****************************************************************************
void outinfo(const std::string &fname,
             int idx_nm,
             float time,
             int need,
             int niid,
             bool first)
{
   char name[100];
   FILE *fp;
   sprintf(name,"%s/%s",outputPath.c_str(), fname.c_str(), idx_nm);
   if(!first)
   {
      fp = fopen(name, "a");
   }
   else
   {
      fp = fopen(name, "w");
   }
   if(fp==NULL)
   {
      printf("Cannot open '%s' file for writing\n",name);
      exit(1);
   }
   fprintf(fp,"%d\t%f\t%d\t%d\n",idx_nm,time,need,niid);
   fclose(fp);
}

void createOutputDir(const char * dir)
{
   if(!boost::filesystem::exists(dir))
   {
      std::cout << "Creating " << dir << std::endl;
      boost::filesystem::create_directory(dir);
   }
}

bool fileExists(const std::string &fileName)
{
  if(boost::filesystem::exists(fileName))
  {
     return true;
  }
  else
  {
     return false;
  }
}

bool verifyParticles(const float2 partLoc[], std::size_t size,
                     unsigned int nx1, unsigned int ny1,
                     const char* whatAmI)
{
   bool ret = true;
   std::size_t numErrors = 0;
   std::size_t printLimit = 20;
   for(std::size_t i = 0; i < size; i++)
   {
      if(partLoc[i].y < DY || partLoc[i].y > DY * NY1 - 1)
      {
         if(numErrors < printLimit)
         {
            std::cout << "ERROR: " << whatAmI << " found at x=" << partLoc[i].x
               << " y=" << partLoc[i].y << std::endl;
         }
         numErrors++;
      }
   }

   return ret;
}

void loadPrevSimState(const std::string &loadDir,
                      DevMem<float2> &dev_eleHotLoc, DevMem<float3> &dev_eleHotVel,
                      DevMem<float2> &dev_eleColdLoc, DevMem<float3> &dev_eleColdVel,
                      DevMem<float2> &dev_ionHotLoc, DevMem<float3> &dev_ionHotVel,
                      DevMem<float2> &dev_ionColdLoc, DevMem<float3> &dev_ionColdVel,
                      unsigned int &numEleHot, unsigned int &numEleCold,
                      unsigned int &numIonHot, unsigned int &numIonCold,
                      const unsigned int allocIncrement)
{
   const unsigned int FPPF = 6; // Floats Per Particle File
   const unsigned int FPPM = 5; // Floats Per Particle Memory

   SimulationState &simState(SimulationState::getRef());
   CommandlineOptions &options(CommandlineOptions::getRef());

   const std::size_t strSize = 40;
   char infoName[strSize];
   std::string eleName;
   std::string ionName;

   // Generate file names
   sprintf(infoName, "info");
   boost::filesystem::path infoPath(loadDir + "/" + infoName);
   boost::filesystem::path elePath;
   boost::filesystem::path ionPath;

   if(!boost::filesystem::exists(infoPath))
   {
      std::cerr << "ERROR: " << infoPath.string() << " does not exist!" << std::endl;
      exit(1);
   }

   // Now I need to find the right files to load
   std::ifstream infoF(infoPath.string().c_str(), std::ios::binary);
   infoF.seekg(-1, std::ios_base::end);
   std::stringstream infoStream;
   std::string infoLine;
   bool foundFiles = false;
   unsigned int numEle;
   unsigned int numIon;
   unsigned int index;

   infoLine = getPrevLine(infoF);
   infoStream << infoLine;
   while(!foundFiles && infoLine != "")
   {
      infoStream >> simState.iterationNum >> simState.simTime >> numEle >> numIon;
      index = simState.iterationNum;
      std::stringstream s;
      s << "ele_" << std::setw(D_LOG_IDX_WIDTH) << std::setfill('0') << index;
      eleName = s.str();
      s.str("");
      s << "ion_" << std::setw(D_LOG_IDX_WIDTH) << std::setfill('0') << index;
      ionName = s.str();
      elePath = boost::filesystem::path(loadDir) / eleName;
      ionPath = boost::filesystem::path(loadDir) / ionName;

      if(boost::filesystem::exists(elePath) &&
         boost::filesystem::exists(ionPath))
      {
         foundFiles = true;
      }
      infoLine.clear();
      infoLine = getPrevLine(infoF);
		infoStream.clear();
      infoStream << infoLine;
   }

   if(infoLine == "")
   {
      std::cerr << "ERROR: " << infoPath.string()
         << " is either empty or does not reference any ele or ion files that exist." << std::endl;
      exit(1);
   }

   std::cout << "Restarting run from index " << index << std::endl;

   std::ifstream infoFile(infoPath.string().c_str());

   infoFile.close();
   simState.iterationNum *= D_LF;

   numEleHot = 0;
   numEleCold = 0;
   numIonHot = 0;
   numIonCold = 0;

   std::ifstream eleFile(elePath.string().c_str(), std::ios::binary);
   eleFile.read(reinterpret_cast<char*>(&numEle), sizeof(unsigned int));
   eleFile.read(reinterpret_cast<char*>(&numEleHot), sizeof(unsigned int));
   eleFile.read(reinterpret_cast<char*>(&numEleCold), sizeof(unsigned int));

   if(numEleHot > dev_eleHotLoc.size())
   {
      dev_eleHotLoc.resize(numEleHot + allocIncrement);
      dev_eleHotVel.resize(numEleHot + allocIncrement);
   }
   HostMem<float2> h_eleHotLoc(dev_eleHotLoc.size());
   HostMem<float3> h_eleHotVel(dev_eleHotVel.size());

   if(numEleCold > dev_eleColdLoc.size())
   {
      dev_eleColdLoc.resize(numEleCold + allocIncrement);
      dev_eleColdVel.resize(numEleCold + allocIncrement);
   }
   HostMem<float2> h_eleColdLoc(dev_eleColdLoc.size());
   HostMem<float3> h_eleColdVel(dev_eleColdVel.size());

   for(unsigned int i = 0; i < numEleHot; i++)
   {
      eleFile.read(reinterpret_cast<char*>(&h_eleHotLoc[i]), sizeof(float2));
      eleFile.read(reinterpret_cast<char*>(&h_eleHotVel[i]), sizeof(float3));
   }
   for(unsigned int i = 0; i < numEleCold; i++)
   {
      eleFile.read(reinterpret_cast<char*>(&h_eleColdLoc[i]), sizeof(float2));
      eleFile.read(reinterpret_cast<char*>(&h_eleColdVel[i]), sizeof(float3));
   }
   eleFile.close();

   std::ifstream ionFile(ionPath.string().c_str(), std::ios::binary);
   ionFile.read(reinterpret_cast<char*>(&numIon), sizeof(unsigned int));
   ionFile.read(reinterpret_cast<char*>(&numIonHot), sizeof(unsigned int));
   ionFile.read(reinterpret_cast<char*>(&numIonCold), sizeof(unsigned int));

   if(numIonHot > dev_ionHotLoc.size())
   {
      dev_ionHotLoc.resize(numIonHot + allocIncrement);
      dev_ionHotVel.resize(numIonHot + allocIncrement);
   }
   HostMem<float2> h_ionHotLoc(dev_ionHotLoc.size());
   HostMem<float3> h_ionHotVel(dev_ionHotVel.size());

   if(numIonCold > dev_ionColdLoc.size())
   {
      dev_ionColdLoc.resize(numIonCold + allocIncrement);
      dev_ionColdVel.resize(numIonCold + allocIncrement);
   }
   HostMem<float2> h_ionColdLoc(dev_ionColdLoc.size());
   HostMem<float3> h_ionColdVel(dev_ionColdVel.size());

   for(unsigned int i = 0; i < numIonHot; i++)
   {
      ionFile.read(reinterpret_cast<char*>(&h_ionHotLoc[i]), sizeof(float2));
      ionFile.read(reinterpret_cast<char*>(&h_ionHotVel[i]), sizeof(float3));
   }
   for(unsigned int i = 0; i < numIonCold; i++)
   {
      ionFile.read(reinterpret_cast<char*>(&h_ionColdLoc[i]), sizeof(float2));
      ionFile.read(reinterpret_cast<char*>(&h_ionColdVel[i]), sizeof(float3));
   }
   ionFile.close();

#ifdef _DEBUG
   verifyParticles(&h_eleHotLoc[0], numEleHot, NX1, NY1, "Hot ele");
   verifyParticles(&h_eleColdLoc[0], numEleCold, NX1, NY1, "Cold ele");
   verifyParticles(&h_ionHotLoc[0], numIonHot, NX1, NY1, "Hot ion");
   verifyParticles(&h_ionColdLoc[0], numIonCold, NX1, NY1, "Cold ion");
#endif

   dev_eleHotLoc.copyArrayToDev(h_eleHotLoc);
   dev_eleHotVel.copyArrayToDev(h_eleHotVel);
   dev_eleColdLoc.copyArrayToDev(h_eleColdLoc);
   dev_eleColdVel.copyArrayToDev(h_eleColdVel);
   dev_ionHotLoc.copyArrayToDev(h_ionHotLoc);
   dev_ionHotVel.copyArrayToDev(h_ionHotVel);
   dev_ionColdLoc.copyArrayToDev(h_ionColdLoc);
   dev_ionColdVel.copyArrayToDev(h_ionColdVel);
}

void getLastLine(const std::string fileName, std::string &lastLine)
{
   char lastChar = 0;
   std::ifstream f(fileName.c_str());
   // Seek for the last character; for some reason -1 is always a newline
   f.seekg(-2, std::ios_base::end);

   lastLine = getPrevLine(f);

}

std::string getPrevLine(std::ifstream &f)
{
   std::string line;
   char lastChar = 0;

   // Loop until I'm done with the file or I've read the last non-emtpy line
   while(f && line == "")
   {
      // Check to see if I've found the start of a line
      lastChar = static_cast<char>(f.peek());
      if('\n' == lastChar || f.tellg() == static_cast<std::ifstream::streampos>(0))
      {
         std::istream::streampos pos = f.tellg();
         // If I'm back at the beginning of the file, lastChar won't be newline
         // In those cases, I don't want to skip the first character
         if('\n' == lastChar)
         {
            f.seekg(1, std::ios_base::cur);
         }

         std::getline(f, line);
         // Clear the EOF bit if its been set
         f.clear();
         // Reset the file cursor to its position before the getline
         f.seekg(pos);
      }
      // I haven't found the start of a non-emtpy line yet.
      // Read one more character back.
      f.seekg(-1, std::ios_base::cur);
   }

   return line;
}
<commit_msg>Printing error messages is now done with streams<commit_after>#include "pic_utils.h"

#include <algorithm>
#include <assert.h>
#include <boost/filesystem.hpp>
#include <cuda_runtime_api.h>
#include <fstream>
#include <sstream>
#include <stdio.h>

#include "commandline_options.h"
#include "host_mem.h"
#include "simulation_state.h"

void checkForCudaError(const char *errorMsg)
{
   cudaError_t error = cudaGetLastError();
   if(error != cudaSuccess)
   {
      std::stringstream s;
      std::ofstream file;
      SimulationState &simState(SimulationState::getRef());
      s << "ERROR on iteration " << simState.iterationNum
        << " " << errorMsg << " " << cudaGetErrorString(error);
      std::cerr << s.str() << std::endl;;
      file.open(errorLogName.c_str());
      file << s.str();
      assert(error == cudaSuccess);
      exit(1);
   }
}

void checkForCudaErrorSync(const char *errorMsg)
{
   cudaThreadSynchronize();
   checkForCudaError(errorMsg);
}

void checkForCudaError(const char *errorMsg, cudaError_t error)
{
   if(error != cudaSuccess)
   {
      SimulationState &simState(SimulationState::getRef());
      fprintf(stderr,"ERROR on iteration %u: %s: %s\n", simState.iterationNum,
         errorMsg, cudaGetErrorString(error) );
      assert(error == cudaSuccess);
      exit(1);
   }
}

void errExit(const char *errorString)
{
   FILE *file;
   file = fopen(errorLogName.c_str(), "w");
   fprintf(stderr,"ERROR: %s\n", errorString);
   fprintf(file,"ERROR: %s\n", errorString);
   fclose(file);
   assert(false);
   exit(1);
}

void resizeDim3(dim3 &rhs, std::size_t x, std::size_t y, std::size_t z)
{
   rhs.x = static_cast<unsigned int>(x);
   rhs.y = static_cast<unsigned int>(y);
   rhs.z = static_cast<unsigned int>(z);
}

//*****************************************************************************
// Name: outinfo
// Purpose: Output info files that are used to periodically report
//          on the iteration number, simulation time, number of
//          electrons and the number of ions
// Parameters:
// ---------------------
// fname  - Filename to output
// idx_nm - Index to append to fname
// time   - TODO *** Find a better description ***
// need   - The number of electrons
// niid   - The number of ions
// first  - Flag which governs overwriting the info file
//*****************************************************************************
void outinfo(const std::string &fname,
             int idx_nm,
             float time,
             int need,
             int niid,
             bool first)
{
   char name[100];
   FILE *fp;
   sprintf(name,"%s/%s",outputPath.c_str(), fname.c_str(), idx_nm);
   if(!first)
   {
      fp = fopen(name, "a");
   }
   else
   {
      fp = fopen(name, "w");
   }
   if(fp==NULL)
   {
      printf("Cannot open '%s' file for writing\n",name);
      exit(1);
   }
   fprintf(fp,"%d\t%f\t%d\t%d\n",idx_nm,time,need,niid);
   fclose(fp);
}

void createOutputDir(const char * dir)
{
   if(!boost::filesystem::exists(dir))
   {
      std::cout << "Creating " << dir << std::endl;
      boost::filesystem::create_directory(dir);
   }
}

bool fileExists(const std::string &fileName)
{
  if(boost::filesystem::exists(fileName))
  {
     return true;
  }
  else
  {
     return false;
  }
}

bool verifyParticles(const float2 partLoc[], std::size_t size,
                     unsigned int nx1, unsigned int ny1,
                     const char* whatAmI)
{
   bool ret = true;
   std::size_t numErrors = 0;
   std::size_t printLimit = 20;
   for(std::size_t i = 0; i < size; i++)
   {
      if(partLoc[i].y < DY || partLoc[i].y > DY * NY1 - 1)
      {
         if(numErrors < printLimit)
         {
            std::cout << "ERROR: " << whatAmI << " found at x=" << partLoc[i].x
               << " y=" << partLoc[i].y << std::endl;
         }
         numErrors++;
      }
   }

   return ret;
}

void loadPrevSimState(const std::string &loadDir,
                      DevMem<float2> &dev_eleHotLoc, DevMem<float3> &dev_eleHotVel,
                      DevMem<float2> &dev_eleColdLoc, DevMem<float3> &dev_eleColdVel,
                      DevMem<float2> &dev_ionHotLoc, DevMem<float3> &dev_ionHotVel,
                      DevMem<float2> &dev_ionColdLoc, DevMem<float3> &dev_ionColdVel,
                      unsigned int &numEleHot, unsigned int &numEleCold,
                      unsigned int &numIonHot, unsigned int &numIonCold,
                      const unsigned int allocIncrement)
{
   const unsigned int FPPF = 6; // Floats Per Particle File
   const unsigned int FPPM = 5; // Floats Per Particle Memory

   SimulationState &simState(SimulationState::getRef());
   CommandlineOptions &options(CommandlineOptions::getRef());

   const std::size_t strSize = 40;
   char infoName[strSize];
   std::string eleName;
   std::string ionName;

   // Generate file names
   sprintf(infoName, "info");
   boost::filesystem::path infoPath(loadDir + "/" + infoName);
   boost::filesystem::path elePath;
   boost::filesystem::path ionPath;

   if(!boost::filesystem::exists(infoPath))
   {
      std::cerr << "ERROR: " << infoPath.string() << " does not exist!" << std::endl;
      exit(1);
   }

   // Now I need to find the right files to load
   std::ifstream infoF(infoPath.string().c_str(), std::ios::binary);
   infoF.seekg(-1, std::ios_base::end);
   std::stringstream infoStream;
   std::string infoLine;
   bool foundFiles = false;
   unsigned int numEle;
   unsigned int numIon;
   unsigned int index;

   infoLine = getPrevLine(infoF);
   infoStream << infoLine;
   while(!foundFiles && infoLine != "")
   {
      infoStream >> simState.iterationNum >> simState.simTime >> numEle >> numIon;
      index = simState.iterationNum;
      std::stringstream s;
      s << "ele_" << std::setw(D_LOG_IDX_WIDTH) << std::setfill('0') << index;
      eleName = s.str();
      s.str("");
      s << "ion_" << std::setw(D_LOG_IDX_WIDTH) << std::setfill('0') << index;
      ionName = s.str();
      elePath = boost::filesystem::path(loadDir) / eleName;
      ionPath = boost::filesystem::path(loadDir) / ionName;

      if(boost::filesystem::exists(elePath) &&
         boost::filesystem::exists(ionPath))
      {
         foundFiles = true;
      }
      infoLine.clear();
      infoLine = getPrevLine(infoF);
		infoStream.clear();
      infoStream << infoLine;
   }

   if(infoLine == "")
   {
      std::cerr << "ERROR: " << infoPath.string()
         << " is either empty or does not reference any ele or ion files that exist." << std::endl;
      exit(1);
   }

   std::cout << "Restarting run from index " << index << std::endl;

   std::ifstream infoFile(infoPath.string().c_str());

   infoFile.close();
   simState.iterationNum *= D_LF;

   numEleHot = 0;
   numEleCold = 0;
   numIonHot = 0;
   numIonCold = 0;

   std::ifstream eleFile(elePath.string().c_str(), std::ios::binary);
   eleFile.read(reinterpret_cast<char*>(&numEle), sizeof(unsigned int));
   eleFile.read(reinterpret_cast<char*>(&numEleHot), sizeof(unsigned int));
   eleFile.read(reinterpret_cast<char*>(&numEleCold), sizeof(unsigned int));

   if(numEleHot > dev_eleHotLoc.size())
   {
      dev_eleHotLoc.resize(numEleHot + allocIncrement);
      dev_eleHotVel.resize(numEleHot + allocIncrement);
   }
   HostMem<float2> h_eleHotLoc(dev_eleHotLoc.size());
   HostMem<float3> h_eleHotVel(dev_eleHotVel.size());

   if(numEleCold > dev_eleColdLoc.size())
   {
      dev_eleColdLoc.resize(numEleCold + allocIncrement);
      dev_eleColdVel.resize(numEleCold + allocIncrement);
   }
   HostMem<float2> h_eleColdLoc(dev_eleColdLoc.size());
   HostMem<float3> h_eleColdVel(dev_eleColdVel.size());

   for(unsigned int i = 0; i < numEleHot; i++)
   {
      eleFile.read(reinterpret_cast<char*>(&h_eleHotLoc[i]), sizeof(float2));
      eleFile.read(reinterpret_cast<char*>(&h_eleHotVel[i]), sizeof(float3));
   }
   for(unsigned int i = 0; i < numEleCold; i++)
   {
      eleFile.read(reinterpret_cast<char*>(&h_eleColdLoc[i]), sizeof(float2));
      eleFile.read(reinterpret_cast<char*>(&h_eleColdVel[i]), sizeof(float3));
   }
   eleFile.close();

   std::ifstream ionFile(ionPath.string().c_str(), std::ios::binary);
   ionFile.read(reinterpret_cast<char*>(&numIon), sizeof(unsigned int));
   ionFile.read(reinterpret_cast<char*>(&numIonHot), sizeof(unsigned int));
   ionFile.read(reinterpret_cast<char*>(&numIonCold), sizeof(unsigned int));

   if(numIonHot > dev_ionHotLoc.size())
   {
      dev_ionHotLoc.resize(numIonHot + allocIncrement);
      dev_ionHotVel.resize(numIonHot + allocIncrement);
   }
   HostMem<float2> h_ionHotLoc(dev_ionHotLoc.size());
   HostMem<float3> h_ionHotVel(dev_ionHotVel.size());

   if(numIonCold > dev_ionColdLoc.size())
   {
      dev_ionColdLoc.resize(numIonCold + allocIncrement);
      dev_ionColdVel.resize(numIonCold + allocIncrement);
   }
   HostMem<float2> h_ionColdLoc(dev_ionColdLoc.size());
   HostMem<float3> h_ionColdVel(dev_ionColdVel.size());

   for(unsigned int i = 0; i < numIonHot; i++)
   {
      ionFile.read(reinterpret_cast<char*>(&h_ionHotLoc[i]), sizeof(float2));
      ionFile.read(reinterpret_cast<char*>(&h_ionHotVel[i]), sizeof(float3));
   }
   for(unsigned int i = 0; i < numIonCold; i++)
   {
      ionFile.read(reinterpret_cast<char*>(&h_ionColdLoc[i]), sizeof(float2));
      ionFile.read(reinterpret_cast<char*>(&h_ionColdVel[i]), sizeof(float3));
   }
   ionFile.close();

#ifdef _DEBUG
   verifyParticles(&h_eleHotLoc[0], numEleHot, NX1, NY1, "Hot ele");
   verifyParticles(&h_eleColdLoc[0], numEleCold, NX1, NY1, "Cold ele");
   verifyParticles(&h_ionHotLoc[0], numIonHot, NX1, NY1, "Hot ion");
   verifyParticles(&h_ionColdLoc[0], numIonCold, NX1, NY1, "Cold ion");
#endif

   dev_eleHotLoc.copyArrayToDev(h_eleHotLoc);
   dev_eleHotVel.copyArrayToDev(h_eleHotVel);
   dev_eleColdLoc.copyArrayToDev(h_eleColdLoc);
   dev_eleColdVel.copyArrayToDev(h_eleColdVel);
   dev_ionHotLoc.copyArrayToDev(h_ionHotLoc);
   dev_ionHotVel.copyArrayToDev(h_ionHotVel);
   dev_ionColdLoc.copyArrayToDev(h_ionColdLoc);
   dev_ionColdVel.copyArrayToDev(h_ionColdVel);
}

void getLastLine(const std::string fileName, std::string &lastLine)
{
   char lastChar = 0;
   std::ifstream f(fileName.c_str());
   // Seek for the last character; for some reason -1 is always a newline
   f.seekg(-2, std::ios_base::end);

   lastLine = getPrevLine(f);

}

std::string getPrevLine(std::ifstream &f)
{
   std::string line;
   char lastChar = 0;

   // Loop until I'm done with the file or I've read the last non-emtpy line
   while(f && line == "")
   {
      // Check to see if I've found the start of a line
      lastChar = static_cast<char>(f.peek());
      if('\n' == lastChar || f.tellg() == static_cast<std::ifstream::streampos>(0))
      {
         std::istream::streampos pos = f.tellg();
         // If I'm back at the beginning of the file, lastChar won't be newline
         // In those cases, I don't want to skip the first character
         if('\n' == lastChar)
         {
            f.seekg(1, std::ios_base::cur);
         }

         std::getline(f, line);
         // Clear the EOF bit if its been set
         f.clear();
         // Reset the file cursor to its position before the getline
         f.seekg(pos);
      }
      // I haven't found the start of a non-emtpy line yet.
      // Read one more character back.
      f.seekg(-1, std::ios_base::cur);
   }

   return line;
}
<|endoftext|>


<commit_before>#include "clientwindow.h"
#include "ui_clientwindow.h"
#include "ServerConnection.h"
#include "Character.h"
#include <QStringListModel>
#include <QAbstractItemModel>

ClientWindow::ClientWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::ClientWindow)
{
  ui->setupUi(this);
}

ClientWindow::~ClientWindow()
{
  delete ui;
}

void ClientWindow::set_serverconnection(ServerConnection* new_connection) {
  connection = new_connection;
}

ServerConnection*ClientWindow::get_serverconnection()
{
  return connection;
}

void ClientWindow::refresh_fields() {
  Character* character = connection->get_controlledChar();
  QStringList strList{};

  ui->name_label->setText(character->get_name());

  ui->attr_tableWidget->setRowCount(character->get_attributes().size());
  for (int i{0}; i< character->get_attributes().size(); ++i) {
    ui->attr_tableWidget->setItem(i,0,new QTableWidgetItem(character->get_attributes().keys().at(i)));
    ui->attr_tableWidget->setItem(i,1,new QTableWidgetItem(QString::number(character->get_attributes().values().at(i))));
  }
  ui->attr_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

}
<commit_msg>Fixed client bug when connecting<commit_after>#include "clientwindow.h"
#include "ui_clientwindow.h"
#include "ServerConnection.h"
#include "Character.h"
#include <QStringListModel>
#include <QAbstractItemModel>

ClientWindow::ClientWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::ClientWindow)
{
  ui->setupUi(this);
}

ClientWindow::~ClientWindow()
{
  delete ui;
}

void ClientWindow::set_serverconnection(ServerConnection* new_connection) {
  connection = new_connection;
  connection->set_clientwindow(this);
}

ServerConnection*ClientWindow::get_serverconnection()
{
  return connection;
}

void ClientWindow::refresh_fields() {
  Character* character = connection->get_controlledChar();
  QStringList strList{};

  ui->name_label->setText(character->get_name());

  ui->attr_tableWidget->setRowCount(character->get_attributes().size());
  for (int i{0}; i< character->get_attributes().size(); ++i) {
    ui->attr_tableWidget->setItem(i,0,new QTableWidgetItem(character->get_attributes().keys().at(i)));
    ui->attr_tableWidget->setItem(i,1,new QTableWidgetItem(QString::number(character->get_attributes().values().at(i))));
  }
  ui->attr_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);

}
<|endoftext|>


<commit_before>//  (C) Copyright Gennadiy Rozental 2005-2014.
//  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)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Provides core implementation for Unit Test Framework.
/// Extensions can be provided in separate files
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER

// Boost.Test
#include <boost/detail/workaround.hpp>

#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>

#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/traverse.hpp>
#include <boost/test/tree/auto_registration.hpp>
#include <boost/test/tree/global_fixture.hpp>

#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>

#include <boost/test/unit_test_parameters.hpp>

// Boost
#include <boost/timer.hpp>

// STL
#include <algorithm>
#include <vector>

#include <boost/test/detail/suppress_warnings.hpp>

#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450)
    using std::rand; // rand is in std and random_shuffle is in _STL
#endif

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

test_unit::test_unit( const_string name, const_string file_name, std::size_t line_num, test_unit_type t )
: p_type( t )
, p_type_name( t == TUT_CASE ? "case" : "suite" )
, p_file_name( file_name )
, p_line_num( line_num )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( name.begin(), name.size() ) )
, p_timeout( -1 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_dependency_rank(0)
{
}

//____________________________________________________________________________//

test_unit::test_unit( const_string module_name )
: p_type( TUT_SUITE )
, p_type_name( "module" )
, p_line_num( 0 )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( module_name.begin(), module_name.size() ) )
, p_timeout( -1 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_dependency_rank(0)
{
}

//____________________________________________________________________________//

test_unit::~test_unit()
{
    framework::deregister_test_unit( this );
}

//____________________________________________________________________________//

void
test_unit::depends_on( test_unit* tu )
{
    BOOST_TEST_SETUP_ASSERT( p_id != framework::master_test_suite().p_id, "Can't add dependency to the master test suite" );

    p_dependencies.value.push_back( tu->p_id );
}

//____________________________________________________________________________//

void
test_unit::add_precondition( precondition_t const& pc )
{
    p_preconditions.value.push_back( pc );
}

//____________________________________________________________________________//

test_tools::assertion_result
test_unit::check_preconditions() const
{
    BOOST_TEST_FOREACH( test_unit_id, dep_id, p_dependencies.get() ) {
        test_unit const& dep = framework::get( dep_id, TUT_ANY );

        if( !dep.is_enabled() ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" is disabled";
            return res;
        }

        test_results const& test_rslt = unit_test::results_collector.results( dep_id );
        if( !test_rslt.passed() ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
            return res;
        }

        if( test_rslt.p_test_cases_skipped > 0 ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has skipped test cases";
            return res;
        }
    }

    BOOST_TEST_FOREACH( precondition_t, precondition, p_preconditions.get() ) {
        test_tools::assertion_result res = precondition( p_id );
        if( !res )
            return res;
    }

    return true;
}

//____________________________________________________________________________//

void
test_unit::increase_exp_fail( unsigned num )
{
    p_expected_failures.value += num;

    if( p_parent_id != INV_TEST_UNIT_ID )
        framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
}

//____________________________________________________________________________//

std::string
test_unit::full_name() const
{
    if( p_parent_id == INV_TEST_UNIT_ID || p_parent_id == framework::master_test_suite().p_id )
        return p_name;

    std::string res = framework::get<test_suite>( p_parent_id ).full_name();
    res.append("/");

    res.append( p_name );

    return res;
}

//____________________________________________________________________________//

void
test_unit::add_label( const_string l )
{
    p_labels.value.push_back( std::string() + l );
}

//____________________________________________________________________________//

bool
test_unit::has_label( const_string l ) const
{
    return std::find( p_labels->begin(), p_labels->end(), l ) != p_labels->end();
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

test_case::test_case( const_string name, boost::function<void ()> const& test_func )
: test_unit( name, "", 0, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

test_case::test_case( const_string name, const_string file_name, std::size_t line_num, boost::function<void ()> const& test_func )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

//____________________________________________________________________________//

test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

test_suite::test_suite( const_string module_name )
: test_unit( module_name )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit* tu, counter_t expected_failures, int timeout )
{
    if( timeout > 0 )
        tu->p_timeout.value = timeout;

    m_members.push_back( tu->p_id );
    tu->p_parent_id.value = p_id;

    if( tu->p_expected_failures != 0 )
        increase_exp_fail( tu->p_expected_failures );

    if( expected_failures )
        tu->increase_exp_fail( expected_failures );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit_generator const& gen, int timeout )
{
    test_unit* tu;
    while(tu = gen.next())
        add( tu, 0, timeout );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
{
    test_unit* tu;
    while(tu = gen.next()) {
        decorators.store_in( *tu );
        add( tu, 0 );
    }

    decorators.reset();
}

//____________________________________________________________________________//

void
test_suite::remove( test_unit_id id )
{
    test_unit_id_list::iterator it = std::find( m_members.begin(), m_members.end(), id );

    if( it != m_members.end() )
        m_members.erase( it );
}

//____________________________________________________________________________//

test_unit_id
test_suite::get( const_string tu_name ) const
{
    BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
        if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
            return id;
    }

    return INV_TEST_UNIT_ID;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

master_test_suite_t::master_test_suite_t()
: test_suite( "Master Test Suite" )
, argc( 0 )
, argv( 0 )
{
    p_default_status.value = RS_ENABLED;
}

// ************************************************************************** //
// **************               traverse_test_tree             ************** //
// ************************************************************************** //

void
traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
{
    if( tc.is_enabled() || ignore_status )
        V.visit( tc );
}

//____________________________________________________________________________//

void
traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
{
    // skip disabled test suite unless we asked to ignore this condition
    if( !ignore_status && !suite.is_enabled() )
        return;

    // Invoke test_suite_start callback
    if( !V.test_suite_start( suite ) )
        return;

    // Recurse into children
    unsigned total_members = suite.m_members.size();
    for( unsigned i=0; i < total_members; ) {
        // this statement can remove the test unit from this list
        traverse_test_tree( suite.m_members[i], V, ignore_status );
        if( total_members > suite.m_members.size() )
            total_members = suite.m_members.size();
        else
            ++i;
    }

    // Invoke test_suite_finish callback
    V.test_suite_finish( suite );
}

//____________________________________________________________________________//

void
traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
{
    if( ut_detail::test_id_2_unit_type( id ) == TUT_CASE )
        traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
    else
        traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace ut_detail {

std::string
normalize_test_case_name( const_string name )
{
    return ( name[0] == '&'
                ? std::string( name.begin()+1, name.size()-1 )
                : std::string( name.begin(), name.size() ) );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************           auto_test_unit_registrar           ************** //
// ************************************************************************** //

auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
{
    framework::current_auto_test_suite().add( tc, exp_fail );

    decorators.store_in( *tc );
    decorators.reset();
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
{
    test_unit_id id = framework::current_auto_test_suite().get( ts_name );

    test_suite* ts;

    if( id != INV_TEST_UNIT_ID ) {
        ts = &framework::get<test_suite>( id );
        BOOST_ASSERT( ts->p_parent_id == framework::current_auto_test_suite().p_id );
    }
    else {
        ts = new test_suite( ts_name, ts_file, ts_line );
        framework::current_auto_test_suite().add( ts );
    }

    decorators.store_in( *ts );
    decorators.reset();

    framework::current_auto_test_suite( ts );
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
{
    framework::current_auto_test_suite().add( tc_gen, decorators );
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( int )
{
    framework::current_auto_test_suite( 0, false );
}

//____________________________________________________________________________//

} // namespace ut_detail

// ************************************************************************** //
// **************                global_fixture                ************** //
// ************************************************************************** //

global_fixture::global_fixture()
{
    framework::register_observer( *this );
}

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
<commit_msg>annoying warnings<commit_after>//  (C) Copyright Gennadiy Rozental 2005-2014.
//  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)

//  See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Provides core implementation for Unit Test Framework.
/// Extensions can be provided in separate files
// ***************************************************************************

#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER

// Boost.Test
#include <boost/detail/workaround.hpp>

#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>

#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/traverse.hpp>
#include <boost/test/tree/auto_registration.hpp>
#include <boost/test/tree/global_fixture.hpp>

#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>

#include <boost/test/unit_test_parameters.hpp>

// Boost
#include <boost/timer.hpp>

// STL
#include <algorithm>
#include <vector>

#include <boost/test/detail/suppress_warnings.hpp>

#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450)
    using std::rand; // rand is in std and random_shuffle is in _STL
#endif

//____________________________________________________________________________//

namespace boost {
namespace unit_test {

// ************************************************************************** //
// **************                   test_unit                  ************** //
// ************************************************************************** //

test_unit::test_unit( const_string name, const_string file_name, std::size_t line_num, test_unit_type t )
: p_type( t )
, p_type_name( t == TUT_CASE ? "case" : "suite" )
, p_file_name( file_name )
, p_line_num( line_num )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( name.begin(), name.size() ) )
, p_timeout( -1 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_dependency_rank(0)
{
}

//____________________________________________________________________________//

test_unit::test_unit( const_string module_name )
: p_type( TUT_SUITE )
, p_type_name( "module" )
, p_line_num( 0 )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( module_name.begin(), module_name.size() ) )
, p_timeout( -1 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_dependency_rank(0)
{
}

//____________________________________________________________________________//

test_unit::~test_unit()
{
    framework::deregister_test_unit( this );
}

//____________________________________________________________________________//

void
test_unit::depends_on( test_unit* tu )
{
    BOOST_TEST_SETUP_ASSERT( p_id != framework::master_test_suite().p_id, "Can't add dependency to the master test suite" );

    p_dependencies.value.push_back( tu->p_id );
}

//____________________________________________________________________________//

void
test_unit::add_precondition( precondition_t const& pc )
{
    p_preconditions.value.push_back( pc );
}

//____________________________________________________________________________//

test_tools::assertion_result
test_unit::check_preconditions() const
{
    BOOST_TEST_FOREACH( test_unit_id, dep_id, p_dependencies.get() ) {
        test_unit const& dep = framework::get( dep_id, TUT_ANY );

        if( !dep.is_enabled() ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" is disabled";
            return res;
        }

        test_results const& test_rslt = unit_test::results_collector.results( dep_id );
        if( !test_rslt.passed() ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
            return res;
        }

        if( test_rslt.p_test_cases_skipped > 0 ) {
            test_tools::assertion_result res(false);
            res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has skipped test cases";
            return res;
        }
    }

    BOOST_TEST_FOREACH( precondition_t, precondition, p_preconditions.get() ) {
        test_tools::assertion_result res = precondition( p_id );
        if( !res )
            return res;
    }

    return true;
}

//____________________________________________________________________________//

void
test_unit::increase_exp_fail( unsigned num )
{
    p_expected_failures.value += num;

    if( p_parent_id != INV_TEST_UNIT_ID )
        framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
}

//____________________________________________________________________________//

std::string
test_unit::full_name() const
{
    if( p_parent_id == INV_TEST_UNIT_ID || p_parent_id == framework::master_test_suite().p_id )
        return p_name;

    std::string res = framework::get<test_suite>( p_parent_id ).full_name();
    res.append("/");

    res.append( p_name );

    return res;
}

//____________________________________________________________________________//

void
test_unit::add_label( const_string l )
{
    p_labels.value.push_back( std::string() + l );
}

//____________________________________________________________________________//

bool
test_unit::has_label( const_string l ) const
{
    return std::find( p_labels->begin(), p_labels->end(), l ) != p_labels->end();
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                   test_case                  ************** //
// ************************************************************************** //

test_case::test_case( const_string name, boost::function<void ()> const& test_func )
: test_unit( name, "", 0, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

test_case::test_case( const_string name, const_string file_name, std::size_t line_num, boost::function<void ()> const& test_func )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************                  test_suite                  ************** //
// ************************************************************************** //

//____________________________________________________________________________//

test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

test_suite::test_suite( const_string module_name )
: test_unit( module_name )
{
    framework::register_test_unit( this );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit* tu, counter_t expected_failures, int timeout )
{
    if( timeout > 0 )
        tu->p_timeout.value = timeout;

    m_members.push_back( tu->p_id );
    tu->p_parent_id.value = p_id;

    if( tu->p_expected_failures != 0 )
        increase_exp_fail( tu->p_expected_failures );

    if( expected_failures )
        tu->increase_exp_fail( expected_failures );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit_generator const& gen, int timeout )
{
    test_unit* tu;
    while((tu = gen.next()) != 0)
        add( tu, 0, timeout );
}

//____________________________________________________________________________//

void
test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
{
    test_unit* tu;
    while((tu = gen.next()) != 0) {
        decorators.store_in( *tu );
        add( tu, 0 );
    }

    decorators.reset();
}

//____________________________________________________________________________//

void
test_suite::remove( test_unit_id id )
{
    test_unit_id_list::iterator it = std::find( m_members.begin(), m_members.end(), id );

    if( it != m_members.end() )
        m_members.erase( it );
}

//____________________________________________________________________________//

test_unit_id
test_suite::get( const_string tu_name ) const
{
    BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
        if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
            return id;
    }

    return INV_TEST_UNIT_ID;
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************               master_test_suite              ************** //
// ************************************************************************** //

master_test_suite_t::master_test_suite_t()
: test_suite( "Master Test Suite" )
, argc( 0 )
, argv( 0 )
{
    p_default_status.value = RS_ENABLED;
}

// ************************************************************************** //
// **************               traverse_test_tree             ************** //
// ************************************************************************** //

void
traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
{
    if( tc.is_enabled() || ignore_status )
        V.visit( tc );
}

//____________________________________________________________________________//

void
traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
{
    // skip disabled test suite unless we asked to ignore this condition
    if( !ignore_status && !suite.is_enabled() )
        return;

    // Invoke test_suite_start callback
    if( !V.test_suite_start( suite ) )
        return;

    // Recurse into children
    unsigned total_members = suite.m_members.size();
    for( unsigned i=0; i < total_members; ) {
        // this statement can remove the test unit from this list
        traverse_test_tree( suite.m_members[i], V, ignore_status );
        if( total_members > suite.m_members.size() )
            total_members = suite.m_members.size();
        else
            ++i;
    }

    // Invoke test_suite_finish callback
    V.test_suite_finish( suite );
}

//____________________________________________________________________________//

void
traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
{
    if( ut_detail::test_id_2_unit_type( id ) == TUT_CASE )
        traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
    else
        traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************               object generators              ************** //
// ************************************************************************** //

namespace ut_detail {

std::string
normalize_test_case_name( const_string name )
{
    return ( name[0] == '&'
                ? std::string( name.begin()+1, name.size()-1 )
                : std::string( name.begin(), name.size() ) );
}

//____________________________________________________________________________//

// ************************************************************************** //
// **************           auto_test_unit_registrar           ************** //
// ************************************************************************** //

auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
{
    framework::current_auto_test_suite().add( tc, exp_fail );

    decorators.store_in( *tc );
    decorators.reset();
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
{
    test_unit_id id = framework::current_auto_test_suite().get( ts_name );

    test_suite* ts;

    if( id != INV_TEST_UNIT_ID ) {
        ts = &framework::get<test_suite>( id );
        BOOST_ASSERT( ts->p_parent_id == framework::current_auto_test_suite().p_id );
    }
    else {
        ts = new test_suite( ts_name, ts_file, ts_line );
        framework::current_auto_test_suite().add( ts );
    }

    decorators.store_in( *ts );
    decorators.reset();

    framework::current_auto_test_suite( ts );
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
{
    framework::current_auto_test_suite().add( tc_gen, decorators );
}

//____________________________________________________________________________//

auto_test_unit_registrar::auto_test_unit_registrar( int )
{
    framework::current_auto_test_suite( 0, false );
}

//____________________________________________________________________________//

} // namespace ut_detail

// ************************************************************************** //
// **************                global_fixture                ************** //
// ************************************************************************** //

global_fixture::global_fixture()
{
    framework::register_observer( *this );
}

//____________________________________________________________________________//

} // namespace unit_test
} // namespace boost

#include <boost/test/detail/enable_warnings.hpp>

#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
<|endoftext|>


<commit_before>/*
 * Copyright (C) 1999-2011 Insight Software Consortium
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Example usage:
./ProsailModel 30.0 10.0 0.0 0.015 0.009 1.2 2 50 1 70 0.2 30 0 0 Output/SailReflTest.txt
*/

//
// This example presents how to use PROSAIL (Prospect + Sail) model to generate
// viewing reflectance from leaf parameters, vegetation, and viewing parameters.
// Output can be used to simulate image for example.
//
// Let's look at the minimal code required to use this algorithm. First, the
// following headers must be included.

#include "otbSailModel.h"
#include "otbProspectModel.h"

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"

int main(int argc, char* argv[])
{
  if (argc < 16)
  {
    std::cerr << "Missing Parameters " << std::endl;
    return EXIT_FAILURE;
  }

  char* OutputName = argv[15];
  //  We now define leaf parameters, which characterize vegetation composition.

  typedef otb::LeafParameters LeafParametersType;

  //  Next the parameters variable is created by invoking the \code{New()}~method and
  //  assigning the result to a \doxygen{itk}{SmartPointer}.

  LeafParametersType::Pointer leafParams = LeafParametersType::New();

  //  Leaf characteristics is then set.
  //  Input parameters are :
  //  \begin{itemize}
  //  \item Chlorophyll concentration (Cab) in $\mu g/cm^2$.
  //  \item Carotenoid concentration (Car) in $\mu g/cm^2$.
  //  \item Brown pigment content (CBrown) in arbitrary unit.
  //  \item Water thickness EWT (Cw) in $cm$.
  //  \item Dry matter content LMA (Cm) in $g/cm^2$.
  //  \item Leaf structure parameter (N).
  //  \end{itemize}

  double Cab    = static_cast<double>(atof(argv[1]));
  double Car    = static_cast<double>(atof(argv[2]));
  double CBrown = static_cast<double>(atof(argv[3]));
  double Cw     = static_cast<double>(atof(argv[4]));
  double Cm     = static_cast<double>(atof(argv[5]));
  double N      = static_cast<double>(atof(argv[6]));

  leafParams->SetCab(Cab);
  leafParams->SetCar(Car);
  leafParams->SetCBrown(CBrown);
  leafParams->SetCw(Cw);
  leafParams->SetCm(Cm);
  leafParams->SetN(N);

  //  Leaf parameters are used as prospect input

  typedef otb::ProspectModel ProspectType;
  ProspectType::Pointer      prospect = ProspectType::New();

  prospect->SetInput(leafParams);

  //  Now we use SAIL model to generate transmitance and reflectance spectrum. SAIL model is created by invoking
  //  the \code{New()} method and
  //  assigning the result to a \doxygen{itk}{SmartPointer}.

  //  sail input parameters are :
  //  \begin{itemize}
  //  \item leaf area index (LAI).
  //  \item average leaf angle (Angle) in $\deg$.
  //  \item soil coefficient (PSoil).
  //  \item diffuse/direct radiation (Skyl).
  //  \item hot spot (HSpot).
  //  \item solar zenith angle (TTS) in $\deg$.
  //  \item observer zenith angle (TTO) in $\deg$.
  //  \item azimuth (PSI) in $\deg$.
  //  \end{itemize}

  double LAI   = static_cast<double>(atof(argv[7]));
  double Angle = static_cast<double>(atof(argv[8]));
  double PSoil = static_cast<double>(atof(argv[9]));
  double Skyl  = static_cast<double>(atof(argv[10]));
  double HSpot = static_cast<double>(atof(argv[11]));
  double TTS   = static_cast<double>(atof(argv[12]));
  double TTO   = static_cast<double>(atof(argv[13]));
  double PSI   = static_cast<double>(atof(argv[14]));

  typedef otb::SailModel SailType;

  SailType::Pointer sail = SailType::New();

  sail->SetLAI(LAI);
  sail->SetAngl(Angle);
  sail->SetPSoil(PSoil);
  sail->SetSkyl(Skyl);
  sail->SetHSpot(HSpot);
  sail->SetTTS(TTS);
  sail->SetTTO(TTO);
  sail->SetPSI(PSI);

  //  Reflectance and Transmittance  are set with prospect output.

  sail->SetReflectance(prospect->GetReflectance());
  sail->SetTransmittance(prospect->GetTransmittance());

  //  The invocation of the \code{Update()} method triggers the
  //  execution of the pipeline.

  sail->Update();

  //  \emph{GetViewingReflectance} method provides viewing reflectance vector (size $Nx2$, where $N$ is the number of sampled wavelength values, columns
  //  corresponds respectively to wavelength and viewing reflectance) by calling \emph{GetResponse}. \emph{GetHemisphericalReflectance} method provides
  //  hemispherical reflectance vector (size $Nx2$, where $N$ is the number ofsampled wavelength values, columns corresponds to wavelength and hemispherical
  //  reflectance) by calling \emph{GetResponse}.
  //
  // Note that PROSAIL simulation are done for 2100 samples starting from 400nm up to 2500nm

  for (unsigned int i = 0; i < sail->GetViewingReflectance()->Size(); ++i)
  {
    std::cout << "wavelength  : ";
    std::cout << sail->GetViewingReflectance()->GetResponse()[i].first;
    std::cout << ". Viewing reflectance ";
    std::cout << sail->GetViewingReflectance()->GetResponse()[i].second;
    std::cout << ". Hemispherical reflectance ";
    std::cout << sail->GetHemisphericalReflectance()->GetResponse()[i].second;
    std::cout << std::endl;
  }

  std::ofstream outputFile(OutputName, std::ios::out);
  for (unsigned int i = 0; i < sail->GetHemisphericalReflectance()->Size(); ++i)
  {
    outputFile << sail->GetViewingReflectance()->GetResponse()[i].second << " ";
    outputFile << sail->GetHemisphericalReflectance()->GetResponse()[i].second << std::endl;
  }

  //  here you can found example parameters :
  //  \begin{itemize}
  //  \item Cab 30.0
  //  \item Car 10.0
  //  \item CBrown 0.0
  //  \item Cw 0.015
  //  \item Cm 0.009
  //  \item N 1.2
  //  \item LAI 2
  //  \item Angle 50
  //  \item PSoil 1
  //  \item Skyl 70
  //  \item HSpot 0.2
  //  \item TTS 30
  //  \item TTO 0
  //  \item PSI 0
  //  \end{itemize}
  //
  //  More information and data about leaf properties can be found at \emph{St\'{e}phane Jacquemoud}
  //  \href{http://teledetection.ipgp.jussieu.fr/opticleaf/}{OPTICLEAF} website.

  return EXIT_SUCCESS;
}
<commit_msg>TEST: less verbose Prosail test<commit_after>/*
 * Copyright (C) 1999-2011 Insight Software Consortium
 * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
 *
 * This file is part of Orfeo Toolbox
 *
 *     https://www.orfeo-toolbox.org/
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* Example usage:
./ProsailModel 30.0 10.0 0.0 0.015 0.009 1.2 2 50 1 70 0.2 30 0 0 Output/SailReflTest.txt
*/

//
// This example presents how to use PROSAIL (Prospect + Sail) model to generate
// viewing reflectance from leaf parameters, vegetation, and viewing parameters.
// Output can be used to simulate image for example.
//
// Let's look at the minimal code required to use this algorithm. First, the
// following headers must be included.

#include "otbSailModel.h"
#include "otbProspectModel.h"
#include "otbMacro.h"

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"

int main(int argc, char* argv[])
{
  if (argc < 16)
  {
    std::cerr << "Missing Parameters " << std::endl;
    return EXIT_FAILURE;
  }

  char* OutputName = argv[15];
  //  We now define leaf parameters, which characterize vegetation composition.

  typedef otb::LeafParameters LeafParametersType;

  //  Next the parameters variable is created by invoking the \code{New()}~method and
  //  assigning the result to a \doxygen{itk}{SmartPointer}.

  LeafParametersType::Pointer leafParams = LeafParametersType::New();

  //  Leaf characteristics is then set.
  //  Input parameters are :
  //  \begin{itemize}
  //  \item Chlorophyll concentration (Cab) in $\mu g/cm^2$.
  //  \item Carotenoid concentration (Car) in $\mu g/cm^2$.
  //  \item Brown pigment content (CBrown) in arbitrary unit.
  //  \item Water thickness EWT (Cw) in $cm$.
  //  \item Dry matter content LMA (Cm) in $g/cm^2$.
  //  \item Leaf structure parameter (N).
  //  \end{itemize}

  double Cab    = static_cast<double>(atof(argv[1]));
  double Car    = static_cast<double>(atof(argv[2]));
  double CBrown = static_cast<double>(atof(argv[3]));
  double Cw     = static_cast<double>(atof(argv[4]));
  double Cm     = static_cast<double>(atof(argv[5]));
  double N      = static_cast<double>(atof(argv[6]));

  leafParams->SetCab(Cab);
  leafParams->SetCar(Car);
  leafParams->SetCBrown(CBrown);
  leafParams->SetCw(Cw);
  leafParams->SetCm(Cm);
  leafParams->SetN(N);

  //  Leaf parameters are used as prospect input

  typedef otb::ProspectModel ProspectType;
  ProspectType::Pointer      prospect = ProspectType::New();

  prospect->SetInput(leafParams);

  //  Now we use SAIL model to generate transmitance and reflectance spectrum. SAIL model is created by invoking
  //  the \code{New()} method and
  //  assigning the result to a \doxygen{itk}{SmartPointer}.

  //  sail input parameters are :
  //  \begin{itemize}
  //  \item leaf area index (LAI).
  //  \item average leaf angle (Angle) in $\deg$.
  //  \item soil coefficient (PSoil).
  //  \item diffuse/direct radiation (Skyl).
  //  \item hot spot (HSpot).
  //  \item solar zenith angle (TTS) in $\deg$.
  //  \item observer zenith angle (TTO) in $\deg$.
  //  \item azimuth (PSI) in $\deg$.
  //  \end{itemize}

  double LAI   = static_cast<double>(atof(argv[7]));
  double Angle = static_cast<double>(atof(argv[8]));
  double PSoil = static_cast<double>(atof(argv[9]));
  double Skyl  = static_cast<double>(atof(argv[10]));
  double HSpot = static_cast<double>(atof(argv[11]));
  double TTS   = static_cast<double>(atof(argv[12]));
  double TTO   = static_cast<double>(atof(argv[13]));
  double PSI   = static_cast<double>(atof(argv[14]));

  typedef otb::SailModel SailType;

  SailType::Pointer sail = SailType::New();

  sail->SetLAI(LAI);
  sail->SetAngl(Angle);
  sail->SetPSoil(PSoil);
  sail->SetSkyl(Skyl);
  sail->SetHSpot(HSpot);
  sail->SetTTS(TTS);
  sail->SetTTO(TTO);
  sail->SetPSI(PSI);

  //  Reflectance and Transmittance  are set with prospect output.

  sail->SetReflectance(prospect->GetReflectance());
  sail->SetTransmittance(prospect->GetTransmittance());

  //  The invocation of the \code{Update()} method triggers the
  //  execution of the pipeline.

  sail->Update();

  //  \emph{GetViewingReflectance} method provides viewing reflectance vector (size $Nx2$, where $N$ is the number of sampled wavelength values, columns
  //  corresponds respectively to wavelength and viewing reflectance) by calling \emph{GetResponse}. \emph{GetHemisphericalReflectance} method provides
  //  hemispherical reflectance vector (size $Nx2$, where $N$ is the number ofsampled wavelength values, columns corresponds to wavelength and hemispherical
  //  reflectance) by calling \emph{GetResponse}.
  //
  // Note that PROSAIL simulation are done for 2100 samples starting from 400nm up to 2500nm

  for (unsigned int i = 0; i < sail->GetViewingReflectance()->Size(); ++i)
  {
    otbLogMacro(Debug, << "wavelength  : "
       << sail->GetViewingReflectance()->GetResponse()[i].first
       << ". Viewing reflectance "
       << sail->GetViewingReflectance()->GetResponse()[i].second
       << ". Hemispherical reflectance "
       << sail->GetHemisphericalReflectance()->GetResponse()[i].second);
  }

  std::ofstream outputFile(OutputName, std::ios::out);
  for (unsigned int i = 0; i < sail->GetHemisphericalReflectance()->Size(); ++i)
  {
    outputFile << sail->GetViewingReflectance()->GetResponse()[i].second << " ";
    outputFile << sail->GetHemisphericalReflectance()->GetResponse()[i].second << std::endl;
  }

  //  here you can found example parameters :
  //  \begin{itemize}
  //  \item Cab 30.0
  //  \item Car 10.0
  //  \item CBrown 0.0
  //  \item Cw 0.015
  //  \item Cm 0.009
  //  \item N 1.2
  //  \item LAI 2
  //  \item Angle 50
  //  \item PSoil 1
  //  \item Skyl 70
  //  \item HSpot 0.2
  //  \item TTS 30
  //  \item TTO 0
  //  \item PSI 0
  //  \end{itemize}
  //
  //  More information and data about leaf properties can be found at \emph{St\'{e}phane Jacquemoud}
  //  \href{http://teledetection.ipgp.jussieu.fr/opticleaf/}{OPTICLEAF} website.

  return EXIT_SUCCESS;
}
<|endoftext|>