Commit 640286ff authored by Laurent Belcour's avatar Laurent Belcour

[Merge] Python into master. Adding the possiblity to pass arguments to

the loading of data objects in the Python interface.
parent 865a6c3f
......@@ -2,6 +2,7 @@
#
# Copyright (C) 2014, 2015 CNRS
# Copyright (C) 2013, 2014, 2015 Inria
# Copyright (C) 2015 Universite de Montreal
#
# This file is part of ALTA.
#
......@@ -15,7 +16,8 @@ import SCons.SConf as C
## Add ALTA custom cmd configurations
##
AddOption('--cfg', help='Specify a configuration file (see config.example')
AddOption('--cfg', help='Specify a configuration file')
AddOption('--no-externals', action="store_false", dest="obtain_externals", default=True, help='Do not download and build externals')
## Import configuration from a config file
......@@ -99,6 +101,7 @@ if len(envVars['PKG_CONFIG_PATH']) > 0:
envVars['PKG_CONFIG_PATH'] += ':'
envVars['PKG_CONFIG_PATH'] += os.path.abspath('external' + os.sep + 'build' + os.sep + 'lib' + os.sep + 'pkgconfig')
env = Environment(variables = vars, ENV = envVars )
env['DL_EXTERNALS'] = GetOption('obtain_externals')
# Generate help text for the build variables.
......
/**
\page python Python Interface
To have access to the python interface, you need to compile the python module. This can be done using the *python* tag in the scons call:
To have access to the python interface, you need to compile the python module. This can be done using the `python` tag in the scons call:
$ scons --cfg=myconfig.py python
$ scons python
Once the python interface (alta.so) is compiled, you need to update the PYTHONPATH environment variable to the build directory. If not, you will not have access to the interface. On UNIX-like systems, it can be done using by sourcing the *setpath.sh* script. On MS-Windows, you need to update the variable by hand.
Once the python interface (alta.so) is compiled, you need to update the `PYTHONPATH` environment variable to the build directory. If not, you will not have access to the interface. On UNIX-like systems, it can be done using by sourcing the *setpath.sh* script. On MS-Windows, you need to update the variable by hand.
In python, the ALTA module is simply loaded using:
>>> import alta
You can obtain \ref functions, \ref datas and \ref fitters objects using the get_function, get_data and get_fitter functions:
This module provide different basic types such as `arguments` and `vec`. They have the same behaviour as ALTA C++ classes \ref arguments and \ref vec. However, they can be intialized from Python types. An `arguments` object can be created using a dictionnary:
>>> func = alta.get_function('nonlinear_function_blinn')
>>> dat = alta.get_data('data_merl')
>>> fitter = alta.get_fitter('nonlinear_fitter_ceres')
>>> args = alta.arguments({'foo' : 'bar', 'hello' : 'world'})
The different \ref softs are available as python functions:
This correspond to the argument `--foo bar --hello world`. Similarly, a `vec` type can be created from a list of floatting point values.
>>> dat1 = alta.load_data('data_merl', 'blue-metallic-paint.binary')
>>> dat2 = alta.get_data('data_utia')
>>> alta.data2data(dat1, dat2)
You can obtain \ref functions, \ref datas and \ref fitters objects using the `get_function`, `get_data` and `get_fitter` functions with the name of the plugin to load as argument:
This will perform a data conversion from the *blue-metallic-paint* of the MERL database to the UTIA format.
>>> func = alta.get_function('nonlinear_function_blinn')
>>> dat = alta.get_data('data_merl')
>>> fitter = alta.get_fitter('nonlinear_fitter_ceres')
Note that you can also provide an \ref arguments object to set specific options for the plugin (see below).
\ref functions and \ref datas can load from files and save to files:
>>> dat = alta.get_data('data_merl')
>>> dat.load('blue_metallic_paint.binary')
>>> dat.save('blue_metallic_paint.copy.binary')
In both cases, an \ref arguments object can be passed to control the behaviour of the load or save functions. For example, if you want to save a function in a specific format, you can use the `export` argument:
>>> args = alta.arguments({'export' : 'shader'})
>>> func = alta.get_function('nonlinear_function_blinn')
>>> func.save('my_function.func', args)
Some \ref softs are available as python functions:
>>> dat1 = alta.load_data('data_merl', 'blue-metallic-paint.binary')
>>> dat2 = alta.get_data('data_utia')
>>> alta.data2data(dat1, dat2)
This will perform a data conversion from the `blue-metallic-paint` of the [MERL][MERL] database to the \ref UTIA format.
Available \ref softs are:
+ `data2data` to convert a \ref data object into another one. This function will try to evaluate the input data at every location specified by the output data format when the format has a static set of configurations (this is the case for all `data_io` plugins). Function call: `data2data(data_in, data_out)`.
+ `brdf2data` to evalute a \ref function at the configurations defined by the data object. This will replace the content of the data object by the values of the function at the specified locations. Function call `brdf2data(func_in, data_out)`.
[MERL]: http://www.merl.com/brdf/
*/
# ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
#
# Copyright (C) 2014, 2015 CNRS
# Copyright (C) 2013, 2014, 2015 Inria
# Copyright (C) 2015 Universite de Montreal
#
# This file is part of ALTA.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import shutil
import SCons.SConf as C
......@@ -54,21 +66,21 @@ else:
# IpOpt dependencies
##
env2 = env.Clone()
if not on_windows and not library_available(env2, pkgspec='ipopt', inc_var='IPOPT_INC', lib_var='IPOPT_DIR', lib='IPOPT_LIB', header='coin/IpTNLP.hpp'):
if not on_windows and not library_available(env2, pkgspec='ipopt', inc_var='IPOPT_INC', lib_var='IPOPT_DIR', lib='IPOPT_LIB', header='coin/IpTNLP.hpp') and env['DL_EXTERNALS']:
execfile('obtain_ipopt.py')
##
# NlOpt dependencies
##
env2 = env.Clone()
if not on_windows and not library_available(env2, pkgspec='nlopt', inc_var='NLOPT_INC', lib_var='NLOPT_DIR', lib='NLOPT_LIB', header='nlopt.h'):
if not on_windows and not library_available(env2, pkgspec='nlopt', inc_var='NLOPT_INC', lib_var='NLOPT_DIR', lib='NLOPT_LIB', header='nlopt.h') and env['DL_EXTERNALS']:
execfile('obtain_nlopt.py')
##
# CERES dependencies
##
env2 = env.Clone()
if not library_available(env2, pkgspec='ceres', inc_var='CERES_INC', lib_var='CERES_DIR', lib='CERES_LIB', header='ceres/ceres.h'):
if not library_available(env2, pkgspec='ceres', inc_var='CERES_INC', lib_var='CERES_DIR', lib='CERES_LIB', header='ceres/ceres.h') and env['DL_EXTERNALS']:
execfile('obtain_ceres.py')
C.progress_display("external libraries are built as shared libraries")
......
/* ALTA --- Analysis of Bidirectional Reflectance Distribution Functions
Copyright (C) 2014, 2015 Universtie de Montreal
Copyright (C) 2013, 2014 Inria
This file is part of ALTA.
......
......@@ -381,10 +381,6 @@ vec nonlinear_function::getParametersMin() const
/*--- Compound functions implementation ----*/
compound_function::~compound_function()
{
for( unsigned int i=0; i < fs.size(); i++)
{
delete fs[i];
}
}
vec compound_function::operator()(const vec& x) const
......@@ -413,7 +409,7 @@ vec compound_function::parametersJacobian(const vec& x) const
// Export the sub-Jacobian for each function
for(unsigned int f=0; f<fs.size(); ++f)
{
nonlinear_function* func = fs[f];
const ptr<nonlinear_function>& func = fs[f];
int nb_f_params = func->nbParameters();
// Only export Jacobian if there are non-linear parameters
......@@ -439,7 +435,7 @@ vec compound_function::parametersJacobian(const vec& x) const
return jac;
}
void compound_function::push_back(nonlinear_function* f, const arguments& f_args)
void compound_function::push_back(const ptr<nonlinear_function>& f, const arguments& f_args)
{
// Update the input param
if(input_parametrization() == params::UNKNOWN_INPUT)
......@@ -472,7 +468,7 @@ nonlinear_function* compound_function::operator[](int i) const
#ifdef DEBUG
assert(i >= 0 && i < fs.size());
#endif
return fs[i];
return fs[i].get();
}
unsigned int compound_function::size() const
......@@ -580,9 +576,9 @@ void compound_function::bootstrap(const ::ptr<data> d, const arguments& args)
{
std::streampos pos = file.tellg();
if(dynamic_cast<product_function*>(fs[i]) != NULL)
{
product_function* p = dynamic_cast<product_function*>(fs[i]);
ptr<product_function> p = dynamic_pointer_cast<product_function>(fs[i]);
if(p) {
nonlinear_function* f1 = p->first();
nonlinear_function* f2 = p->second();
......@@ -837,8 +833,9 @@ void compound_function::save_call(std::ostream& out, const arguments& args) cons
/*--- Product functions implementation ----*/
product_function::product_function( nonlinear_function* g1, nonlinear_function* g2,
bool is_g1_fixed, bool is_g2_fixed)
product_function::product_function(const ptr<nonlinear_function>& g1,
const ptr<nonlinear_function>& g2,
bool is_g1_fixed, bool is_g2_fixed)
: f1( g1 ),
f2( g2 ),
_is_fixed( std::pair<bool,bool>( is_g1_fixed, is_g2_fixed) )
......@@ -859,8 +856,6 @@ product_function::product_function( nonlinear_function* g1, nonlinear_function*
product_function::~product_function()
{
delete f1;
delete f2;
}
......@@ -895,8 +890,7 @@ bool product_function::load(std::istream& in)
std::streampos pos = in.tellg();
// Load the first function
if(f1 != NULL)
{
if(f1) {
loaded_f1 = f1->load(in);
if(! loaded_f1)
{
......@@ -906,8 +900,7 @@ bool product_function::load(std::istream& in)
pos = in.tellg();
// Load the second function
if(f2 != NULL)
{
if(f2) {
loaded_f2 = f2->load(in);
if(! loaded_f2)
{
......@@ -1296,10 +1289,10 @@ void product_function::setParametrization(params::output new_param)
nonlinear_function* product_function::first() const
{
return f1;
return f1.get();
}
nonlinear_function* product_function::second() const
{
return f2;
return f2.get();
}
......@@ -183,7 +183,7 @@ class compound_function: public nonlinear_function
//! This function allows to put a new nonlinear function \a f in the
//! compound object. This function will be processed for nonlinear
//! optimisation only if \a fixed equals true.
virtual void push_back(nonlinear_function* f, const arguments& f_args);
virtual void push_back(const ptr<nonlinear_function>& f, const arguments& f_args);
//! \brief Access to the i-th function of the compound
nonlinear_function* operator[](int i) const;
......@@ -214,7 +214,7 @@ class compound_function: public nonlinear_function
//!
//! <u>Local/Global policy:</u></br />
//! Local bootstrap can not overload the global bootstrap.
virtual void bootstrap(const ::ptr<data> d, const arguments& args);
virtual void bootstrap(const ptr<data> d, const arguments& args);
//! Set the dimension of the input space of the function
virtual void setDimX(int nX);
......@@ -272,7 +272,7 @@ class compound_function: public nonlinear_function
virtual void save_call(std::ostream& out, const arguments& args) const;
protected:
std::vector<nonlinear_function*> fs;
std::vector<ptr<nonlinear_function>> fs;
std::vector<arguments> fs_args;
std::vector<bool> is_fixed;
......@@ -289,9 +289,8 @@ class product_function : public nonlinear_function
//! \brief Constructor of the product function, affect the two function
//! to already created nonlinear_function objects.
product_function(nonlinear_function* g1, nonlinear_function* g2,
bool is_g1_fixed = false,
bool is_g2_fixed = false);
product_function(const ptr<nonlinear_function>& g1, const ptr<nonlinear_function>& g2,
bool is_g1_fixed = false, bool is_g2_fixed = false);
~product_function();
......@@ -372,7 +371,7 @@ class product_function : public nonlinear_function
private: // data
// Function composing the product
nonlinear_function *f1, *f2;
ptr<nonlinear_function> f1, f2;
std::pair<bool,bool> _is_fixed; /*!< represents whether or not the parameters of each function is fixed regardint the optimizer */
......
......@@ -424,7 +424,7 @@ ptr<function> plugins_manager::get_function(const std::string& n)
ptr<data> plugins_manager::get_data(const std::string& n, const arguments& args)
{
if(n.empty())
if(n.empty() || n == "vertical_segment")
{
#ifdef DEBUG
std::cout << "<<DEBUG>> no data plugin specified, returning a vertical_segment loader" << std::endl;
......
......@@ -217,7 +217,7 @@ class rational_function : public function
this->nq = nq;
clear();
}
//! \brief Clear the vector of 1D rational functions.
virtual void clear()
{
......
......@@ -39,7 +39,8 @@ class blinn_function : public nonlinear_function
blinn_function()
{
setParametrization(params::COS_TH);
setDimX(1);
setDimX(1);
setDimY(1);
}
// Overload the function operator
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment