<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
// Author: Hadrien Courtecuisse
//
// Copyright: See COPYING file that comes with this distribution
#include <sofa/core/objectmodel/BaseContext.h>
#include <sofa/core/behavior/LinearSolver.h>
#include <sofa/component/linearsolver/ShewchukPCGLinearSolver.h>
#include <sofa/component/linearsolver/NewMatMatrix.h>
#include <sofa/component/linearsolver/FullMatrix.h>
#include <sofa/component/linearsolver/SparseMatrix.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/thread/CTime.h>
#include <sofa/helper/AdvancedTimer.h>

#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace component
{

namespace linearsolver
{

using namespace sofa::defaulttype;
using namespace sofa::core::behavior;
using namespace sofa::simulation;
using namespace sofa::core::objectmodel;
using sofa::helper::system::thread::CTime;
using sofa::helper::system::thread::ctime_t;
using std::cerr;
using std::endl;

template<class TMatrix, class TVector>
ShewchukPCGLinearSolver<TMatrix,TVector>::ShewchukPCGLinearSolver()
    : f_maxIter( initData(&f_maxIter,(unsigned)25,"iterations","maximum number of iterations of the Conjugate Gradient solution") )
    , f_tolerance( initData(&f_tolerance,1e-5,"tolerance","desired precision of the Conjugate Gradient Solution (ratio of current residual norm over initial residual norm)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
    , f_update_iteration( initData(&f_update_iteration,(unsigned)0,"update_iteration","Number of CG iterations before next refresh of precondtioner") )
    , f_update_step( initData(&f_update_step,(unsigned)1,"update_step","Number of steps before the next refresh of precondtioners") )
    , f_use_precond( initData(&f_use_precond,true,"use_precond","Use preconditioners") )
    , f_preconditioners( initData(&f_preconditioners, "preconditioners", "If not empty: path to the solvers to use as preconditioners") )
    , f_graph( initData(&f_graph,"graph","Graph of residuals at each iteration") )
{
    f_graph.setWidget("graph");
//    f_graph.setReadOnly(true);
    usePrecond = true;
    first = true;
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::init()
{
    std::vector<sofa::core::behavior::LinearSolver*> solvers;
    BaseContext * c = this->getContext();

    const helper::vector<std::string>& precondNames = f_preconditioners.getValue();
    if (precondNames.empty() && f_use_precond.getValue())
    {
        c->get<sofa::core::behavior::LinearSolver>(&solvers,BaseContext::SearchDown);
    }
    else
    {
        for (unsigned int i=0; i<precondNames.size(); ++i)
        {
            sofa::core::behavior::LinearSolver* s = NULL;
            c->get(s, precondNames[i]);
            if (s) solvers.push_back(s);
            else serr << "Solver \"" << precondNames[i] << "\" not found." << sendl;
        }
    }

    for (unsigned int i=0; i<solvers.size(); ++i)
    {
        if (solvers[i] && solvers[i] != this)
        {
            this->preconditioners.push_back(solvers[i]);
        }
    }

    sout<<"Found " << this->preconditioners.size() << " preconditioners"<<sendl;

    first = true;
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::setSystemMBKMatrix(double mFact, double bFact, double kFact)
{
    sofa::helper::AdvancedTimer::valSet("PCG::buildMBK", 1);
    sofa::helper::AdvancedTimer::stepBegin("PCG::setSystemMBKMatrix");

    Inherit::setSystemMBKMatrix(mFact,bFact,kFact);

    sofa::helper::AdvancedTimer::stepEnd("PCG::setSystemMBKMatrix(Precond)");

    if (preconditioners.size()==0) return;

    if (first)   //We initialize all the preconditioners for the first step
    {
        for (unsigned int i=0; i<this->preconditioners.size(); ++i)
        {
            preconditioners[i]->setSystemMBKMatrix(mFact,bFact,kFact);
        }
        first = false;
        next_refresh_iteration = 1;
        next_refresh_step = 1;
    }
    else if (f_use_precond.getValue())     // We use only the first precond in the list
    {
        sofa::helper::AdvancedTimer::valSet("PCG::PrecondBuildMBK", 1);
        sofa::helper::AdvancedTimer::stepBegin("PCG::PrecondSetSystemMBKMatrix");

        if (f_update_step.getValue()>0)
        {
            if (next_refresh_step>=f_update_step.getValue())
            {
                preconditioners[0]->setSystemMBKMatrix(mFact,bFact,kFact);
                next_refresh_step=1;
            }
            else
            {
                next_refresh_step++;
            }
        }
        else if (f_update_iteration.getValue()>0)
        {
            if (next_refresh_iteration>=f_update_iteration.getValue())
            {
                preconditioners[0]->setSystemMBKMatrix(mFact,bFact,kFact);
                next_refresh_iteration=1;
            }
        }
        sofa::helper::AdvancedTimer::stepEnd("PCG::PrecondSetSystemMBKMatrix");
    }

}

template<>
inline void ShewchukPCGLinearSolver<component::linearsolver::GraphScatteredMatrix,component::linearsolver::GraphScatteredVector>::cgstep_beta(Vector& p, Vector& r, double beta)
{
    this->v_op(p,r,p,beta); // p = p*beta + r
}

template<>
inline void ShewchukPCGLinearSolver<component::linearsolver::GraphScatteredMatrix,component::linearsolver::GraphScatteredVector>::cgstep_alpha(Vector& x, Vector& p, double alpha)
{
    x.peq(p,alpha);                 // x = x + alpha p
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::solve (Matrix& M, Vector& x, Vector& b)
{
    sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");

    Vector& r = *this->createVector();
    Vector& d = *this->createVector();
    Vector& q = *this->createVector();
    Vector& s = *this->createVector();
    const bool verbose  = f_verbose.getValue();

    unsigned iter=1;
    r = M*x;

    cgstep_beta(r,b,-1);//for (int i=0; i<n; i++) r[i] = b[i] - r[i];
    if (this->preconditioners.size()>0 && usePrecond)
    {
        sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
        sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::apply Precond");
        preconditioners[0]->setSystemLHVector(d);
        preconditioners[0]->setSystemRHVector(r);
        preconditioners[0]->freezeSystemMatrix();
        preconditioners[0]->solveSystem();
        //Use freeze boolean to specify the preconditioner that's the fist solve of the step (for example if stepMBK is not call)
        preconditioners[0]->updateSystemMatrix();
        sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::apply Precond");
        sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");
    }
    else
    {
        d = r;
    }

    double deltaNew = r.dot(d);
    double delta0 = deltaNew;
    double eps = f_tolerance.getValue() * f_tolerance.getValue()  * delta0;
    std::map < std::string, sofa::helper::vector<double> >& graph = * f_graph.beginEdit();
    sofa::helper::vector<double>& graph_error = graph["Error"];
    graph_error.clear();

    while ((iter <= f_maxIter.getValue()) && (deltaNew > eps))
    {
        if (verbose) printf("CG iteration %d: current L2 error vs initial error=%G\n", iter, sqrt(deltaNew/delta0));

        graph_error.push_back(deltaNew);

        q = M * d;
        double dtq = d.dot(q);
        double alpha = deltaNew / dtq;

        cgstep_alpha(x,d,alpha);//for(int i=0; i<n; i++) x[i] += alpha * d[i];

        if (iter % 50 == 0)  // periodically compute the exact residual
        {
            r = M * x;
            cgstep_beta(r,b,-1);//for (int i=0; i<n; i++) r[i] = b[i] - r[i];
        }
        else
        {
            cgstep_alpha(r,q,-alpha);//for (int i=0; i<n; i++) r[i] = r[i] - alpha * q[i];
        }

        if (this->preconditioners.size()>0 && usePrecond)
        {
            sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
            sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::apply Precond");
            preconditioners[0]->setSystemLHVector(s);
            preconditioners[0]->setSystemRHVector(r);
            preconditioners[0]->solveSystem();
            sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::apply Precond");
            sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");

        }
        else
        {
            s = r;
        }

        double deltaOld = deltaNew;
        deltaNew = r.dot(s);
        double beta = deltaNew / deltaOld;

        cgstep_beta(d,s,beta);//for (int i=0; i<n; i++) d[i] = r[i] + beta * d[i];

        iter++;
    }

    graph_error.push_back(deltaNew);
    next_refresh_iteration=iter;
    sofa::helper::AdvancedTimer::valSet("PCG iterations", iter);

    f_graph.endEdit();
    this->deleteVector(&r);
    this->deleteVector(&q);
    this->deleteVector(&d);
    this->deleteVector(&s);
    sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
}

SOFA_DECL_CLASS(ShewchukPCGLinearSolver)

int ShewchukPCGLinearSolverClass = core::RegisterObject("Linear system solver using the conjugate gradient iterative algorithm")
        .add< ShewchukPCGLinearSolver<GraphScatteredMatrix,GraphScatteredVector> >(true)
        ;

} // namespace linearsolver

} // namespace component

} // namespace sofa

<commit_msg>r7803/sofa-dev : Small changes in ShewchukPCGLinearSolver<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* You should have received a copy of the GNU Lesser General Public License    *
* along with this library; if not, write to the Free Software Foundation,     *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
// Author: Hadrien Courtecuisse
//
// Copyright: See COPYING file that comes with this distribution
#include <sofa/core/objectmodel/BaseContext.h>
#include <sofa/core/behavior/LinearSolver.h>
#include <sofa/component/linearsolver/ShewchukPCGLinearSolver.h>
#include <sofa/component/linearsolver/NewMatMatrix.h>
#include <sofa/component/linearsolver/FullMatrix.h>
#include <sofa/component/linearsolver/SparseMatrix.h>
#include <sofa/simulation/common/MechanicalVisitor.h>
#include <sofa/helper/system/thread/CTime.h>
#include <sofa/helper/AdvancedTimer.h>

#include <sofa/core/ObjectFactory.h>
#include <iostream>

namespace sofa
{

namespace component
{

namespace linearsolver
{

using namespace sofa::defaulttype;
using namespace sofa::core::behavior;
using namespace sofa::simulation;
using namespace sofa::core::objectmodel;
using sofa::helper::system::thread::CTime;
using sofa::helper::system::thread::ctime_t;
using std::cerr;
using std::endl;

template<class TMatrix, class TVector>
ShewchukPCGLinearSolver<TMatrix,TVector>::ShewchukPCGLinearSolver()
    : f_maxIter( initData(&f_maxIter,(unsigned)25,"iterations","maximum number of iterations of the Conjugate Gradient solution") )
    , f_tolerance( initData(&f_tolerance,1e-5,"tolerance","desired precision of the Conjugate Gradient Solution (ratio of current residual norm over initial residual norm)") )
    , f_verbose( initData(&f_verbose,false,"verbose","Dump system state at each iteration") )
    , f_update_iteration( initData(&f_update_iteration,(unsigned)0,"update_iteration","Number of CG iterations before next refresh of precondtioner") )
    , f_update_step( initData(&f_update_step,(unsigned)1,"update_step","Number of steps before the next refresh of precondtioners") )
    , f_use_precond( initData(&f_use_precond,true,"use_precond","Use preconditioners") )
    , f_preconditioners( initData(&f_preconditioners, "preconditioners", "If not empty: path to the solvers to use as preconditioners") )
    , f_graph( initData(&f_graph,"graph","Graph of residuals at each iteration") )
{
    f_graph.setWidget("graph");
//    f_graph.setReadOnly(true);
    usePrecond = true;
    first = true;
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::init()
{
    std::vector<sofa::core::behavior::LinearSolver*> solvers;
    BaseContext * c = this->getContext();

    const helper::vector<std::string>& precondNames = f_preconditioners.getValue();
    if (precondNames.empty() && f_use_precond.getValue())
    {
        c->get<sofa::core::behavior::LinearSolver>(&solvers,BaseContext::SearchDown);
    }
    else
    {
        for (unsigned int i=0; i<precondNames.size(); ++i)
        {
            sofa::core::behavior::LinearSolver* s = NULL;
            c->get(s, precondNames[i]);
            if (s) solvers.push_back(s);
            else serr << "Solver \"" << precondNames[i] << "\" not found." << sendl;
        }
    }

    for (unsigned int i=0; i<solvers.size(); ++i)
    {
        if (solvers[i] && solvers[i] != this)
        {
            this->preconditioners.push_back(solvers[i]);
        }
    }

    sout<<"Found " << this->preconditioners.size() << " preconditioners"<<sendl;

    first = true;
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::setSystemMBKMatrix(double mFact, double bFact, double kFact)
{
    sofa::helper::AdvancedTimer::valSet("PCG::buildMBK", 1);
    sofa::helper::AdvancedTimer::stepBegin("PCG::setSystemMBKMatrix");

    Inherit::setSystemMBKMatrix(mFact,bFact,kFact);

    sofa::helper::AdvancedTimer::stepEnd("PCG::setSystemMBKMatrix(Precond)");

    if (preconditioners.size()==0) return;

    if (first)   //We initialize all the preconditioners for the first step
    {
        for (unsigned int i=0; i<this->preconditioners.size(); ++i)
        {
            preconditioners[i]->setSystemMBKMatrix(mFact,bFact,kFact);
        }
        first = false;
        next_refresh_step = 1;
    }
    else if (f_use_precond.getValue())     // We use only the first precond in the list
    {
        sofa::helper::AdvancedTimer::valSet("PCG::PrecondBuildMBK", 1);
        sofa::helper::AdvancedTimer::stepBegin("PCG::PrecondSetSystemMBKMatrix");

        if ((f_update_step.getValue()>0) && (f_update_iteration.getValue()>0))
        {
            if ((next_refresh_step>=f_update_step.getValue()) && (next_refresh_iteration>=f_update_iteration.getValue()))
            {
                preconditioners[0]->setSystemMBKMatrix(mFact,bFact,kFact);
                next_refresh_step=1;
            }
            else
            {
                next_refresh_step++;
            }
        }
        else if (f_update_step.getValue()>0)
        {
            if (next_refresh_step>=f_update_step.getValue())
            {
                preconditioners[0]->setSystemMBKMatrix(mFact,bFact,kFact);
                next_refresh_step=1;
            }
            else
            {
                next_refresh_step++;
            }
        }
        else if (f_update_iteration.getValue()>0)
        {
            if (next_refresh_iteration>=f_update_iteration.getValue())
            {
                preconditioners[0]->setSystemMBKMatrix(mFact,bFact,kFact);
                next_refresh_iteration=1;
            }
        }
        sofa::helper::AdvancedTimer::stepEnd("PCG::PrecondSetSystemMBKMatrix");
    }
    next_refresh_iteration = 1;

}

template<>
inline void ShewchukPCGLinearSolver<component::linearsolver::GraphScatteredMatrix,component::linearsolver::GraphScatteredVector>::cgstep_beta(Vector& p, Vector& r, double beta)
{
    this->v_op(p,r,p,beta); // p = p*beta + r
}

template<>
inline void ShewchukPCGLinearSolver<component::linearsolver::GraphScatteredMatrix,component::linearsolver::GraphScatteredVector>::cgstep_alpha(Vector& x, Vector& p, double alpha)
{
    x.peq(p,alpha);                 // x = x + alpha p
}

template<class TMatrix, class TVector>
void ShewchukPCGLinearSolver<TMatrix,TVector>::solve (Matrix& M, Vector& x, Vector& b)
{
    sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");

    Vector& r = *this->createVector();
    Vector& d = *this->createVector();
    Vector& q = *this->createVector();
    Vector& s = *this->createVector();
    const bool verbose  = f_verbose.getValue();

    unsigned iter=1;
    r = M*x;

    cgstep_beta(r,b,-1);//for (int i=0; i<n; i++) r[i] = b[i] - r[i];
    if (this->preconditioners.size()>0 && usePrecond)
    {
        sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
        sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::apply Precond");
        preconditioners[0]->setSystemLHVector(d);
        preconditioners[0]->setSystemRHVector(r);
        preconditioners[0]->freezeSystemMatrix();
        preconditioners[0]->solveSystem();
        //Use freeze boolean to specify the preconditioner that's the fist solve of the step (for example if stepMBK is not call)
        preconditioners[0]->updateSystemMatrix();
        sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::apply Precond");
        sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");
    }
    else
    {
        d = r;
    }

    double deltaNew = r.dot(d);
    double delta0 = deltaNew;
    double eps = f_tolerance.getValue() * f_tolerance.getValue()  * delta0;
    std::map < std::string, sofa::helper::vector<double> >& graph = * f_graph.beginEdit();
    sofa::helper::vector<double>& graph_error = graph["Error"];
    graph_error.clear();

    while ((iter <= f_maxIter.getValue()) && (deltaNew > eps))
    {
        if (verbose) printf("CG iteration %d: current L2 error vs initial error=%G\n", iter, sqrt(deltaNew/delta0));

        graph_error.push_back(deltaNew);

        q = M * d;
        double dtq = d.dot(q);
        double alpha = deltaNew / dtq;

        cgstep_alpha(x,d,alpha);//for(int i=0; i<n; i++) x[i] += alpha * d[i];

        if (iter % 50 == 0)  // periodically compute the exact residual
        {
            r = M * x;
            cgstep_beta(r,b,-1);//for (int i=0; i<n; i++) r[i] = b[i] - r[i];
        }
        else
        {
            cgstep_alpha(r,q,-alpha);//for (int i=0; i<n; i++) r[i] = r[i] - alpha * q[i];
        }

        if (this->preconditioners.size()>0 && usePrecond)
        {
            sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
            sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::apply Precond");
            preconditioners[0]->setSystemLHVector(s);
            preconditioners[0]->setSystemRHVector(r);
            preconditioners[0]->solveSystem();
            sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::apply Precond");
            sofa::helper::AdvancedTimer::stepBegin("PCGLinearSolver::solve");

        }
        else
        {
            s = r;
        }

        double deltaOld = deltaNew;
        deltaNew = r.dot(s);
        double beta = deltaNew / deltaOld;

        cgstep_beta(d,s,beta);//for (int i=0; i<n; i++) d[i] = r[i] + beta * d[i];

        iter++;
    }

    graph_error.push_back(deltaNew);
    next_refresh_iteration=iter;
    sofa::helper::AdvancedTimer::valSet("PCG iterations", iter);

    f_graph.endEdit();
    this->deleteVector(&r);
    this->deleteVector(&q);
    this->deleteVector(&d);
    this->deleteVector(&s);
    sofa::helper::AdvancedTimer::stepEnd("PCGLinearSolver::solve");
}

SOFA_DECL_CLASS(ShewchukPCGLinearSolver)

int ShewchukPCGLinearSolverClass = core::RegisterObject("Linear system solver using the conjugate gradient iterative algorithm")
        .add< ShewchukPCGLinearSolver<GraphScatteredMatrix,GraphScatteredVector> >(true)
        ;

} // namespace linearsolver

} // namespace component

} // namespace sofa

<|endoftext|>


<commit_before>#ifndef REFL_INFORMATION_HPP
#define REFL_INFORMATION_HPP

#include "../meta_utils/meta_utils.hpp"
#include "variables/reflect_information_variable.hpp"
#include "functions/reflect_information_method.hpp"

namespace reflect {

/**
 * @brief Namespace related to all reflection information(metadata, names, etc)
 */
namespace info {

/**
 * @brief SFINAE check if class is generator
 */
template <class T>
struct is_generator {
    template <class C, ::std::size_t... Indices> static constexpr ::std::true_type check(decltype (&C::template generate<::boost::hana::tuple<::boost::hana::size_t<Indices>...>>));
    template <class> static constexpr ::std::false_type check(...);
    static constexpr bool value = ::std::is_same<::std::true_type, decltype(check<T>(nullptr))>::value;
};

template <class T> constexpr bool is_generator_v = is_generator<T>::value;

/**
 * @brief SFINAE check if class is reflected
 *
 */
template <class T>
struct is_reflected {

    /**
     * @brief If is_reflected method exist
     *
     * @return ::std::true_type
     */
    template <class C> static constexpr ::std::true_type check(decltype(&C::is_reflected));
    /**
     * @brief If is_reflected method doesn't exist
     *
     * @return ::std::false_type
     */
    template <class> static constexpr ::std::false_type check(...);
    static constexpr bool value = ::std::is_same<::std::true_type, decltype(check<T>(nullptr))>::value; /**< true true if reflected, othervise false */
};

template <class T> constexpr bool is_reflected_v = is_reflected<T>::value; /**< Helper variable template for is_reflected */

namespace detail {

/**
  * @brief Concating all names in one tuple
  */
template <class Type, class MetaInfo_type, ::std::size_t... Indices>
constexpr decltype (auto) names_tuple (::std::index_sequence<Indices... >&&) {
    return metautils::multiple_concat(names_state(metautils::counter<Indices>{},static_cast<const Type*>(nullptr),static_cast<const MetaInfo_type*>(nullptr))...);
}

/**
  * @brief Concating all metadata in one tuple
  */
template <class Type, class MetaInfo_type, ::std::size_t... Indices>
constexpr decltype (auto) metadata_tuple (::std::index_sequence<Indices... >&&) {
    return metautils::multiple_concat(metadata_state(metautils::counter<Indices>{},static_cast<const Type*>(nullptr),static_cast<const MetaInfo_type*>(nullptr))...);
}

}

/**
 * @brief Class that stores meta-information about T
 *
 */
template <class T>
struct MetaClass {
    using Type = typename T::Type;
    using MetaInfo_type = T;
    static constexpr auto class_name   {HANA_STR(class_name_detail(static_cast<const typename T::Type*>(nullptr),static_cast<const T*>(nullptr)))}; /**< compile-time string of class name */
    static constexpr auto names        {detail::names_tuple<Type, MetaInfo_type>(::std::make_index_sequence<decltype(counter(metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>{})}; /**< tuple of all variable names */
    static constexpr auto metadata     {detail::metadata_tuple<Type, MetaInfo_type>(::std::make_index_sequence<decltype(counter(metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>{})}; /**< tuple of all method names  */
};

class EmptyGenerator;

/**
 * @brief The DefaultIndexGenerator class - generate tuple of indices [0..N-1] where N - tuple size
 */
class DefaultIndexGenerator final {
public:
    using reverse = EmptyGenerator;

    /**
      * @brief Generate tuple of indices
      * @return  ::boost::hana::tuple<0...N-1>
      */
    template<class Tuple>
    constexpr static decltype (auto) generate () {
        return metautils::gen_inds_tup<decltype(::boost::hana::size(::std::declval<Tuple>()))>();
    }
};

/**
 * @brief Empty generator
 */
class EmptyGenerator final {
public:
    using reverse = DefaultIndexGenerator;

    template<class Tuple>
    /**
     * @brief Generate empty tuple
     * @return ::boost::hana::tuple<>
     */
    constexpr static ::boost::hana::tuple<> generate () {
        return {};
    }
};

/**
 * @brief Class that stores meta-functions
 */
template <class... Args>
struct MetaInfo;

}

}

#define IN_METAINFO(TYPE) \
    using Type = TYPE; \
    using MetaInfo_type = TYPE; \
    static constexpr auto is_reflected () {return std::true_type();} \
    friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
    friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define OUT_METAINFO(TYPE) \
    friend struct reflect::info::MetaInfo<TYPE>; \
    using MetaInfo_type = ::reflect::info::MetaInfo<TYPE>; \
    static constexpr auto is_reflected () {return std::true_type();}

#define METAINFO(TYPE) \
    namespace reflect { \
        namespace info { \
            template <> \
            struct MetaInfo<TYPE> { \
                using Type = TYPE; \
                using MetaInfo_type = ::reflect::info::MetaInfo<Type>; \
                friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
                friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define TEMPLATE_METAINFO(TYPE,TEMPLATE_TYPE,TEMPLATE) \
    namespace reflect { \
        namespace info { \
            template <TEMPLATE_TYPE> \
            struct MetaInfo<TYPE<TEMPLATE>> { \
                using Type = TYPE<TEMPLATE>; \
                using MetaInfo_type = ::reflect::info::MetaInfo<Type>; \
                friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
                friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define TEMPLATE_METAINFO_SPETIALIZE(TYPE,TEMPLATE) \
    namespace reflect { \
        namespace info { \
            struct MetaInfo<TYPE<TEMPLATE>> { \
                using Type = TYPE<TEMPLATE>; \
                using MetaInfo_type = ::reflect::info::MetaInfo<Type>; \
                friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
                friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define END_METAINFO \
            }; \
    } }

#define TUPLE_APPEND(STATE, COUNTER, ...) \
    friend constexpr auto STATE(::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>, \
            const Type*, const MetaInfo_type*) -> decltype (::boost::hana::make_tuple(__VA_ARGS__)) \
        { return ::boost::hana::make_tuple(__VA_ARGS__); }

#define INCREASE_COUNTER(COUNTER) \
    friend constexpr ::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value+1u> \
                     COUNTER (::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value+1u>, const MetaInfo_type*);

#endif // META_INFORMATION_HPP
<commit_msg>Remove unnecessary macros<commit_after>#ifndef REFL_INFORMATION_HPP
#define REFL_INFORMATION_HPP

#include "../meta_utils/meta_utils.hpp"
#include "variables/reflect_information_variable.hpp"
#include "functions/reflect_information_method.hpp"

namespace reflect {

/**
 * @brief Namespace related to all reflection information(metadata, names, etc)
 */
namespace info {

/**
 * @brief SFINAE check if class is generator
 */
template <class T>
struct is_generator {
    template <class C, ::std::size_t... Indices> static constexpr ::std::true_type check(decltype (&C::template generate<::boost::hana::tuple<::boost::hana::size_t<Indices>...>>));
    template <class> static constexpr ::std::false_type check(...);
    static constexpr bool value = ::std::is_same<::std::true_type, decltype(check<T>(nullptr))>::value;
};

template <class T> constexpr bool is_generator_v = is_generator<T>::value;

/**
 * @brief SFINAE check if class is reflected
 *
 */
template <class T>
struct is_reflected {

    /**
     * @brief If is_reflected method exist
     *
     * @return ::std::true_type
     */
    template <class C> static constexpr ::std::true_type check(decltype(&C::is_reflected));
    /**
     * @brief If is_reflected method doesn't exist
     *
     * @return ::std::false_type
     */
    template <class> static constexpr ::std::false_type check(...);
    static constexpr bool value = ::std::is_same<::std::true_type, decltype(check<T>(nullptr))>::value; /**< true true if reflected, othervise false */
};

template <class T> constexpr bool is_reflected_v = is_reflected<T>::value; /**< Helper variable template for is_reflected */

namespace detail {

/**
  * @brief Concating all names in one tuple
  */
template <class Type, class MetaInfo_type, ::std::size_t... Indices>
constexpr decltype (auto) names_tuple (::std::index_sequence<Indices... >&&) {
    return metautils::multiple_concat(names_state(metautils::counter<Indices>{},static_cast<const Type*>(nullptr),static_cast<const MetaInfo_type*>(nullptr))...);
}

/**
  * @brief Concating all metadata in one tuple
  */
template <class Type, class MetaInfo_type, ::std::size_t... Indices>
constexpr decltype (auto) metadata_tuple (::std::index_sequence<Indices... >&&) {
    return metautils::multiple_concat(metadata_state(metautils::counter<Indices>{},static_cast<const Type*>(nullptr),static_cast<const MetaInfo_type*>(nullptr))...);
}

}

/**
 * @brief Class that stores meta-information about T
 *
 */
template <class T>
struct MetaClass {
    using Type = typename T::Type;
    using MetaInfo_type = T;
    static constexpr auto class_name   {HANA_STR(class_name_detail(static_cast<const typename T::Type*>(nullptr),static_cast<const T*>(nullptr)))}; /**< compile-time string of class name */
    static constexpr auto names        {detail::names_tuple<Type, MetaInfo_type>(::std::make_index_sequence<decltype(counter(metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>{})}; /**< tuple of all variable names */
    static constexpr auto metadata     {detail::metadata_tuple<Type, MetaInfo_type>(::std::make_index_sequence<decltype(counter(metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>{})}; /**< tuple of all method names  */
};

class EmptyGenerator;

/**
 * @brief The DefaultIndexGenerator class - generate tuple of indices [0..N-1] where N - tuple size
 */
class DefaultIndexGenerator final {
public:
    using reverse = EmptyGenerator;

    /**
      * @brief Generate tuple of indices
      * @return  ::boost::hana::tuple<0...N-1>
      */
    template<class Tuple>
    constexpr static decltype (auto) generate () {
        return metautils::gen_inds_tup<decltype(::boost::hana::size(::std::declval<Tuple>()))>();
    }
};

/**
 * @brief Empty generator
 */
class EmptyGenerator final {
public:
    using reverse = DefaultIndexGenerator;

    template<class Tuple>
    /**
     * @brief Generate empty tuple
     * @return ::boost::hana::tuple<>
     */
    constexpr static ::boost::hana::tuple<> generate () {
        return {};
    }
};

/**
 * @brief Class that stores meta-functions
 */
template <class... Args>
struct MetaInfo;

}

}

#define IN_METAINFO(TYPE) \
    using Type = TYPE; \
    using MetaInfo_type = TYPE; \
    static constexpr auto is_reflected () {return std::true_type();} \
    friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
    friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define OUT_METAINFO(TYPE) \
    friend struct reflect::info::MetaInfo<TYPE>; \
    using MetaInfo_type = ::reflect::info::MetaInfo<TYPE>; \
    static constexpr auto is_reflected () {return std::true_type();}

#define METAINFO(TYPE) \
    namespace reflect { \
        namespace info { \
            template <> \
            struct MetaInfo<TYPE> { \
                using Type = TYPE; \
                using MetaInfo_type = ::reflect::info::MetaInfo<Type>; \
                friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
                friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define TEMPLATE_METAINFO(TYPE,TEMPLATE_TYPE,TEMPLATE) \
    namespace reflect { \
        namespace info { \
            template <TEMPLATE_TYPE> \
            struct MetaInfo<TYPE<TEMPLATE>> { \
                using Type = TYPE<TEMPLATE>; \
                using MetaInfo_type = ::reflect::info::MetaInfo<Type>; \
                friend constexpr auto class_name_detail(const Type*, const MetaInfo_type*) -> decltype (#TYPE) { return #TYPE; } \
                friend constexpr ::reflect::metautils::counter<0> counter (::reflect::metautils::counter<0>, const MetaInfo_type*);

#define END_METAINFO \
            }; \
    } }

#define TUPLE_APPEND(STATE, COUNTER, ...) \
    friend constexpr auto STATE(::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value>, \
            const Type*, const MetaInfo_type*) -> decltype (::boost::hana::make_tuple(__VA_ARGS__)) \
        { return ::boost::hana::make_tuple(__VA_ARGS__); }

#define INCREASE_COUNTER(COUNTER) \
    friend constexpr ::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value+1u> \
                     COUNTER (::reflect::metautils::counter<decltype(COUNTER(::reflect::metautils::counter<>{},static_cast<const MetaInfo_type*>(nullptr)))::value+1u>, const MetaInfo_type*);

#endif // META_INFORMATION_HPP
<|endoftext|>


<commit_before>// MOOSE includes
#include "FEProblemBase.h"
#include "MultiApp.h"
#include "PiecewiseBase.h"

// MASTODON includes
#include "PiecewiseFunctionTransfer.h"

registerMooseObject("MastodonApp", PiecewiseFunctionTransfer);

InputParameters
PiecewiseFunctionTransfer::validParams()
{
  InputParameters params = MultiAppTransfer::validParams();
  params.addClassDescription("Transfers from one Piecewise function to another.");

  params.addRequiredParam<std::string>("to_function",
                                       "The name of the function being transferred into.");

  params.addRequiredParam<std::string>("from_function",
                                       "The name of the function being transferred out of.");

  return params;
}

PiecewiseFunctionTransfer::PiecewiseFunctionTransfer(const InputParameters & parameters)
  : MultiAppTransfer(parameters)
{
}

void
PiecewiseFunctionTransfer::execute()
{
  const std::string & from_name = getParam<std::string>("from_function");
  const std::string & to_name = getParam<std::string>("to_function");

  if (_direction == TO_MULTIAPP)
  {
    FEProblemBase & from_problem = _multi_app->problemBase();
    PiecewiseBase & from_function =
        dynamic_cast<PiecewiseBase &>(from_problem.getFunction(from_name));
    for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
      if (_multi_app->hasLocalApp(i))
      {
        FEProblemBase & to_problem = getMultiApp()->appProblemBase(i);
        PiecewiseBase & to_function =
            dynamic_cast<PiecewiseBase &>(to_problem.getFunction(to_name));
        transfer(from_function, to_function);
      }
  }

  else if (_direction == FROM_MULTIAPP)
  {
    FEProblemBase & to_problem = _multi_app->problemBase();
    PiecewiseBase & to_function = dynamic_cast<PiecewiseBase &>(to_problem.getFunction(to_name));
    for (unsigned int i = 0; i < _multi_app->numGlobalApps(); i++)
      if (_multi_app->hasLocalApp(i))
      {
        FEProblemBase & from_problem = getMultiApp()->appProblemBase(i);
        PiecewiseBase & from_function =
            dynamic_cast<PiecewiseBase &>(from_problem.getFunction(from_name));
        transfer(from_function, to_function);
      }
  }
}

void
PiecewiseFunctionTransfer::transfer(PiecewiseBase & from_function, PiecewiseBase & to_function)
{
  std::size_t n = from_function.functionSize();
  std::vector<Real> x(n), y(n);
  for (std::size_t i = 0; i < n; ++i)
  {
    x[i] = from_function.domain(i);
    y[i] = from_function.range(i);
  }
  to_function.setData(x, y);
}
<commit_msg>Adapt transfers for compatibility with moose sibling multiapp transfers, refs idaholab/moose#19451<commit_after>// MOOSE includes
#include "FEProblemBase.h"
#include "MultiApp.h"
#include "PiecewiseBase.h"

// MASTODON includes
#include "PiecewiseFunctionTransfer.h"

registerMooseObject("MastodonApp", PiecewiseFunctionTransfer);

InputParameters
PiecewiseFunctionTransfer::validParams()
{
  InputParameters params = MultiAppTransfer::validParams();
  params.addClassDescription("Transfers from one Piecewise function to another.");

  params.addRequiredParam<std::string>("to_function",
                                       "The name of the function being transferred into.");

  params.addRequiredParam<std::string>("from_function",
                                       "The name of the function being transferred out of.");

  return params;
}

PiecewiseFunctionTransfer::PiecewiseFunctionTransfer(const InputParameters & parameters)
  : MultiAppTransfer(parameters)
{
}

void
PiecewiseFunctionTransfer::execute()
{
  const std::string & from_name = getParam<std::string>("from_function");
  const std::string & to_name = getParam<std::string>("to_function");

  if (_direction == TO_MULTIAPP)
  {
    FEProblemBase & from_problem = _to_multi_app->problemBase();
    PiecewiseBase & from_function =
        dynamic_cast<PiecewiseBase &>(from_problem.getFunction(from_name));
    for (unsigned int i = 0; i < _to_multi_app->numGlobalApps(); i++)
      if (_to_multi_app->hasLocalApp(i))
      {
        FEProblemBase & to_problem = getMultiApp()->appProblemBase(i);
        PiecewiseBase & to_function =
            dynamic_cast<PiecewiseBase &>(to_problem.getFunction(to_name));
        transfer(from_function, to_function);
      }
  }

  else if (_direction == FROM_MULTIAPP)
  {
    FEProblemBase & to_problem = _from_multi_app->problemBase();
    PiecewiseBase & to_function = dynamic_cast<PiecewiseBase &>(to_problem.getFunction(to_name));
    for (unsigned int i = 0; i < _from_multi_app->numGlobalApps(); i++)
      if (_from_multi_app->hasLocalApp(i))
      {
        FEProblemBase & from_problem = getMultiApp()->appProblemBase(i);
        PiecewiseBase & from_function =
            dynamic_cast<PiecewiseBase &>(from_problem.getFunction(from_name));
        transfer(from_function, to_function);
      }
  }
}

void
PiecewiseFunctionTransfer::transfer(PiecewiseBase & from_function, PiecewiseBase & to_function)
{
  std::size_t n = from_function.functionSize();
  std::vector<Real> x(n), y(n);
  for (std::size_t i = 0; i < n; ++i)
  {
    x[i] = from_function.domain(i);
    y[i] = from_function.range(i);
  }
  to_function.setData(x, y);
}
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS tbe15 (1.15.54); FILE MERGED 2004/12/17 12:29:40 sb 1.15.54.2: #i25819# Minor optimization. 2004/12/16 15:40:22 sb 1.15.54.1: #i25819# Flush instruction cache.<commit_after><|endoftext|>


<commit_before>#include "controller_node.h"
#include <std_msgs/Bool.h>
#include <std_srvs/Empty.h>
#include <iostream>

Controller::Controller() :
    speedX_(1.05f), speedY_(1.05f), speedZ_(1.05f), speedYaw_(1.01f), goal_reached_(true),
    search_for_plane_(false), stick_to_plane_(false), sticking_distance_(0.5f), correction_speed_(0.5f) {

    std::cout << "Controller node started..." << std::endl;

    // get Ros parameters and set variables
    nh_.param("speedForward", speedX_, speedX_);
    nh_.param("speedRight", speedY_, speedY_);
    nh_.param("speedUp", speedZ_, speedZ_);
    nh_.param("speedYaw", speedYaw_, speedYaw_);

    // set subscriber and publisher
    sub_joy_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10, &Controller::callback, this);
    sub_mocap_pose_ = nh_.subscribe<geometry_msgs::PoseWithCovarianceStamped>("vrpn_client/estimated_transform", 10, &Controller::setMocapPose, this);
    sub_plane_tf_ = nh_.subscribe<geometry_msgs::TransformStamped>("plane", 10, &Controller::processPlaneMsg, this);
    pub_pose_ = nh_.advertise<geometry_msgs::PoseStamped>("command/pose", 1);
    pub_stickToSurface_ = nh_.advertise<std_msgs::Bool>("stickToSurface", 10);

    std::cout << "speeds: " << speedX_ << " " << speedY_ << " " << speedZ_ << " " << speedYaw_ << std::endl;

    // identity rotation matrix as quaternion
    tf::Quaternion q;
    q.setRPY(0,0,0);

    // init mocap_tf
    mavToWorld_.setOrigin( tf::Vector3(0,0,0) );
    mavToWorld_.setRotation(q);

    // init transform
    transform_.setOrigin( tf::Vector3(0,0,0) );
    transform_.setRotation(q);

    // TBD if we should be able to change this via launch file
    // init hover transform
    hover_goal_tf_.setOrigin( tf::Vector3(0,0,1) );
    hover_goal_tf_.setRotation(q);

    // init plane_tf
    plane_tf_.setOrigin(tf::Vector3(2,0,0));
    tf::Quaternion plane_q;
    plane_q.setRPY(0,0,-M_PI/4.f);
    plane_tf_.setRotation(plane_q);

    // init snap_goal_tf
    snap_goal_tf_.setOrigin(tf::Vector3(0,0,0));
    snap_goal_tf_.setRotation(q);

    // set sensor offset tf by getting the relative offset
//    tf::TransformListener listener;
//    try {
//        listener.lookupTransform("euroc_hex/ground_truth", "euroc_hex/vi_sensor/ground_truth", ros::Time(0), sensor_offset_tf_);
//    } catch (tf::TransformException ex) {
//        ROS_ERROR("%s",ex.what());
//    }

    // hack
    tf::Transform mavToWorld;
    mavToWorld.setOrigin(tf::Vector3(0,0,0.117));
    mavToWorld.setRotation(tf::Quaternion(0,0,0,1));
    tf::Transform sensorToWorld;
    sensorToWorld.setOrigin(tf::Vector3(0.133,0,0.0605));
    sensorToWorld.setRotation(tf::Quaternion(0,0.17365,0,0.98481));
    sensorToMav_ = mavToWorld.inverse() * sensorToWorld;
}

void Controller::setMocapPose(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg) {
    mavToWorld_.setOrigin( tf::Vector3(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z) );
    mavToWorld_.setRotation( tf::Quaternion(msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z, msg->pose.pose.orientation.w) );

    if(!goal_reached_) {
        tf::Transform diff = mavToWorld_.inverse() * hover_goal_tf_;
        if(diff.getOrigin().length() < 0.05f) {
            goal_reached_ = true;
        }
        else {
            transform_ = diff;
        }
    }

    // world transform
    tf::Transform curr_transform;
    /// stick to plane
    if(stick_to_plane_) {
        testPlanes();
        tf::Vector3 diff = snap_goal_tf_.getOrigin() - mavToWorld_.getOrigin();
        curr_transform.setOrigin(mavToWorld_.getOrigin() + correction_speed_*diff);
        curr_transform.setRotation(snap_goal_tf_.getRotation());
    } else {
        curr_transform = mavToWorld_ * transform_;
    }

    // convert tf into pose and publish the pose
    tf::Vector3 desired_pos = curr_transform.getOrigin();
    tf::Quaternion desired_rot = curr_transform.getRotation();

    geometry_msgs::PoseStamped pose;
    // set header
    pose.header.stamp = ros::Time::now();
    pose.header.frame_id = "world";
    // set pose
    pose.pose.position.x = desired_pos.x();
    pose.pose.position.y = desired_pos.y();
    pose.pose.position.z = desired_pos.z();
    pose.pose.orientation.x = desired_rot.x();
    pose.pose.orientation.y = desired_rot.y();
    pose.pose.orientation.z = desired_rot.z();
    pose.pose.orientation.w = desired_rot.w();
    pub_pose_.publish(pose);

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(curr_transform, ros::Time::now(), "world", "controller") );
}

void Controller::callback(const sensor_msgs::Joy::ConstPtr& joy) {
    /// translation from controller axis
    float jx = speedX_ * joy->axes[PS3_AXIS_STICK_RIGHT_UPWARDS];
    float jy = speedY_ * joy->axes[PS3_AXIS_STICK_RIGHT_LEFTWARDS];
    float jz = speedZ_ * joy->axes[PS3_AXIS_STICK_LEFT_UPWARDS];
    // yaw from axis
    float jr = speedYaw_ * joy->axes[PS3_AXIS_STICK_LEFT_LEFTWARDS];

    // save only the latest relative transform in global variable transform_
    transform_.setOrigin( tf::Vector3(jx,jy,jz) );
    tf::Quaternion q;
    q.setRPY(0,0,jr);
    transform_.setRotation(q);

    /// buttons
    // tell PcMeshBuilder to search for a plane
    if(joy->buttons[PS3_BUTTON_REAR_RIGHT_1]) {
        search_for_plane_ = true;
        std_msgs::Bool sticking;
        sticking.data = search_for_plane_;
        pub_stickToSurface_.publish(sticking);
    }
    if(joy->buttons[PS3_BUTTON_REAR_LEFT_1]) {
        search_for_plane_ = false;
        std_msgs::Bool sticking;
        sticking.data = search_for_plane_;
        pub_stickToSurface_.publish(sticking);
    }
    // enable or disable sticking to the plane
    if(joy->buttons[PS3_BUTTON_REAR_RIGHT_2]) {
        stick_to_plane_ = true;
    }
    if(joy->buttons[PS3_BUTTON_REAR_LEFT_2]) {
        stick_to_plane_ = false;
    }
    // sticking distance
    if(joy->buttons[PS3_BUTTON_CROSS_UP] && sticking_distance_ > 0.05f) {
        sticking_distance_ -= 0.005f;
    }
    if(joy->buttons[PS3_BUTTON_CROSS_DOWN]) {
        sticking_distance_ += 0.005f;
    }
}

void Controller::takeoffAndHover() {
    std_srvs::Empty::Request request;
    std_srvs::Empty::Response response;
    ros::service::call("euroc2/takeoff", request, response);

    tf::Vector3 desired_pos = tf::Vector3( mavToWorld_.getOrigin().x(), mavToWorld_.getOrigin().y(), 1.0f);
    tf::Quaternion desired_rot = mavToWorld_.getRotation();

    hover_goal_tf_.setOrigin(desired_pos);
    hover_goal_tf_.setRotation(desired_rot);
}

// TODO add constant offset transform for camera
// TODO improve handedness correction
void Controller::processPlaneMsg(const geometry_msgs::TransformStamped::ConstPtr& msg) {
    // realtive plane transform to mav
    //planeToCam = plane_tf
    plane_tf_.setOrigin( tf::Vector3(msg->transform.translation.x, msg->transform.translation.y, msg->transform.translation.z) );
    plane_tf_.setRotation( tf::Quaternion(msg->transform.rotation.x, msg->transform.rotation.y, msg->transform.rotation.z, msg->transform.rotation.w) );

    //plane_tf_.setOrigin( tf::Vector3(0,0,0) ); //TODO rm debug
    //plane_tf_.setRotation( tf::Quaternion::getIdentity() );

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Cam_World") );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/vi_sensor/ground_truth", "plane_Cam") );

    // plane forward is z should be x, hack to fix it for testing
    //CamToSensor
//    tf::Matrix3x3 tmp_rot = tf::Matrix3x3(0,-1,0,0,0,-1,1,0,0);
    tf::Quaternion q1; q1.setRPY(0,M_PI/2.0,0);
    tf::Quaternion q2; q2.setRPY(-M_PI/2.0,0,0);
    tf::Quaternion correction_rot = q2*q1;
    plane_tf_.setOrigin( tf::Matrix3x3(correction_rot)*plane_tf_.getOrigin() );
    plane_tf_.setRotation( plane_tf_.getRotation() );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/vi_sensor/ground_truth", "plane_Sensor") );

    /// testing ///
////    tf::Quaternion q1; q1.setRPY(0,-M_PI/2.0,0);
////    tf::Quaternion q2; q2.setRPY(M_PI/2.0,0,0);
////    tf::Quaternion q3; q3.setRPY(0,0,M_PI);
//    tf::Quaternion q1; q1.setRPY(0,M_PI/2.0,0);
//    tf::Quaternion q2; q2.setRPY(-M_PI/2.0,0,0);
//    tf::Quaternion q3; q3.setRPY(0,0,0);
//    correction_rot = q3*q2*q1;
//    tf::Transform test0;
//    test0.setOrigin(tf::Vector3(-0.5,-0.5,1));
//    test0.setRotation(tf::Quaternion::getIdentity());
//    br_tf_.sendTransform( tf::StampedTransform(test0, ros::Time::now(), "world", "test0") );
//    tf::Transform test1;
//    test1.setOrigin( tf::Matrix3x3(correction_rot)*test0.getOrigin() );
//    test1.setRotation( test0.getRotation() );
//    br_tf_.sendTransform( tf::StampedTransform(test1, ros::Time::now(), "world", "test1") );
    /// end of testing section ///

    // correct the relative camera offset
    // planeToMav = plane_tf CORRECT
    plane_tf_ = sensorToMav_.inverse()*plane_tf_;

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Mav_World") );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/ground_truth", "plane_Mav") );

    // transform into global coordinates
    // planeToWorld = plane_tf_ CORRECT
    plane_tf_ = mavToWorld_*plane_tf_;
    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Global") );
}

// TODO remove hacks enhance methods
void Controller::testPlanes() {
    //// mav
    // predicted mav tf
    tf::Transform mav_tf = mavToWorld_ * transform_;

    // Eigen conversions
    Eigen::Vector3f mav_pos = Eigen::Vector3f( mav_tf.getOrigin().x(),
                                               mav_tf.getOrigin().y(),
                                               mav_tf.getOrigin().z());

    //// plane
    Eigen::Vector3f plane_pos = Eigen::Vector3f( plane_tf_.getOrigin().x(), plane_tf_.getOrigin().y(), plane_tf_.getOrigin().z() );
    tf::Quaternion plane_q = plane_tf_.getRotation();
    Eigen::Quaternionf plane_rot = Eigen::Quaternionf(plane_q.w(),plane_q.x(),plane_q.y(),plane_q.z());

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "normal") );

    //// calculations
    Eigen::Vector3f normal = plane_rot*forward;
    normal.normalize();
//    normal = -normal;
    // determine if mav is in front or behind plane normal, take current pos to avoid switching of sides by wrong predictions in mav_tf
    Eigen::Vector3f curr_pos = Eigen::Vector3f(mavToWorld_.getOrigin().x(), mavToWorld_.getOrigin().y(), mavToWorld_.getOrigin().z());

    int facing = normal.dot(curr_pos-plane_pos) >= 0 ? 1 : -1;
    // calculate projected position of the mav onto the plane
    Eigen::Vector3f proj_pos = mav_pos + (facing*sticking_distance_ - normal.dot(mav_pos-plane_pos))*normal;

    // another hack
//    tf::Quaternion correction_rot;
//    correction_rot.setRPY(0,0,M_PI);

    // set snapping goal tf
    snap_goal_tf_.setOrigin( tf::Vector3(proj_pos.x(), proj_pos.y(), proj_pos.z()) );
//    snap_goal_tf_.setRotation(correction_rot*plane_tf_.getRotation());
    snap_goal_tf_.setRotation(plane_tf_.getRotation());
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "te_joy_controller");
    Controller rc;
    ros::spin();
}
<commit_msg>Fixed a bug with the sensor offset.<commit_after>#include "controller_node.h"
#include <std_msgs/Bool.h>
#include <std_srvs/Empty.h>
#include <iostream>

Controller::Controller() :
    speedX_(1.05f), speedY_(1.05f), speedZ_(1.05f), speedYaw_(1.01f), goal_reached_(true),
    search_for_plane_(false), stick_to_plane_(false), sticking_distance_(0.5f), correction_speed_(0.5f) {

    std::cout << "Controller node started..." << std::endl;

    // get Ros parameters and set variables
    nh_.param("speedForward", speedX_, speedX_);
    nh_.param("speedRight", speedY_, speedY_);
    nh_.param("speedUp", speedZ_, speedZ_);
    nh_.param("speedYaw", speedYaw_, speedYaw_);

    // set subscriber and publisher
    sub_joy_ = nh_.subscribe<sensor_msgs::Joy>("joy", 10, &Controller::callback, this);
    sub_mocap_pose_ = nh_.subscribe<geometry_msgs::PoseWithCovarianceStamped>("vrpn_client/estimated_transform", 10, &Controller::setMocapPose, this);
    sub_plane_tf_ = nh_.subscribe<geometry_msgs::TransformStamped>("plane", 10, &Controller::processPlaneMsg, this);
    pub_pose_ = nh_.advertise<geometry_msgs::PoseStamped>("command/pose", 1);
    pub_stickToSurface_ = nh_.advertise<std_msgs::Bool>("stickToSurface", 10);

    std::cout << "speeds: " << speedX_ << " " << speedY_ << " " << speedZ_ << " " << speedYaw_ << std::endl;

    // identity rotation matrix as quaternion
    tf::Quaternion q;
    q.setRPY(0,0,0);

    // init mocap_tf
    mavToWorld_.setOrigin( tf::Vector3(0,0,0) );
    mavToWorld_.setRotation(q);

    // init transform
    transform_.setOrigin( tf::Vector3(0,0,0) );
    transform_.setRotation(q);

    // TBD if we should be able to change this via launch file
    // init hover transform
    hover_goal_tf_.setOrigin( tf::Vector3(0,0,1) );
    hover_goal_tf_.setRotation(q);

    // init plane_tf
    plane_tf_.setOrigin(tf::Vector3(2,0,0));
    tf::Quaternion plane_q;
    plane_q.setRPY(0,0,-M_PI/4.f);
    plane_tf_.setRotation(plane_q);

    // init snap_goal_tf
    snap_goal_tf_.setOrigin(tf::Vector3(0,0,0));
    snap_goal_tf_.setRotation(q);

    // set sensor offset tf by getting the relative offset
//    tf::TransformListener listener;
//    try {
//        listener.lookupTransform("euroc_hex/ground_truth", "euroc_hex/vi_sensor/ground_truth", ros::Time(0), sensor_offset_tf_);
//    } catch (tf::TransformException ex) {
//        ROS_ERROR("%s",ex.what());
//    }

    // hack
    tf::Transform mavToWorld;
    mavToWorld.setOrigin(tf::Vector3(0,0,0.117));
    mavToWorld.setRotation(tf::Quaternion(0,0,0,1));
    tf::Transform sensorToWorld;
    sensorToWorld.setOrigin(tf::Vector3(0.133,0,0.0605));
    sensorToWorld.setRotation(tf::Quaternion(0,0.17365,0,0.98481));
    sensorToMav_ = mavToWorld.inverse() * sensorToWorld;
}

void Controller::setMocapPose(const geometry_msgs::PoseWithCovarianceStamped::ConstPtr& msg) {
    mavToWorld_.setOrigin( tf::Vector3(msg->pose.pose.position.x, msg->pose.pose.position.y, msg->pose.pose.position.z) );
    mavToWorld_.setRotation( tf::Quaternion(msg->pose.pose.orientation.x, msg->pose.pose.orientation.y, msg->pose.pose.orientation.z, msg->pose.pose.orientation.w) );

    if(!goal_reached_) {
        tf::Transform diff = mavToWorld_.inverse() * hover_goal_tf_;
        if(diff.getOrigin().length() < 0.05f) {
            goal_reached_ = true;
        }
        else {
            transform_ = diff;
        }
    }

    // world transform
    tf::Transform curr_transform;
    /// stick to plane
    if(stick_to_plane_) {
        testPlanes();
        tf::Vector3 diff = snap_goal_tf_.getOrigin() - mavToWorld_.getOrigin();
        curr_transform.setOrigin(mavToWorld_.getOrigin() + correction_speed_*diff);
        curr_transform.setRotation(snap_goal_tf_.getRotation());
    } else {
        curr_transform = mavToWorld_ * transform_;
    }

    // convert tf into pose and publish the pose
    tf::Vector3 desired_pos = curr_transform.getOrigin();
    tf::Quaternion desired_rot = curr_transform.getRotation();

    geometry_msgs::PoseStamped pose;
    // set header
    pose.header.stamp = ros::Time::now();
    pose.header.frame_id = "world";
    // set pose
    pose.pose.position.x = desired_pos.x();
    pose.pose.position.y = desired_pos.y();
    pose.pose.position.z = desired_pos.z();
    pose.pose.orientation.x = desired_rot.x();
    pose.pose.orientation.y = desired_rot.y();
    pose.pose.orientation.z = desired_rot.z();
    pose.pose.orientation.w = desired_rot.w();
    pub_pose_.publish(pose);

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(curr_transform, ros::Time::now(), "world", "controller") );
}

void Controller::callback(const sensor_msgs::Joy::ConstPtr& joy) {
    /// translation from controller axis
    float jx = speedX_ * joy->axes[PS3_AXIS_STICK_RIGHT_UPWARDS];
    float jy = speedY_ * joy->axes[PS3_AXIS_STICK_RIGHT_LEFTWARDS];
    float jz = speedZ_ * joy->axes[PS3_AXIS_STICK_LEFT_UPWARDS];
    // yaw from axis
    float jr = speedYaw_ * joy->axes[PS3_AXIS_STICK_LEFT_LEFTWARDS];

    // save only the latest relative transform in global variable transform_
    transform_.setOrigin( tf::Vector3(jx,jy,jz) );
    tf::Quaternion q;
    q.setRPY(0,0,jr);
    transform_.setRotation(q);

    /// buttons
    // tell PcMeshBuilder to search for a plane
    if(joy->buttons[PS3_BUTTON_REAR_RIGHT_1]) {
        search_for_plane_ = true;
        std_msgs::Bool sticking;
        sticking.data = search_for_plane_;
        pub_stickToSurface_.publish(sticking);
    }
    if(joy->buttons[PS3_BUTTON_REAR_LEFT_1]) {
        search_for_plane_ = false;
        std_msgs::Bool sticking;
        sticking.data = search_for_plane_;
        pub_stickToSurface_.publish(sticking);
    }
    // enable or disable sticking to the plane
    if(joy->buttons[PS3_BUTTON_REAR_RIGHT_2]) {
        stick_to_plane_ = true;
    }
    if(joy->buttons[PS3_BUTTON_REAR_LEFT_2]) {
        stick_to_plane_ = false;
    }
    // sticking distance
    if(joy->buttons[PS3_BUTTON_CROSS_UP] && sticking_distance_ > 0.05f) {
        sticking_distance_ -= 0.005f;
    }
    if(joy->buttons[PS3_BUTTON_CROSS_DOWN]) {
        sticking_distance_ += 0.005f;
    }
}

void Controller::takeoffAndHover() {
    std_srvs::Empty::Request request;
    std_srvs::Empty::Response response;
    ros::service::call("euroc2/takeoff", request, response);

    tf::Vector3 desired_pos = tf::Vector3( mavToWorld_.getOrigin().x(), mavToWorld_.getOrigin().y(), 1.0f);
    tf::Quaternion desired_rot = mavToWorld_.getRotation();

    hover_goal_tf_.setOrigin(desired_pos);
    hover_goal_tf_.setRotation(desired_rot);
}

// TODO add constant offset transform for camera
// TODO improve handedness correction
void Controller::processPlaneMsg(const geometry_msgs::TransformStamped::ConstPtr& msg) {
    // realtive plane transform to mav
    //planeToCam = plane_tf
    plane_tf_.setOrigin( tf::Vector3(msg->transform.translation.x, msg->transform.translation.y, msg->transform.translation.z) );
    plane_tf_.setRotation( tf::Quaternion(msg->transform.rotation.x, msg->transform.rotation.y, msg->transform.rotation.z, msg->transform.rotation.w) );

    //plane_tf_.setOrigin( tf::Vector3(0,0,0) ); //TODO rm debug
    //plane_tf_.setRotation( tf::Quaternion::getIdentity() );

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Cam_World") );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/vi_sensor/ground_truth", "plane_Cam") );

    // plane forward is z should be x, hack to fix it for testing
    //CamToSensor
//    tf::Matrix3x3 tmp_rot = tf::Matrix3x3(0,-1,0,0,0,-1,1,0,0);
    tf::Quaternion q1; q1.setRPY(0,M_PI/2.0,0);
    tf::Quaternion q2; q2.setRPY(-M_PI/2.0,0,0);
    tf::Quaternion correction_rot = q2*q1;
    plane_tf_.setOrigin( tf::Matrix3x3(correction_rot)*plane_tf_.getOrigin() );
    plane_tf_.setRotation( plane_tf_.getRotation() );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/vi_sensor/ground_truth", "plane_Sensor") );

    /// testing ///
////    tf::Quaternion q1; q1.setRPY(0,-M_PI/2.0,0);
////    tf::Quaternion q2; q2.setRPY(M_PI/2.0,0,0);
////    tf::Quaternion q3; q3.setRPY(0,0,M_PI);
//    tf::Quaternion q1; q1.setRPY(0,M_PI/2.0,0);
//    tf::Quaternion q2; q2.setRPY(-M_PI/2.0,0,0);
//    tf::Quaternion q3; q3.setRPY(0,0,0);
//    correction_rot = q3*q2*q1;
//    tf::Transform test0;
//    test0.setOrigin(tf::Vector3(-0.5,-0.5,1));
//    test0.setRotation(tf::Quaternion::getIdentity());
//    br_tf_.sendTransform( tf::StampedTransform(test0, ros::Time::now(), "world", "test0") );
//    tf::Transform test1;
//    test1.setOrigin( tf::Matrix3x3(correction_rot)*test0.getOrigin() );
//    test1.setRotation( test0.getRotation() );
//    br_tf_.sendTransform( tf::StampedTransform(test1, ros::Time::now(), "world", "test1") );
    /// end of testing section ///

    // correct the relative camera offset
    // planeToMav = plane_tf CORRECT
    plane_tf_ = sensorToMav_*plane_tf_;

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Mav_World") );
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "euroc_hex/ground_truth", "plane_Mav") );

    // transform into global coordinates
    // planeToWorld = plane_tf_ CORRECT
    plane_tf_ = mavToWorld_*plane_tf_;
    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "plane_Global") );
}

// TODO remove hacks enhance methods
void Controller::testPlanes() {
    //// mav
    // predicted mav tf
    tf::Transform mav_tf = mavToWorld_ * transform_;

    // Eigen conversions
    Eigen::Vector3f mav_pos = Eigen::Vector3f( mav_tf.getOrigin().x(),
                                               mav_tf.getOrigin().y(),
                                               mav_tf.getOrigin().z());

    //// plane
    Eigen::Vector3f plane_pos = Eigen::Vector3f( plane_tf_.getOrigin().x(), plane_tf_.getOrigin().y(), plane_tf_.getOrigin().z() );
    tf::Quaternion plane_q = plane_tf_.getRotation();
    Eigen::Quaternionf plane_rot = Eigen::Quaternionf(plane_q.w(),plane_q.x(),plane_q.y(),plane_q.z());

    // rviz debug
    br_tf_.sendTransform( tf::StampedTransform(plane_tf_, ros::Time::now(), "world", "normal") );

    //// calculations
    Eigen::Vector3f normal = plane_rot*forward;
    normal.normalize();
//    normal = -normal;
    // determine if mav is in front or behind plane normal, take current pos to avoid switching of sides by wrong predictions in mav_tf
    Eigen::Vector3f curr_pos = Eigen::Vector3f(mavToWorld_.getOrigin().x(), mavToWorld_.getOrigin().y(), mavToWorld_.getOrigin().z());

    int facing = normal.dot(curr_pos-plane_pos) >= 0 ? 1 : -1;
    // calculate projected position of the mav onto the plane
    Eigen::Vector3f proj_pos = mav_pos + (facing*sticking_distance_ - normal.dot(mav_pos-plane_pos))*normal;

    // another hack
//    tf::Quaternion correction_rot;
//    correction_rot.setRPY(0,0,M_PI);

    // set snapping goal tf
    snap_goal_tf_.setOrigin( tf::Vector3(proj_pos.x(), proj_pos.y(), proj_pos.z()) );
//    snap_goal_tf_.setRotation(correction_rot*plane_tf_.getRotation());
    snap_goal_tf_.setRotation(plane_tf_.getRotation());
}

int main(int argc, char** argv) {
    ros::init(argc, argv, "te_joy_controller");
    Controller rc;
    ros::spin();
}
<|endoftext|>


<commit_before>/*
* Copyright (c) 2003-2009 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/
// OptionsPasswordHistory.cpp : implementation file
//

#include "stdafx.h"
#include "passwordsafe.h"
#include "corelib/PwsPlatform.h"

#if defined(POCKET_PC)
#include "pocketpc/resource.h"
#else
#include "resource.h"
#include "resource3.h"  // String resources
#endif
#include "OptionsPasswordHistory.h"
#include "DboxMain.h"  // needed for DboxMain::UpdatePasswordHistory

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COptionsPasswordHistory property page

IMPLEMENT_DYNCREATE(COptionsPasswordHistory, CPWPropertyPage)

COptionsPasswordHistory::COptionsPasswordHistory()
  : CPWPropertyPage(COptionsPasswordHistory::IDD)
{
  //{{AFX_DATA_INIT(COptionsPasswordHistory)
  //}}AFX_DATA_INIT
  m_ToolTipCtrl = NULL;
  m_pwhaction = 0;
}

COptionsPasswordHistory::~COptionsPasswordHistory()
{
  delete m_ToolTipCtrl;
}

void COptionsPasswordHistory::DoDataExchange(CDataExchange* pDX)
{
  CPWPropertyPage::DoDataExchange(pDX);

  //{{AFX_DATA_MAP(COptionsPasswordHistory)
  DDX_Check(pDX, IDC_SAVEPWHISTORY, m_savepwhistory);
  DDX_Text(pDX, IDC_DEFPWHNUM, m_pwhistorynumdefault);
  //}}AFX_DATA_MAP
  DDX_Radio(pDX, IDC_PWHISTORYNOACTION, m_pwhaction);
}

BEGIN_MESSAGE_MAP(COptionsPasswordHistory, CPWPropertyPage)
  //{{AFX_MSG_MAP(COptionsPasswordHistory)
  ON_BN_CLICKED(IDC_SAVEPWHISTORY, OnSavePWHistory)
  ON_BN_CLICKED(IDC_APPLYPWHCHANGESNOW, OnApplyPWHChanges)
  //}}AFX_MSG_MAP
  ON_BN_CLICKED(IDC_PWHISTORYNOACTION, OnPWHistoryNoAction)
  ON_BN_CLICKED(IDC_RESETPWHISTORYOFF, OnPWHistoryDoAction)
  ON_BN_CLICKED(IDC_RESETPWHISTORYON, OnPWHistoryDoAction)
  ON_BN_CLICKED(IDC_SETMAXPWHISTORY, OnPWHistoryDoAction)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COptionsPasswordHistory message handlers

BOOL COptionsPasswordHistory::OnInitDialog()
{
  BOOL bResult = CPWPropertyPage::OnInitDialog();

  CSpinButtonCtrl* pspin = (CSpinButtonCtrl *)GetDlgItem(IDC_PWHSPIN);

  pspin->SetBuddy(GetDlgItem(IDC_DEFPWHNUM));
  pspin->SetRange(1, 255);
  pspin->SetBase(10);
  pspin->SetPos(m_pwhistorynumdefault);

  // Tooltips on Property Pages
  EnableToolTips();

  m_ToolTipCtrl = new CToolTipCtrl;
  if (!m_ToolTipCtrl->Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX)) {
    TRACE("Unable To create Property Page ToolTip\n");
    return bResult;
  }

  // Activate the tooltip control.
  m_ToolTipCtrl->Activate(TRUE);
  m_ToolTipCtrl->SetMaxTipWidth(300);
  // Quadruple the time to allow reading by user - there is a lot there!
  int iTime = m_ToolTipCtrl->GetDelayTime(TTDT_AUTOPOP);
  m_ToolTipCtrl->SetDelayTime(TTDT_AUTOPOP, 4 * iTime);

  // Set the tooltip
  // Note naming convention: string IDS_xxx corresponds to control IDC_xxx
  CString cs_ToolTip;
  cs_ToolTip.LoadString(IDS_RESETPWHISTORYOFF);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_RESETPWHISTORYOFF), cs_ToolTip);
  cs_ToolTip.LoadString(IDS_RESETPWHISTORYON);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_RESETPWHISTORYON), cs_ToolTip);
  cs_ToolTip.LoadString(IDS_SETMAXPWHISTORY);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_SETMAXPWHISTORY), cs_ToolTip);

  return TRUE;  // return TRUE unless you set the focus to a control
  // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL COptionsPasswordHistory::OnKillActive()
{
  CPWPropertyPage::OnKillActive();

  // Check that options, as set, are valid.
  if (m_savepwhistory && ((m_pwhistorynumdefault < 1) || (m_pwhistorynumdefault > 255))) {
    AfxMessageBox(IDS_DEFAULTNUMPWH);
    ((CEdit*)GetDlgItem(IDC_DEFPWHNUM))->SetFocus();
    return FALSE;
  }

  //End check

  return TRUE;
}

void COptionsPasswordHistory::OnSavePWHistory()
{
  BOOL enable = (((CButton*)GetDlgItem(IDC_SAVEPWHISTORY))->GetCheck() == 1) ? TRUE : FALSE;
  GetDlgItem(IDC_PWHSPIN)->EnableWindow(enable);
  GetDlgItem(IDC_DEFPWHNUM)->EnableWindow(enable);
}

void COptionsPasswordHistory::OnApplyPWHChanges()
{
  ASSERT(m_pDboxMain != NULL);

  UpdateData(TRUE);
  m_pDboxMain->UpdatePasswordHistory(m_pwhaction, m_pwhistorynumdefault);

  m_pwhaction = 0;
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(FALSE);
  UpdateData(FALSE);
}

// Override PreTranslateMessage() so RelayEvent() can be
// called to pass a mouse message to CPWSOptions's
// tooltip control for processing.
BOOL COptionsPasswordHistory::PreTranslateMessage(MSG* pMsg)
{
  if (m_ToolTipCtrl != NULL)
    m_ToolTipCtrl->RelayEvent(pMsg);

  return CPWPropertyPage::PreTranslateMessage(pMsg);
}

void COptionsPasswordHistory::OnPWHistoryNoAction()
{
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(FALSE);
}

void COptionsPasswordHistory::OnPWHistoryDoAction()
{
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(TRUE);
}
<commit_msg>Fix initial status of number of saved passwords edit control<commit_after>/*
* Copyright (c) 2003-2009 Rony Shapiro <ronys@users.sourceforge.net>.
* All rights reserved. Use of the code is allowed under the
* Artistic License 2.0 terms, as specified in the LICENSE file
* distributed with this code, or available from
* http://www.opensource.org/licenses/artistic-license-2.0.php
*/
// OptionsPasswordHistory.cpp : implementation file
//

#include "stdafx.h"
#include "passwordsafe.h"
#include "corelib/PwsPlatform.h"

#if defined(POCKET_PC)
#include "pocketpc/resource.h"
#else
#include "resource.h"
#include "resource3.h"  // String resources
#endif
#include "OptionsPasswordHistory.h"
#include "DboxMain.h"  // needed for DboxMain::UpdatePasswordHistory

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// COptionsPasswordHistory property page

IMPLEMENT_DYNCREATE(COptionsPasswordHistory, CPWPropertyPage)

COptionsPasswordHistory::COptionsPasswordHistory()
  : CPWPropertyPage(COptionsPasswordHistory::IDD)
{
  //{{AFX_DATA_INIT(COptionsPasswordHistory)
  //}}AFX_DATA_INIT
  m_ToolTipCtrl = NULL;
  m_pwhaction = 0;
}

COptionsPasswordHistory::~COptionsPasswordHistory()
{
  delete m_ToolTipCtrl;
}

void COptionsPasswordHistory::DoDataExchange(CDataExchange* pDX)
{
  CPWPropertyPage::DoDataExchange(pDX);

  //{{AFX_DATA_MAP(COptionsPasswordHistory)
  DDX_Check(pDX, IDC_SAVEPWHISTORY, m_savepwhistory);
  DDX_Text(pDX, IDC_DEFPWHNUM, m_pwhistorynumdefault);
  //}}AFX_DATA_MAP
  DDX_Radio(pDX, IDC_PWHISTORYNOACTION, m_pwhaction);
}

BEGIN_MESSAGE_MAP(COptionsPasswordHistory, CPWPropertyPage)
  //{{AFX_MSG_MAP(COptionsPasswordHistory)
  ON_BN_CLICKED(IDC_SAVEPWHISTORY, OnSavePWHistory)
  ON_BN_CLICKED(IDC_APPLYPWHCHANGESNOW, OnApplyPWHChanges)
  //}}AFX_MSG_MAP
  ON_BN_CLICKED(IDC_PWHISTORYNOACTION, OnPWHistoryNoAction)
  ON_BN_CLICKED(IDC_RESETPWHISTORYOFF, OnPWHistoryDoAction)
  ON_BN_CLICKED(IDC_RESETPWHISTORYON, OnPWHistoryDoAction)
  ON_BN_CLICKED(IDC_SETMAXPWHISTORY, OnPWHistoryDoAction)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// COptionsPasswordHistory message handlers

BOOL COptionsPasswordHistory::OnInitDialog()
{
  BOOL bResult = CPWPropertyPage::OnInitDialog();

  CSpinButtonCtrl* pspin = (CSpinButtonCtrl *)GetDlgItem(IDC_PWHSPIN);

  pspin->SetBuddy(GetDlgItem(IDC_DEFPWHNUM));
  pspin->SetRange(1, 255);
  pspin->SetBase(10);
  pspin->SetPos(m_pwhistorynumdefault);

  GetDlgItem(IDC_PWHSPIN)->EnableWindow(m_savepwhistory);
  GetDlgItem(IDC_DEFPWHNUM)->EnableWindow(m_savepwhistory);

  // Tooltips on Property Pages
  EnableToolTips();

  m_ToolTipCtrl = new CToolTipCtrl;
  if (!m_ToolTipCtrl->Create(this, TTS_ALWAYSTIP | TTS_BALLOON | TTS_NOPREFIX)) {
    TRACE("Unable To create Property Page ToolTip\n");
    return bResult;
  }

  // Activate the tooltip control.
  m_ToolTipCtrl->Activate(TRUE);
  m_ToolTipCtrl->SetMaxTipWidth(300);
  // Quadruple the time to allow reading by user - there is a lot there!
  int iTime = m_ToolTipCtrl->GetDelayTime(TTDT_AUTOPOP);
  m_ToolTipCtrl->SetDelayTime(TTDT_AUTOPOP, 4 * iTime);

  // Set the tooltip
  // Note naming convention: string IDS_xxx corresponds to control IDC_xxx
  CString cs_ToolTip;
  cs_ToolTip.LoadString(IDS_RESETPWHISTORYOFF);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_RESETPWHISTORYOFF), cs_ToolTip);
  cs_ToolTip.LoadString(IDS_RESETPWHISTORYON);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_RESETPWHISTORYON), cs_ToolTip);
  cs_ToolTip.LoadString(IDS_SETMAXPWHISTORY);
  m_ToolTipCtrl->AddTool(GetDlgItem(IDC_SETMAXPWHISTORY), cs_ToolTip);

  return TRUE;  // return TRUE unless you set the focus to a control
  // EXCEPTION: OCX Property Pages should return FALSE
}

BOOL COptionsPasswordHistory::OnKillActive()
{
  CPWPropertyPage::OnKillActive();

  // Check that options, as set, are valid.
  if (m_savepwhistory && ((m_pwhistorynumdefault < 1) || (m_pwhistorynumdefault > 255))) {
    AfxMessageBox(IDS_DEFAULTNUMPWH);
    ((CEdit*)GetDlgItem(IDC_DEFPWHNUM))->SetFocus();
    return FALSE;
  }

  //End check

  return TRUE;
}

void COptionsPasswordHistory::OnSavePWHistory()
{
  BOOL enable = (((CButton*)GetDlgItem(IDC_SAVEPWHISTORY))->GetCheck() == 1) ? TRUE : FALSE;
  GetDlgItem(IDC_PWHSPIN)->EnableWindow(enable);
  GetDlgItem(IDC_DEFPWHNUM)->EnableWindow(enable);
}

void COptionsPasswordHistory::OnApplyPWHChanges()
{
  ASSERT(m_pDboxMain != NULL);

  UpdateData(TRUE);
  m_pDboxMain->UpdatePasswordHistory(m_pwhaction, m_pwhistorynumdefault);

  m_pwhaction = 0;
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(FALSE);
  UpdateData(FALSE);
}

// Override PreTranslateMessage() so RelayEvent() can be
// called to pass a mouse message to CPWSOptions's
// tooltip control for processing.
BOOL COptionsPasswordHistory::PreTranslateMessage(MSG* pMsg)
{
  if (m_ToolTipCtrl != NULL)
    m_ToolTipCtrl->RelayEvent(pMsg);

  return CPWPropertyPage::PreTranslateMessage(pMsg);
}

void COptionsPasswordHistory::OnPWHistoryNoAction()
{
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(FALSE);
}

void COptionsPasswordHistory::OnPWHistoryDoAction()
{
  GetDlgItem(IDC_APPLYPWHCHANGESNOW)->EnableWindow(TRUE);
}
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////////////
///                                                                          ///
/// AliFemtoModelCorrFctnDirectYlm - the class for correlation function which   ///
/// uses the model framework and weight generation and saves the generated   ///
/// emission source                                                          ///
/// Authors: Adam Kisiel, kisiel@mps.ohio-state.edu                          ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////
#ifdef __ROOT__
  ClassImp(AliFemtoModelCorrFctnDirectYlm, 1)
#endif

#include "AliFemtoModelGausLCMSFreezeOutGenerator.h"
#include "AliFemtoModelHiddenInfo.h"
#include "AliFemtoModelCorrFctnDirectYlm.h"

//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm():
  AliFemtoModelCorrFctn(),
  fCYlmTrue(0),
  fCYlmFake(0),
  fUseLCMS(0)
{
  // default constructor

  fCYlmTrue = new AliFemtoCorrFctnDirectYlm();
  fCYlmFake = new AliFemtoCorrFctnDirectYlm();
  fCYlmTrue->SetUseLCMS(fUseLCMS);
  fCYlmFake->SetUseLCMS(fUseLCMS);
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm(const char *title, Int_t aMaxL, Int_t aNbins, Double_t aQinvLo, Double_t aQinvHi, int aUseLCMS=0):
  AliFemtoModelCorrFctn(title, aNbins, aQinvLo, aQinvHi),
  fCYlmTrue(0),
  fCYlmFake(0),
  fUseLCMS(aUseLCMS)
{
  // basic constructor
  char fname[1000];
  snprintf(fname, 1000, "%s%s", title, "True");
  fCYlmTrue = new AliFemtoCorrFctnDirectYlm(fname, aMaxL, aNbins, aQinvLo, aQinvHi, fUseLCMS);
  snprintf(fname, 1000, "%s%s", title, "Fake");
  fCYlmFake = new AliFemtoCorrFctnDirectYlm(fname, aMaxL, aNbins, aQinvLo, aQinvHi, fUseLCMS);
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm(const AliFemtoModelCorrFctnDirectYlm& aCorrFctn):
  AliFemtoModelCorrFctn(aCorrFctn),
  fCYlmTrue(new AliFemtoCorrFctnDirectYlm(*(aCorrFctn.fCYlmTrue))),
  fCYlmFake(new AliFemtoCorrFctnDirectYlm(*(aCorrFctn.fCYlmFake))),
  fUseLCMS(0)
{
  // copy constructor
  fUseLCMS = aCorrFctn.fUseLCMS;
//   fCYlmTrue = dynamic_cast<AliFemtoCorrFctnDirectYlm*>(aCorrFctn.fCYlmTrue->Clone());
//   fCYlmFake = dynamic_cast<AliFemtoCorrFctnDirectYlm*>(aCorrFctn.fCYlmFake->Clone());
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::~AliFemtoModelCorrFctnDirectYlm()
{
  // destructor
  if (fCYlmTrue) delete fCYlmTrue;
  if (fCYlmFake) delete fCYlmFake;
  if (fNumeratorTrue) delete fNumeratorTrue;
  if (fNumeratorFake) delete fNumeratorFake;
  if (fDenominator) delete fDenominator;
}

//_______________________
AliFemtoModelCorrFctnDirectYlm& AliFemtoModelCorrFctnDirectYlm::operator=(const AliFemtoModelCorrFctnDirectYlm& aCorrFctn)
{
  // assignment operator
  if (this == &aCorrFctn)
    return *this;

  fUseLCMS = aCorrFctn.fUseLCMS;

  if (aCorrFctn.fCYlmTrue)
    fCYlmTrue = new AliFemtoCorrFctnDirectYlm(*aCorrFctn.fCYlmTrue);
  else fCYlmTrue = 0;

  if (aCorrFctn.fCYlmFake)
    fCYlmFake = new AliFemtoCorrFctnDirectYlm(*aCorrFctn.fCYlmFake);
  else fCYlmFake = 0;

  if (aCorrFctn.fNumeratorTrue)
    fNumeratorTrue = new TH1D(*aCorrFctn.fNumeratorTrue);
  else
    fNumeratorTrue = 0;

  if (aCorrFctn.fNumeratorFake)
    fNumeratorFake = new TH1D(*aCorrFctn.fNumeratorFake);
  else
    fNumeratorFake = 0;

  if (aCorrFctn.fDenominator)
    fDenominator = new TH1D(*aCorrFctn.fDenominator);
  else
    fDenominator = 0;

  return *this;
}
//_______________________
AliFemtoString AliFemtoModelCorrFctnDirectYlm::Report()
{
  // construct report
  AliFemtoString tStr = "AliFemtoModelCorrFctnDirectYlm report";

  return tStr;
}

//_______________________
void AliFemtoModelCorrFctnDirectYlm::AddRealPair(AliFemtoPair* aPair)
{
  // add real (effect) pair
  if (fPairCut)
    if (!(fPairCut->Pass(aPair))) return;

  Double_t weight = fManager->GetWeight(aPair);

  if (fUseLCMS)
    fCYlmTrue->AddRealPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), weight);
  else
    fCYlmTrue->AddRealPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), weight);
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::AddMixedPair(AliFemtoPair* aPair)
{
  // add mixed (background) pair
  if (fPairCut)
    if (!(fPairCut->Pass(aPair))) return;

  Double_t weight = fManager->GetWeight(aPair);

  if (fUseLCMS) {
    fCYlmTrue->AddMixedPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
    fCYlmFake->AddRealPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), weight);
    fCYlmFake->AddMixedPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
  }
  else {
    fCYlmTrue->AddMixedPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
    fCYlmFake->AddRealPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), weight);
    fCYlmFake->AddMixedPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
  }
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::Write()
{
  // write out all the histograms

  fCYlmTrue->Write();
  fCYlmFake->Write();
}
//_______________________
TList* AliFemtoModelCorrFctnDirectYlm::GetOutputList()
{
  // Prepare the list of objects to be written to the output
  TList *tOutputList = AliFemtoModelCorrFctn::GetOutputList();
  tOutputList->Clear();

  TList *tListCfTrue = fCYlmTrue->GetOutputList();

  TIter nextListCfTrue(tListCfTrue);
  while (TObject *obj = nextListCfTrue()) {
    tOutputList->Add(obj);
  }

  TList *tListCfFake = fCYlmFake->GetOutputList();

  TIter nextListCfFake(tListCfFake);
  while (TObject *obj = nextListCfFake()) {
    tOutputList->Add(obj);
  }
//   tOutputList->Add(fCYlmTrue->GetOutputList());
//   tOutputList->Add(fCYlmFake->GetOutputList());

  return tOutputList;
}
//_______________________
AliFemtoModelCorrFctn* AliFemtoModelCorrFctnDirectYlm::Clone()
{
  // Clone the correlation function
  AliFemtoModelCorrFctnDirectYlm *tCopy = new AliFemtoModelCorrFctnDirectYlm(*this);

  return tCopy;
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::Finish()
{
  fCYlmTrue->Finish();
  fCYlmFake->Finish();
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::SetUseLCMS(int aUseLCMS)
{
  fUseLCMS = aUseLCMS;
  fCYlmTrue->SetUseLCMS(fUseLCMS);
  fCYlmFake->SetUseLCMS(fUseLCMS);
}
//_______________________
int  AliFemtoModelCorrFctnDirectYlm::GetUseLCMS()
{
  return fUseLCMS;
}

<commit_msg>Fix Coverity<commit_after>////////////////////////////////////////////////////////////////////////////////
///                                                                          ///
/// AliFemtoModelCorrFctnDirectYlm - the class for correlation function which   ///
/// uses the model framework and weight generation and saves the generated   ///
/// emission source                                                          ///
/// Authors: Adam Kisiel, kisiel@mps.ohio-state.edu                          ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////
#ifdef __ROOT__
  ClassImp(AliFemtoModelCorrFctnDirectYlm, 1)
#endif

#include "AliFemtoModelGausLCMSFreezeOutGenerator.h"
#include "AliFemtoModelHiddenInfo.h"
#include "AliFemtoModelCorrFctnDirectYlm.h"

//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm():
  AliFemtoModelCorrFctn(),
  fCYlmTrue(0),
  fCYlmFake(0),
  fUseLCMS(0)
{
  // default constructor

  fCYlmTrue = new AliFemtoCorrFctnDirectYlm();
  fCYlmFake = new AliFemtoCorrFctnDirectYlm();
  fCYlmTrue->SetUseLCMS(fUseLCMS);
  fCYlmFake->SetUseLCMS(fUseLCMS);
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm(const char *title, Int_t aMaxL, Int_t aNbins, Double_t aQinvLo, Double_t aQinvHi, int aUseLCMS=0):
  AliFemtoModelCorrFctn(title, aNbins, aQinvLo, aQinvHi),
  fCYlmTrue(0),
  fCYlmFake(0),
  fUseLCMS(aUseLCMS)
{
  // basic constructor
  char fname[1000];
  snprintf(fname, 1000, "%s%s", title, "True");
  fCYlmTrue = new AliFemtoCorrFctnDirectYlm(fname, aMaxL, aNbins, aQinvLo, aQinvHi, fUseLCMS);
  snprintf(fname, 1000, "%s%s", title, "Fake");
  fCYlmFake = new AliFemtoCorrFctnDirectYlm(fname, aMaxL, aNbins, aQinvLo, aQinvHi, fUseLCMS);
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::AliFemtoModelCorrFctnDirectYlm(const AliFemtoModelCorrFctnDirectYlm& aCorrFctn):
  AliFemtoModelCorrFctn(aCorrFctn),
  fCYlmTrue(new AliFemtoCorrFctnDirectYlm(*(aCorrFctn.fCYlmTrue))),
  fCYlmFake(new AliFemtoCorrFctnDirectYlm(*(aCorrFctn.fCYlmFake))),
  fUseLCMS(0)
{
  // copy constructor
  fUseLCMS = aCorrFctn.fUseLCMS;
//   fCYlmTrue = dynamic_cast<AliFemtoCorrFctnDirectYlm*>(aCorrFctn.fCYlmTrue->Clone());
//   fCYlmFake = dynamic_cast<AliFemtoCorrFctnDirectYlm*>(aCorrFctn.fCYlmFake->Clone());
}
//_______________________
AliFemtoModelCorrFctnDirectYlm::~AliFemtoModelCorrFctnDirectYlm()
{
  // destructor
  if (fCYlmTrue) delete fCYlmTrue;
  if (fCYlmFake) delete fCYlmFake;
  if (fNumeratorTrue) delete fNumeratorTrue;
  if (fNumeratorFake) delete fNumeratorFake;
  if (fDenominator) delete fDenominator;
}

//_______________________
AliFemtoModelCorrFctnDirectYlm& AliFemtoModelCorrFctnDirectYlm::operator=(const AliFemtoModelCorrFctnDirectYlm& aCorrFctn)
{
  // assignment operator
  if (this != &aCorrFctn) {

    fUseLCMS = aCorrFctn.fUseLCMS;

    if (fCYlmTrue) delete fCYlmTrue;
    if (aCorrFctn.fCYlmTrue)
      fCYlmTrue = new AliFemtoCorrFctnDirectYlm(*aCorrFctn.fCYlmTrue);
    else fCYlmTrue = 0;

    if (fCYlmFake) delete fCYlmFake;
    if (aCorrFctn.fCYlmFake)
      fCYlmFake = new AliFemtoCorrFctnDirectYlm(*aCorrFctn.fCYlmFake);
    else fCYlmFake = 0;

    if (fNumeratorTrue) delete fNumeratorTrue;
    if (aCorrFctn.fNumeratorTrue)
      fNumeratorTrue = new TH1D(*aCorrFctn.fNumeratorTrue);
    else
      fNumeratorTrue = 0;

    if (fNumeratorFake) delete fNumeratorFake;
    if (aCorrFctn.fNumeratorFake)
      fNumeratorFake = new TH1D(*aCorrFctn.fNumeratorFake);
    else
      fNumeratorFake = 0;

    if (fDenominator) delete fDenominator;
    if (aCorrFctn.fDenominator)
      fDenominator = new TH1D(*aCorrFctn.fDenominator);
    else
      fDenominator = 0;
  }

  return *this;
}
//_______________________
AliFemtoString AliFemtoModelCorrFctnDirectYlm::Report()
{
  // construct report
  AliFemtoString tStr = "AliFemtoModelCorrFctnDirectYlm report";

  return tStr;
}

//_______________________
void AliFemtoModelCorrFctnDirectYlm::AddRealPair(AliFemtoPair* aPair)
{
  // add real (effect) pair
  if (fPairCut)
    if (!(fPairCut->Pass(aPair))) return;

  Double_t weight = fManager->GetWeight(aPair);

  if (fUseLCMS)
    fCYlmTrue->AddRealPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), weight);
  else
    fCYlmTrue->AddRealPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), weight);
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::AddMixedPair(AliFemtoPair* aPair)
{
  // add mixed (background) pair
  if (fPairCut)
    if (!(fPairCut->Pass(aPair))) return;

  Double_t weight = fManager->GetWeight(aPair);

  if (fUseLCMS) {
    fCYlmTrue->AddMixedPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
    fCYlmFake->AddRealPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), weight);
    fCYlmFake->AddMixedPair(aPair->QOutCMS(), aPair->QSideCMS(), aPair->QLongCMS(), 1.0);
  }
  else {
    fCYlmTrue->AddMixedPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
    fCYlmFake->AddRealPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), weight);
    fCYlmFake->AddMixedPair(aPair->KOut(), aPair->KSide(), aPair->KLong(), 1.0);
  }
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::Write()
{
  // write out all the histograms

  fCYlmTrue->Write();
  fCYlmFake->Write();
}
//_______________________
TList* AliFemtoModelCorrFctnDirectYlm::GetOutputList()
{
  // Prepare the list of objects to be written to the output
  TList *tOutputList = AliFemtoModelCorrFctn::GetOutputList();
  tOutputList->Clear();

  TList *tListCfTrue = fCYlmTrue->GetOutputList();

  TIter nextListCfTrue(tListCfTrue);
  while (TObject *obj = nextListCfTrue()) {
    tOutputList->Add(obj);
  }

  TList *tListCfFake = fCYlmFake->GetOutputList();

  TIter nextListCfFake(tListCfFake);
  while (TObject *obj = nextListCfFake()) {
    tOutputList->Add(obj);
  }
//   tOutputList->Add(fCYlmTrue->GetOutputList());
//   tOutputList->Add(fCYlmFake->GetOutputList());

  return tOutputList;
}
//_______________________
AliFemtoModelCorrFctn* AliFemtoModelCorrFctnDirectYlm::Clone()
{
  // Clone the correlation function
  AliFemtoModelCorrFctnDirectYlm *tCopy = new AliFemtoModelCorrFctnDirectYlm(*this);

  return tCopy;
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::Finish()
{
  fCYlmTrue->Finish();
  fCYlmFake->Finish();
}
//_______________________
void AliFemtoModelCorrFctnDirectYlm::SetUseLCMS(int aUseLCMS)
{
  fUseLCMS = aUseLCMS;
  fCYlmTrue->SetUseLCMS(fUseLCMS);
  fCYlmFake->SetUseLCMS(fUseLCMS);
}
//_______________________
int  AliFemtoModelCorrFctnDirectYlm::GetUseLCMS()
{
  return fUseLCMS;
}

<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS ooo19126 (1.6.14); FILE MERGED 2005/09/05 17:28:11 rt 1.6.14.1: #i54170# Change license header: remove SISSL<commit_after><|endoftext|>