<commit_before>/**
 *  @file CVodesIntegrator.cpp
 *
 */

// Copyright 2001  California Institute of Technology

#include "CVodesIntegrator.h"
#include "stringUtils.h"

#include <iostream>
using namespace std;

#ifdef SUNDIALS_VERSION_22

#include <sundials_types.h>
#include <sundials_math.h>
#include <cvodes.h>
#include <cvodes_dense.h>
#include <cvodes_diag.h>
#include <cvodes_spgmr.h>
#include <cvodes_band.h>
#include <nvector_serial.h>

#else

#ifdef SUNDIALS_VERSION_23
#include <sundials/sundials_types.h>
#include <sundials/sundials_math.h>
#include <sundials/sundials_nvector.h>
#include <nvector/nvector_serial.h>
#include <cvodes/cvodes.h>
#include <cvodes/cvodes_dense.h>
#include <cvodes/cvodes_diag.h>
#include <cvodes/cvodes_spgmr.h>
#include <cvodes/cvodes_band.h>

#else

unsupported sundials version!

#endif

#endif

inline static N_Vector nv(void* x) {
    return reinterpret_cast<N_Vector>(x);
}

namespace Cantera {

    class FuncData {
    public:
        FuncData(FuncEval* f, int npar = 0) {
            m_pars.resize(npar, 1.0);
            m_func = f;
        }
        virtual ~FuncData() {}
        vector_fp m_pars;
        FuncEval* m_func;
    };
}

extern "C" {

    /**
     *  Function called by cvodes to evaluate ydot given y.  The cvode
     *  integrator allows passing in a void* pointer to access
     *  external data. This pointer is cast to a pointer to a instance
     *  of class FuncEval. The equations to be integrated should be
     *  specified by deriving a class from FuncEval that evaluates the
     *  desired equations.
     *  @ingroup odeGroup
     */
    static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot,
        void *f_data) {
        double* ydata = NV_DATA_S(y); //N_VDATA(y);
        double* ydotdata = NV_DATA_S(ydot); //N_VDATA(ydot);
        Cantera::FuncData* d = (Cantera::FuncData*)f_data;
        Cantera::FuncEval* f = d->m_func;
        //try {
            if (d->m_pars.size() == 0)
                f->eval(t, ydata, ydotdata, NULL);
            else
                f->eval(t, ydata, ydotdata, DATA_PTR(d->m_pars));
            //}
            //catch (...) {
            //Cantera::showErrors();
            //Cantera::error("Teminating execution");
            //}
            return 0;
    }

}

namespace Cantera {

    /**
     *  Constructor. Default settings: dense jacobian, no user-supplied
     *  Jacobian function, Newton iteration.
     */
    CVodesIntegrator::CVodesIntegrator() : m_neq(0),
                           m_cvode_mem(0),
                           m_t0(0.0),
                           m_y(0),
                           m_abstol(0),
                           m_type(DENSE+NOJAC),
                           m_itol(CV_SS),
                           m_method(CV_BDF),
                           m_iter(CV_NEWTON),
                           m_maxord(0),
                           m_reltol(1.e-9),
                           m_abstols(1.e-15),
                                           m_reltolsens(1.0e-5),
                                           m_abstolsens(1.0e-4),
                           m_nabs(0),
                           m_hmax(0.0),
                                           m_maxsteps(20000), m_np(0),
                                           m_mupper(0), m_mlower(0)
    {
        //m_ropt.resize(OPT_SIZE,0.0);
        //m_iopt = new long[OPT_SIZE];
        //fill(m_iopt, m_iopt+OPT_SIZE,0);
    }

    /// Destructor.
    CVodesIntegrator::~CVodesIntegrator()
    {
        if (m_cvode_mem) {
            if (m_np > 0)
                CVodeSensFree(m_cvode_mem);
#ifdef SUNDIALS_VERSION_1
            CVodeFree(m_cvode_mem);
#else
            CVodeFree(&m_cvode_mem);
#endif
        }
      if (m_y) N_VDestroy_Serial(nv(m_y));
      if (m_abstol) N_VDestroy_Serial(nv(m_abstol));
      delete m_fdata;

      //delete[] m_iopt;
    }

    double& CVodesIntegrator::solution(int k){
        return NV_Ith_S(nv(m_y),k);
    }

    double* CVodesIntegrator::solution(){ return NV_DATA_S(nv(m_y));
    }

    void CVodesIntegrator::setTolerances(double reltol, int n, double* abstol) {
        m_itol = CV_SV;
        m_nabs = n;
        if (n != m_neq) {
            if (m_abstol) N_VDestroy_Serial(nv(m_abstol));
            m_abstol = reinterpret_cast<void*>(N_VNew_Serial(n));
        }
        for (int i=0; i<n; i++) {
            NV_Ith_S(nv(m_abstol), i) = abstol[i];
        }
        m_reltol = reltol;
    }

    void CVodesIntegrator::setTolerances(double reltol, double abstol) {
        m_itol = CV_SS;
        m_reltol = reltol;
        m_abstols = abstol;
    }

    void CVodesIntegrator::setSensitivityTolerances(double reltol, double abstol) {
        m_reltolsens = reltol;
        m_abstolsens = abstol;
    }

    void CVodesIntegrator::setProblemType(int probtype) {
      m_type = probtype;
    }

    void CVodesIntegrator::setMethod(MethodType t) {
        if (t == BDF_Method)
            m_method = CV_BDF;
        else if (t == Adams_Method)
            m_method = CV_ADAMS;
        else
            throw CVodesErr("unknown method");
    }

    void CVodesIntegrator::setMaxStepSize(doublereal hmax) {
        m_hmax = hmax;
        if (m_cvode_mem)
            CVodeSetMaxStep(m_cvode_mem, hmax);
    }

    void CVodesIntegrator::setMinStepSize(doublereal hmin) {
        m_hmin = hmin;
        if (m_cvode_mem)
            CVodeSetMinStep(m_cvode_mem, hmin);
    }

    void CVodesIntegrator::setMaxSteps(int nmax) {
        m_maxsteps = nmax;
        if (m_cvode_mem)
            CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
    }

    void CVodesIntegrator::setIterator(IterType t) {
        if (t == Newton_Iter)
            m_iter = CV_NEWTON;
        else if (t == Functional_Iter)
            m_iter = CV_FUNCTIONAL;
        else
            throw CVodesErr("unknown iterator");
    }

    void CVodesIntegrator::sensInit(double t0, FuncEval& func) {
        m_np = func.nparams();
        long int nv = func.neq();

#ifdef SUNDIALS_VERSION_1
        doublereal* data;
        int n, j;
        m_yS = N_VNewVectorArray_Serial(m_np, nv);
        for (n = 0; n < m_np; n++) {
            data = NV_DATA_S(m_yS[n]);
            for (j = 0; j < nv; j++) {
                data[j] =0.0;
            }
        }
#else
        doublereal* data;
        int n, j;
        N_Vector y;
        y = N_VNew_Serial(nv);
        m_yS = N_VCloneVectorArray_Serial(m_np, y);
        for (n = 0; n < m_np; n++) {
            data = NV_DATA_S(m_yS[n]);
            for (j = 0; j < nv; j++) {
                data[j] =0.0;
            }
        }
#endif
        int flag;
        flag = CVodeSensMalloc(m_cvode_mem, m_np, CV_STAGGERED, m_yS);
        if (flag != CV_SUCCESS)
            throw CVodesErr("Error in CVodeSensMalloc");
        vector_fp atol(m_np, m_abstolsens);
        double rtol = m_reltolsens;
        flag = CVodeSetSensTolerances(m_cvode_mem, CV_SS, rtol, DATA_PTR(atol));
    }

    void CVodesIntegrator::initialize(double t0, FuncEval& func)
    {
        m_neq = func.neq();
        m_t0  = t0;

        if (m_y) {
            N_VDestroy_Serial(nv(m_y));    // free solution vector if already allocated
        }
        m_y = reinterpret_cast<void*>(N_VNew_Serial(m_neq));   // allocate solution vector
        for (int i=0; i<m_neq; i++) {
            NV_Ith_S(nv(m_y), i) = 0.0;
        }
        // check abs tolerance array size
        if (m_itol == CV_SV && m_nabs < m_neq)
            throw CVodesErr("not enough absolute tolerance values specified.");

        func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));

        if (m_cvode_mem) CVodeFree(&m_cvode_mem);
        m_cvode_mem = CVodeCreate(m_method, m_iter);
        if (!m_cvode_mem) throw CVodesErr("CVodeCreate failed.");

        int flag = 0;
        if (m_itol == CV_SV) {
            // vector atol
            flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
                m_reltol, nv(m_abstol));
        }
        else {
            // scalar atol
            flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
                m_reltol, &m_abstols);
        }
        if (flag != CV_SUCCESS) {
            if (flag == CV_MEM_FAIL) {
                throw CVodesErr("Memory allocation failed.");
            }
            else if (flag == CV_ILL_INPUT) {
                throw CVodesErr("Illegal value for CVodeMalloc input argument.");
            }
            else
                throw CVodesErr("CVodeMalloc failed.");
        }

        if (m_type == DENSE + NOJAC) {
            long int N = m_neq;
            CVDense(m_cvode_mem, N);
        }
        else if (m_type == DIAG) {
            CVDiag(m_cvode_mem);
        }
        else if (m_type == GMRES) {
            CVSpgmr(m_cvode_mem, PREC_NONE, 0);
        }
        else if (m_type == BAND + NOJAC) {
            long int N = m_neq;
            long int nu = m_mupper;
            long int nl = m_mlower;
            CVBand(m_cvode_mem, N, nu, nl);
        }
        else {
            throw CVodesErr("unsupported option");
        }

        // pass a pointer to func in m_data
        m_fdata = new FuncData(&func, func.nparams());

        //m_data = (void*)&func;

        flag = CVodeSetFdata(m_cvode_mem, (void*)m_fdata);
        if (flag != CV_SUCCESS)
            throw CVodesErr("CVodeSetFdata failed.");

        if (func.nparams() > 0) {
            sensInit(t0, func);
            flag = CVodeSetSensParams(m_cvode_mem, DATA_PTR(m_fdata->m_pars),
                NULL, NULL);
        }

        // set options
        if (m_maxord > 0)
            flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord);
        if (m_maxsteps > 0)
            flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
        if (m_hmax > 0)
            flag = CVodeSetMaxStep(m_cvode_mem, m_hmax);
    }

    void CVodesIntegrator::reinitialize(double t0, FuncEval& func)
    {
        m_t0  = t0;
        //try {
            func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));
            //}
            //catch (CanteraError) {
            //showErrors();
            //error("Teminating execution");
            //}

        int result, flag;
        if (m_itol == CV_SV) {
            result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y),
                m_itol, m_reltol,
                nv(m_abstol));
        }
        else {
            result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y),
                m_itol, m_reltol,
                &m_abstols);
        }
        if (result != CV_SUCCESS)
            throw CVodesErr("CVReInit failed. result = "+int2str(result));

        if (m_type == DENSE + NOJAC) {
            long int N = m_neq;
            CVDense(m_cvode_mem, N);
        }
        else if (m_type == DIAG) {
            CVDiag(m_cvode_mem);
        }
        else if (m_type == BAND + NOJAC) {
            long int N = m_neq;
            long int nu = m_mupper;
            long int nl = m_mlower;
            CVBand(m_cvode_mem, N, nu, nl);
        }
        else if (m_type == GMRES) {
            CVSpgmr(m_cvode_mem, PREC_NONE, 0);
        }
        else {
            throw CVodesErr("unsupported option");
        }

        // set options
        if (m_maxord > 0)
            flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord);
        if (m_maxsteps > 0)
            flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
        if (m_hmax > 0)
            flag = CVodeSetMaxStep(m_cvode_mem, m_hmax);
    }

    void CVodesIntegrator::integrate(double tout)
    {
        double t;
        int flag;
	flag = CVode(m_cvode_mem, tout, nv(m_y), &t, CV_NORMAL);
	if (flag != CV_SUCCESS)
	  throw CVodesErr(" CVodes error encountered.");
        if (m_np > 0) {
            CVodeGetSens(m_cvode_mem, tout, m_yS);
        }
    }

    double CVodesIntegrator::step(double tout)
    {
        double t;
        int flag;
	flag = CVode(m_cvode_mem, tout, nv(m_y), &t, CV_ONE_STEP);
	if (flag != CV_SUCCESS)
	  throw CVodesErr(" CVodes error encountered.");
        return t;
      }

    int CVodesIntegrator::nEvals() const {
        long int ne;
        CVodeGetNumRhsEvals(m_cvode_mem, &ne);
        return ne;
        //return m_iopt[NFE];
    }

    double CVodesIntegrator::sensitivity(int k, int p) {
        if (k < 0 || k >= m_neq)
            throw CVodesErr("sensitivity: k out of range ("+int2str(p)+")");
        if (p < 0 || p >= m_np)
            throw CVodesErr("sensitivity: p out of range ("+int2str(p)+")");
        return NV_Ith_S(m_yS[p],k);
    }
}

<commit_msg>*** empty log message ***<commit_after>/**
 *  @file CVodesIntegrator.cpp
 *
 */

// Copyright 2001  California Institute of Technology

#include "CVodesIntegrator.h"
#include "stringUtils.h"

#include <iostream>
using namespace std;

#ifdef SUNDIALS_VERSION_22

#include <sundials_types.h>
#include <sundials_math.h>
#include <cvodes.h>
#include <cvodes_dense.h>
#include <cvodes_diag.h>
#include <cvodes_spgmr.h>
#include <cvodes_band.h>
#include <nvector_serial.h>

#else

#ifdef SUNDIALS_VERSION_23
#include <sundials/sundials_types.h>
#include <sundials/sundials_math.h>
#include <sundials/sundials_nvector.h>
#include <nvector/nvector_serial.h>
#include <cvodes/cvodes.h>
#include <cvodes/cvodes_dense.h>
#include <cvodes/cvodes_diag.h>
#include <cvodes/cvodes_spgmr.h>
#include <cvodes/cvodes_band.h>

#else

unsupported sundials version!

#endif

#endif

inline static N_Vector nv(void* x) {
    return reinterpret_cast<N_Vector>(x);
}

namespace Cantera {

    class FuncData {
    public:
        FuncData(FuncEval* f, int npar = 0) {
            m_pars.resize(npar, 1.0);
            m_func = f;
        }
        virtual ~FuncData() {}
        vector_fp m_pars;
        FuncEval* m_func;
    };
}

extern "C" {

    /**
     *  Function called by cvodes to evaluate ydot given y.  The cvode
     *  integrator allows passing in a void* pointer to access
     *  external data. This pointer is cast to a pointer to a instance
     *  of class FuncEval. The equations to be integrated should be
     *  specified by deriving a class from FuncEval that evaluates the
     *  desired equations.
     *  @ingroup odeGroup
     */
    static int cvodes_rhs(realtype t, N_Vector y, N_Vector ydot,
        void *f_data) {
        double* ydata = NV_DATA_S(y); //N_VDATA(y);
        double* ydotdata = NV_DATA_S(ydot); //N_VDATA(ydot);
        Cantera::FuncData* d = (Cantera::FuncData*)f_data;
        Cantera::FuncEval* f = d->m_func;
        //try {
            if (d->m_pars.size() == 0)
                f->eval(t, ydata, ydotdata, NULL);
            else
                f->eval(t, ydata, ydotdata, DATA_PTR(d->m_pars));
            //}
            //catch (...) {
            //Cantera::showErrors();
            //Cantera::error("Teminating execution");
            //}
            return 0;
    }

}

namespace Cantera {

    /**
     *  Constructor. Default settings: dense jacobian, no user-supplied
     *  Jacobian function, Newton iteration.
     */
    CVodesIntegrator::CVodesIntegrator() : m_neq(0),
                           m_cvode_mem(0),
                           m_t0(0.0),
                           m_y(0),
                           m_abstol(0),
                           m_type(DENSE+NOJAC),
                           m_itol(CV_SS),
                           m_method(CV_BDF),
                           m_iter(CV_NEWTON),
                           m_maxord(0),
                           m_reltol(1.e-9),
                           m_abstols(1.e-15),
                                           m_reltolsens(1.0e-5),
                                           m_abstolsens(1.0e-4),
                           m_nabs(0),
                           m_hmax(0.0),
                                           m_maxsteps(20000), m_np(0),
                                           m_mupper(0), m_mlower(0)
    {
        //m_ropt.resize(OPT_SIZE,0.0);
        //m_iopt = new long[OPT_SIZE];
        //fill(m_iopt, m_iopt+OPT_SIZE,0);
    }

    /// Destructor.
    CVodesIntegrator::~CVodesIntegrator()
    {
        if (m_cvode_mem) {
            if (m_np > 0)
                CVodeSensFree(m_cvode_mem);
            CVodeFree(&m_cvode_mem);
        }
      if (m_y) N_VDestroy_Serial(nv(m_y));
      if (m_abstol) N_VDestroy_Serial(nv(m_abstol));
      delete m_fdata;

      //delete[] m_iopt;
    }

    double& CVodesIntegrator::solution(int k){
        return NV_Ith_S(nv(m_y),k);
    }

    double* CVodesIntegrator::solution(){ return NV_DATA_S(nv(m_y));
    }

    void CVodesIntegrator::setTolerances(double reltol, int n, double* abstol) {
        m_itol = CV_SV;
        m_nabs = n;
        if (n != m_neq) {
            if (m_abstol) N_VDestroy_Serial(nv(m_abstol));
            m_abstol = reinterpret_cast<void*>(N_VNew_Serial(n));
        }
        for (int i=0; i<n; i++) {
            NV_Ith_S(nv(m_abstol), i) = abstol[i];
        }
        m_reltol = reltol;
    }

    void CVodesIntegrator::setTolerances(double reltol, double abstol) {
        m_itol = CV_SS;
        m_reltol = reltol;
        m_abstols = abstol;
    }

    void CVodesIntegrator::setSensitivityTolerances(double reltol, double abstol) {
        m_reltolsens = reltol;
        m_abstolsens = abstol;
    }

    void CVodesIntegrator::setProblemType(int probtype) {
      m_type = probtype;
    }

    void CVodesIntegrator::setMethod(MethodType t) {
        if (t == BDF_Method)
            m_method = CV_BDF;
        else if (t == Adams_Method)
            m_method = CV_ADAMS;
        else
            throw CVodesErr("unknown method");
    }

    void CVodesIntegrator::setMaxStepSize(doublereal hmax) {
        m_hmax = hmax;
        if (m_cvode_mem)
            CVodeSetMaxStep(m_cvode_mem, hmax);
    }

    void CVodesIntegrator::setMinStepSize(doublereal hmin) {
        m_hmin = hmin;
        if (m_cvode_mem)
            CVodeSetMinStep(m_cvode_mem, hmin);
    }

    void CVodesIntegrator::setMaxSteps(int nmax) {
        m_maxsteps = nmax;
        if (m_cvode_mem)
            CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
    }

    void CVodesIntegrator::setIterator(IterType t) {
        if (t == Newton_Iter)
            m_iter = CV_NEWTON;
        else if (t == Functional_Iter)
            m_iter = CV_FUNCTIONAL;
        else
            throw CVodesErr("unknown iterator");
    }

    void CVodesIntegrator::sensInit(double t0, FuncEval& func) {
        m_np = func.nparams();
        long int nv = func.neq();

        doublereal* data;
        int n, j;
        N_Vector y;
        y = N_VNew_Serial(nv);
        m_yS = N_VCloneVectorArray_Serial(m_np, y);
        for (n = 0; n < m_np; n++) {
            data = NV_DATA_S(m_yS[n]);
            for (j = 0; j < nv; j++) {
                data[j] =0.0;
            }
        }

        int flag;
        flag = CVodeSensMalloc(m_cvode_mem, m_np, CV_STAGGERED, m_yS);
        if (flag != CV_SUCCESS)
            throw CVodesErr("Error in CVodeSensMalloc");
        vector_fp atol(m_np, m_abstolsens);
        double rtol = m_reltolsens;
        flag = CVodeSetSensTolerances(m_cvode_mem, CV_SS, rtol, DATA_PTR(atol));
    }

    void CVodesIntegrator::initialize(double t0, FuncEval& func)
    {
        m_neq = func.neq();
        m_t0  = t0;

        if (m_y) {
            N_VDestroy_Serial(nv(m_y));    // free solution vector if already allocated
        }
        m_y = reinterpret_cast<void*>(N_VNew_Serial(m_neq));   // allocate solution vector
        for (int i=0; i<m_neq; i++) {
            NV_Ith_S(nv(m_y), i) = 0.0;
        }
        // check abs tolerance array size
        if (m_itol == CV_SV && m_nabs < m_neq)
            throw CVodesErr("not enough absolute tolerance values specified.");

        func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));

        if (m_cvode_mem) CVodeFree(&m_cvode_mem);
        m_cvode_mem = CVodeCreate(m_method, m_iter);
        if (!m_cvode_mem) throw CVodesErr("CVodeCreate failed.");

        int flag = 0;
        if (m_itol == CV_SV) {
            // vector atol
            flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
                m_reltol, nv(m_abstol));
        }
        else {
            // scalar atol
            flag = CVodeMalloc(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y), m_itol,
                m_reltol, &m_abstols);
        }
        if (flag != CV_SUCCESS) {
            if (flag == CV_MEM_FAIL) {
                throw CVodesErr("Memory allocation failed.");
            }
            else if (flag == CV_ILL_INPUT) {
                throw CVodesErr("Illegal value for CVodeMalloc input argument.");
            }
            else
                throw CVodesErr("CVodeMalloc failed.");
        }

        if (m_type == DENSE + NOJAC) {
            long int N = m_neq;
            CVDense(m_cvode_mem, N);
        }
        else if (m_type == DIAG) {
            CVDiag(m_cvode_mem);
        }
        else if (m_type == GMRES) {
            CVSpgmr(m_cvode_mem, PREC_NONE, 0);
        }
        else if (m_type == BAND + NOJAC) {
            long int N = m_neq;
            long int nu = m_mupper;
            long int nl = m_mlower;
            CVBand(m_cvode_mem, N, nu, nl);
        }
        else {
            throw CVodesErr("unsupported option");
        }

        // pass a pointer to func in m_data
        m_fdata = new FuncData(&func, func.nparams());

        //m_data = (void*)&func;

        flag = CVodeSetFdata(m_cvode_mem, (void*)m_fdata);
        if (flag != CV_SUCCESS)
            throw CVodesErr("CVodeSetFdata failed.");

        if (func.nparams() > 0) {
            sensInit(t0, func);
            flag = CVodeSetSensParams(m_cvode_mem, DATA_PTR(m_fdata->m_pars),
                NULL, NULL);
        }

        // set options
        if (m_maxord > 0)
            flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord);
        if (m_maxsteps > 0)
            flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
        if (m_hmax > 0)
            flag = CVodeSetMaxStep(m_cvode_mem, m_hmax);
    }

    void CVodesIntegrator::reinitialize(double t0, FuncEval& func)
    {
        m_t0  = t0;
        //try {
            func.getInitialConditions(m_t0, m_neq, NV_DATA_S(nv(m_y)));
            //}
            //catch (CanteraError) {
            //showErrors();
            //error("Teminating execution");
            //}

        int result, flag;
        if (m_itol == CV_SV) {
            result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y),
                m_itol, m_reltol,
                nv(m_abstol));
        }
        else {
            result = CVodeReInit(m_cvode_mem, cvodes_rhs, m_t0, nv(m_y),
                m_itol, m_reltol,
                &m_abstols);
        }
        if (result != CV_SUCCESS)
            throw CVodesErr("CVReInit failed. result = "+int2str(result));

        if (m_type == DENSE + NOJAC) {
            long int N = m_neq;
            CVDense(m_cvode_mem, N);
        }
        else if (m_type == DIAG) {
            CVDiag(m_cvode_mem);
        }
        else if (m_type == BAND + NOJAC) {
            long int N = m_neq;
            long int nu = m_mupper;
            long int nl = m_mlower;
            CVBand(m_cvode_mem, N, nu, nl);
        }
        else if (m_type == GMRES) {
            CVSpgmr(m_cvode_mem, PREC_NONE, 0);
        }
        else {
            throw CVodesErr("unsupported option");
        }

        // set options
        if (m_maxord > 0)
            flag = CVodeSetMaxOrd(m_cvode_mem, m_maxord);
        if (m_maxsteps > 0)
            flag = CVodeSetMaxNumSteps(m_cvode_mem, m_maxsteps);
        if (m_hmax > 0)
            flag = CVodeSetMaxStep(m_cvode_mem, m_hmax);
    }

    void CVodesIntegrator::integrate(double tout)
    {
        double t;
        int flag;
	flag = CVode(m_cvode_mem, tout, nv(m_y), &t, CV_NORMAL);
	if (flag != CV_SUCCESS)
	  throw CVodesErr(" CVodes error encountered.");
        if (m_np > 0) {
            CVodeGetSens(m_cvode_mem, tout, m_yS);
        }
    }

    double CVodesIntegrator::step(double tout)
    {
        double t;
        int flag;
	flag = CVode(m_cvode_mem, tout, nv(m_y), &t, CV_ONE_STEP);
	if (flag != CV_SUCCESS)
	  throw CVodesErr(" CVodes error encountered.");
        return t;
      }

    int CVodesIntegrator::nEvals() const {
        long int ne;
        CVodeGetNumRhsEvals(m_cvode_mem, &ne);
        return ne;
        //return m_iopt[NFE];
    }

    double CVodesIntegrator::sensitivity(int k, int p) {
        if (k < 0 || k >= m_neq)
            throw CVodesErr("sensitivity: k out of range ("+int2str(p)+")");
        if (p < 0 || p >= m_np)
            throw CVodesErr("sensitivity: p out of range ("+int2str(p)+")");
        return NV_Ith_S(m_yS[p],k);
    }
}

<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "QmitkDataStorageComboBox.h"

#include <itkCommand.h>

QmitkDataStorageComboBox::QmitkDataStorageComboBox(QWidget *parent, bool autoSelectNewNodes)
  : QComboBox(parent),
    m_DataStorage(nullptr),
    m_Predicate(nullptr),
    m_BlockEvents(false),
    m_AutoSelectNewNodes(autoSelectNewNodes)
{
  this->Init();
}

QmitkDataStorageComboBox::QmitkDataStorageComboBox(mitk::DataStorage *dataStorage,
                                                   const mitk::NodePredicateBase *predicate,
                                                   QWidget *parent,
                                                   bool autoSelectNewNodes)
  : QComboBox(parent),
    m_DataStorage(nullptr),
    m_Predicate(predicate),
    m_BlockEvents(false),
    m_AutoSelectNewNodes(autoSelectNewNodes)
{
  // make connections, fill combobox
  this->Init();
  this->SetDataStorage(dataStorage);
}

QmitkDataStorageComboBox::~QmitkDataStorageComboBox()
{
  // if there was an old storage, remove listeners
  if (!m_DataStorage.IsExpired())
  {
    auto dataStorage = m_DataStorage.Lock();

    dataStorage->AddNodeEvent.RemoveListener(
      mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
                                                                               &QmitkDataStorageComboBox::AddNode));

    dataStorage->RemoveNodeEvent.RemoveListener(
      mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
                                                                               &QmitkDataStorageComboBox::RemoveNode));
  }
  // we have lots of observers to nodes and their name properties, this gets ugly if nodes live longer than the box
  while (m_Nodes.size() > 0)
    RemoveNode(0);
}

int QmitkDataStorageComboBox::Find(const mitk::DataNode *dataNode) const
{
  std::iterator_traits<mitk::DataNode*>::difference_type index = -1;

  auto nodeIt = std::find(m_Nodes.begin(), m_Nodes.end(), dataNode);

  if (nodeIt != m_Nodes.end())
    index = std::distance(m_Nodes.begin(), nodeIt);

  return static_cast<int>(index);
}

mitk::DataStorage::Pointer QmitkDataStorageComboBox::GetDataStorage() const
{
  return m_DataStorage.Lock();
}

const mitk::NodePredicateBase::ConstPointer QmitkDataStorageComboBox::GetPredicate() const
{
  return m_Predicate.GetPointer();
}

mitk::DataNode::Pointer QmitkDataStorageComboBox::GetNode(int index) const
{
  return (this->HasIndex(index)) ? m_Nodes.at(index) : nullptr;
}

mitk::DataNode::Pointer QmitkDataStorageComboBox::GetSelectedNode() const
{
  if (this->count() == 0)
    return nullptr;

  int currentIndex = this->currentIndex();

  return currentIndex >= 0 ? this->GetNode(currentIndex) : nullptr;
}

mitk::DataStorage::SetOfObjects::ConstPointer QmitkDataStorageComboBox::GetNodes() const
{
  mitk::DataStorage::SetOfObjects::Pointer setOfObjects = mitk::DataStorage::SetOfObjects::New();

  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
  {
    setOfObjects->push_back(*it);
  }

  return setOfObjects.GetPointer();
}

bool QmitkDataStorageComboBox::GetAutoSelectNewItems()
{
  return m_AutoSelectNewNodes;
}

void QmitkDataStorageComboBox::SetDataStorage(mitk::DataStorage *dataStorage)
{
  auto currentDataStorage = m_DataStorage.Lock();

  // reset only if datastorage really changed
  if (currentDataStorage.GetPointer() != dataStorage)
  {
    // if there was an old storage, remove listeners
    if (currentDataStorage.IsNotNull())
    {
      currentDataStorage->AddNodeEvent.RemoveListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::AddNode));

      currentDataStorage->RemoveNodeEvent.RemoveListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::RemoveNode));
    }
    // set new storage
    m_DataStorage = dataStorage;

    // if there is a new storage, add listeners
    if (!m_DataStorage.IsExpired())
    {
      currentDataStorage = m_DataStorage.Lock();

      currentDataStorage->AddNodeEvent.AddListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::AddNode));

      currentDataStorage->RemoveNodeEvent.AddListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::RemoveNode));
    }

    // reset predicate to reset the combobox
    this->Reset();
  }
}

void QmitkDataStorageComboBox::SetPredicate(const mitk::NodePredicateBase *predicate)
{
  if (m_Predicate != predicate)
  {
    m_Predicate = predicate;
    this->Reset();
  }
}

void QmitkDataStorageComboBox::AddNode(const mitk::DataNode *dataNode)
{
  // this is an event function, make sure that we didn't call ourself
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;
    // pass a -1 to the InsertNode function in order to append the datatree node to the end
    this->InsertNode(-1, dataNode);
    m_BlockEvents = false;
  }
}

void QmitkDataStorageComboBox::RemoveNode(int index)
{
  if (this->HasIndex(index))
  {
    RemoveNodeAndPropertyLists(index);
    // remove node name from combobox
    this->removeItem(index);
  }
}

void QmitkDataStorageComboBox::RemoveNode(const mitk::DataNode *dataNode)
{
  // this is an event function, make sure that we didn't call ourself
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;
    this->RemoveNode(this->Find(dataNode));
    m_BlockEvents = false;
  }
}

void QmitkDataStorageComboBox::SetNode(int index, const mitk::DataNode *dataNode)
{
  if (this->HasIndex(index))
  {
    // if node is identical, we only update the name in the QComboBoxItem
    if (dataNode == m_Nodes.at(index))
    {
      this->setItemText(index, QString::fromStdString(dataNode->GetName()));
    }
    else
    {
      this->InsertNode(index, dataNode);
    }
  }
}

void QmitkDataStorageComboBox::SetNode(const mitk::DataNode *dataNode, const mitk::DataNode *otherDataNode)
{
  this->SetNode(this->Find(dataNode), otherDataNode);
}

void QmitkDataStorageComboBox::SetAutoSelectNewItems(bool autoSelectNewItems)
{
  m_AutoSelectNewNodes = autoSelectNewItems;
}

void QmitkDataStorageComboBox::OnPropertyListChanged(const itk::Object *caller, const itk::EventObject &event)
{
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;

    // check if we have a modified event
    const itk::ModifiedEvent *modifiedEvent = dynamic_cast<const itk::ModifiedEvent *>(&event);
    if (modifiedEvent)
    {
      const mitk::PropertyList *propertyList = dynamic_cast<const mitk::PropertyList *>(caller);
      UpdateComboBoxText(propertyList);
    }

    m_BlockEvents = false;
  }
}

bool QmitkDataStorageComboBox::HasIndex(unsigned int index) const
{
  return (m_Nodes.size() > 0 && index < m_Nodes.size());
}

void QmitkDataStorageComboBox::OnCurrentIndexChanged(int index)
{
  if (index >= 0 && index < this->count())
    emit OnSelectionChanged(this->GetSelectedNode());
  if (index == -1)
    emit OnSelectionChanged(nullptr);
}

void QmitkDataStorageComboBox::SetSelectedNode(const mitk::DataNode::Pointer& node)
{
  int index = this->Find(node);
  if (index == -1)
  {
    MITK_INFO << "QmitkDataStorageComboBox: item not available";
  }
  else
  {
    this->setCurrentIndex(index);
  }
}

void QmitkDataStorageComboBox::InsertNode(int index, const mitk::DataNode *dataNode)
{
  // check new or updated node first
  if (m_Predicate.IsNotNull() && !m_Predicate->CheckNode(dataNode))
    return;

  bool addNewNode = false;
  bool insertNewNode = false;
  bool changedNode = false;

  // if this->HasIndex(index), then a node shall be updated
  if (this->HasIndex(index))
  {
    // if we really have another node at this position then ...
    if (dataNode != m_Nodes.at(index))
    {
      // ... remove node, then proceed as usual
      this->RemoveNode(index);
      insertNewNode = true;
    }
    else
      changedNode = true;
  }
  // otherwise a new node shall be added, let index point to the element after the last element
  else
  {
    index = m_Nodes.size();
    addNewNode = true;
  }

  // const cast because we need non const nodes
  mitk::DataNode *nonConstDataNode = const_cast<mitk::DataNode *>(dataNode);
  if (!changedNode)
  {
    // break on duplicated nodes (that doesn't make sense to have duplicates in the combobox)
    if (this->Find(dataNode) != -1)
      return;

    // add modified observer
    itk::MemberCommand<QmitkDataStorageComboBox>::Pointer propertyListChangedCommand =
      itk::MemberCommand<QmitkDataStorageComboBox>::New();
    propertyListChangedCommand->SetCallbackFunction(this, &QmitkDataStorageComboBox::OnPropertyListChanged);

    // add observer for the data node property list
    mitk::PropertyList* dataNodePropertyList = nonConstDataNode->GetPropertyList();
    if (nullptr != dataNodePropertyList)
    {
      m_DataNodePropertyListObserverTags.push_back(dataNodePropertyList->AddObserver(itk::ModifiedEvent(),
        propertyListChangedCommand));
    }
    else
    {
      // fill vector with invalid value
      m_DataNodePropertyListObserverTags.push_back(-1);
    }

    mitk::PropertyList* baseDataPropertyList;
    //add observer for the base data property list
    mitk::BaseData* baseData = dynamic_cast<mitk::BaseData*>(nonConstDataNode->GetData());
    if (nullptr != baseData)
    {
      baseDataPropertyList = baseData->GetPropertyList();
      if (nullptr != baseDataPropertyList)
      {
        m_BaseDatapropertyListObserverTags.push_back(baseDataPropertyList->AddObserver(itk::ModifiedEvent(),
          propertyListChangedCommand));
      }
      else
      {
        // fill vector with invalid value
        m_BaseDatapropertyListObserverTags.push_back(-1);
      }
    }
    else
    {
      // fill vector with invalid value
      m_BaseDatapropertyListObserverTags.push_back(-1);
    }
  }

  // add node to the vector
  if (addNewNode)
    m_Nodes.push_back(nonConstDataNode);
  else if (insertNewNode)
    m_Nodes.insert(m_Nodes.begin() + index, nonConstDataNode);

  if (addNewNode)
  {
    this->addItem(QString::fromStdString(nonConstDataNode->GetName()));
    // select new node if m_AutoSelectNewNodes is true or if we have just added the first node
    if (m_AutoSelectNewNodes || m_Nodes.size() == 1)
      this->setCurrentIndex(index);
  }
  else
  {
    // update text in combobox
    this->setItemText(index, QString::fromStdString(nonConstDataNode->GetName()));
  }
}

void QmitkDataStorageComboBox::Init()
{
  connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCurrentIndexChanged(int)));
}

void QmitkDataStorageComboBox::Reset()
{
  // remove all nodes first
  while (!m_Nodes.empty())
  {
    // remove last node
    // explicitly calling RemoveNode of QmitkDataStorageComboBox since derived classes may prevent the removal of all
    // nodes in their respective RemoveNode implementation. This is happening for example in
    // QmitkDataStorageComboBoxWithSelectNone.
    QmitkDataStorageComboBox::RemoveNode(m_Nodes.size() - 1);
  }

  // clear combobox
  this->clear();

  if (!m_DataStorage.IsExpired())
  {
    auto dataStorage = m_DataStorage.Lock();
    mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects;

    // select all if predicate == nullptr
    if (m_Predicate.IsNotNull())
      setOfObjects = dataStorage->GetSubset(m_Predicate);
    else
      setOfObjects = dataStorage->GetAll();

    // add all found nodes
    for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin(); nodeIt != setOfObjects->End();
         ++nodeIt) // for each dataNode
    {
      // add node to the node vector and to the combobox
      this->AddNode(nodeIt.Value().GetPointer());
    }
  }
}

void QmitkDataStorageComboBox::RemoveNodeAndPropertyLists(int index)
{
  // remove itk::Event observer
  mitk::DataNode *dataNode = m_Nodes.at(index);

  // remove observer from data node property list
  mitk::PropertyList* dataNodePropertyList = dataNode->GetPropertyList();
  if (nullptr != dataNodePropertyList)
  {
    dataNodePropertyList->RemoveObserver(m_DataNodePropertyListObserverTags[index]);
    // remove observer tags from lists
    m_DataNodePropertyListObserverTags.erase(m_DataNodePropertyListObserverTags.begin() + index);
  }

  // remove observer from base data property list
  mitk::BaseData* baseData = dynamic_cast<mitk::BaseData*>(dataNode->GetData());
  if (nullptr != baseData)
  {
    mitk::PropertyList* baseDataPropertyList = baseData->GetPropertyList();
    if (nullptr != dataNodePropertyList)
    {
      baseDataPropertyList->RemoveObserver(m_BaseDatapropertyListObserverTags[index]);
      // remove observer tags from lists
      m_BaseDatapropertyListObserverTags.erase(m_BaseDatapropertyListObserverTags.begin() + index);
    }
  }

  // remove node from node vector
  m_Nodes.erase(m_Nodes.begin() + index);
}

void QmitkDataStorageComboBox::UpdateComboBoxText(const mitk::PropertyList* propertyList)
{
  mitk::PropertyList* dataNodePropertyList;
  mitk::PropertyList* baseDataPropertyList;
  mitk::BaseData* baseData;
  for (const auto& node : m_Nodes)
  {
    dataNodePropertyList = node->GetPropertyList();

    baseData = dynamic_cast<mitk::BaseData*>(node->GetData());
    if (nullptr != baseData)
    {
      baseDataPropertyList = baseData->GetPropertyList();
    }

    if (propertyList == dataNodePropertyList
     || propertyList == baseDataPropertyList)
    {
      // if one of the property list is the one that has just been modified
      // get the node's index and set its text to the node name
      // the node name might have been changed, depending on the modified property list
      auto index = Find(node);
      // update text in combobox
      this->setItemText(index, QString::fromStdString(node->GetName()));
      return;
    }
  }
}
<commit_msg>Initialize property lists to nullptr<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "QmitkDataStorageComboBox.h"

#include <itkCommand.h>

QmitkDataStorageComboBox::QmitkDataStorageComboBox(QWidget *parent, bool autoSelectNewNodes)
  : QComboBox(parent),
    m_DataStorage(nullptr),
    m_Predicate(nullptr),
    m_BlockEvents(false),
    m_AutoSelectNewNodes(autoSelectNewNodes)
{
  this->Init();
}

QmitkDataStorageComboBox::QmitkDataStorageComboBox(mitk::DataStorage *dataStorage,
                                                   const mitk::NodePredicateBase *predicate,
                                                   QWidget *parent,
                                                   bool autoSelectNewNodes)
  : QComboBox(parent),
    m_DataStorage(nullptr),
    m_Predicate(predicate),
    m_BlockEvents(false),
    m_AutoSelectNewNodes(autoSelectNewNodes)
{
  // make connections, fill combobox
  this->Init();
  this->SetDataStorage(dataStorage);
}

QmitkDataStorageComboBox::~QmitkDataStorageComboBox()
{
  // if there was an old storage, remove listeners
  if (!m_DataStorage.IsExpired())
  {
    auto dataStorage = m_DataStorage.Lock();

    dataStorage->AddNodeEvent.RemoveListener(
      mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
                                                                               &QmitkDataStorageComboBox::AddNode));

    dataStorage->RemoveNodeEvent.RemoveListener(
      mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
                                                                               &QmitkDataStorageComboBox::RemoveNode));
  }
  // we have lots of observers to nodes and their name properties, this gets ugly if nodes live longer than the box
  while (m_Nodes.size() > 0)
    RemoveNode(0);
}

int QmitkDataStorageComboBox::Find(const mitk::DataNode *dataNode) const
{
  std::iterator_traits<mitk::DataNode*>::difference_type index = -1;

  auto nodeIt = std::find(m_Nodes.begin(), m_Nodes.end(), dataNode);

  if (nodeIt != m_Nodes.end())
    index = std::distance(m_Nodes.begin(), nodeIt);

  return static_cast<int>(index);
}

mitk::DataStorage::Pointer QmitkDataStorageComboBox::GetDataStorage() const
{
  return m_DataStorage.Lock();
}

const mitk::NodePredicateBase::ConstPointer QmitkDataStorageComboBox::GetPredicate() const
{
  return m_Predicate.GetPointer();
}

mitk::DataNode::Pointer QmitkDataStorageComboBox::GetNode(int index) const
{
  return (this->HasIndex(index)) ? m_Nodes.at(index) : nullptr;
}

mitk::DataNode::Pointer QmitkDataStorageComboBox::GetSelectedNode() const
{
  if (this->count() == 0)
    return nullptr;

  int currentIndex = this->currentIndex();

  return currentIndex >= 0 ? this->GetNode(currentIndex) : nullptr;
}

mitk::DataStorage::SetOfObjects::ConstPointer QmitkDataStorageComboBox::GetNodes() const
{
  mitk::DataStorage::SetOfObjects::Pointer setOfObjects = mitk::DataStorage::SetOfObjects::New();

  for (auto it = m_Nodes.begin(); it != m_Nodes.end(); ++it)
  {
    setOfObjects->push_back(*it);
  }

  return setOfObjects.GetPointer();
}

bool QmitkDataStorageComboBox::GetAutoSelectNewItems()
{
  return m_AutoSelectNewNodes;
}

void QmitkDataStorageComboBox::SetDataStorage(mitk::DataStorage *dataStorage)
{
  auto currentDataStorage = m_DataStorage.Lock();

  // reset only if datastorage really changed
  if (currentDataStorage.GetPointer() != dataStorage)
  {
    // if there was an old storage, remove listeners
    if (currentDataStorage.IsNotNull())
    {
      currentDataStorage->AddNodeEvent.RemoveListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::AddNode));

      currentDataStorage->RemoveNodeEvent.RemoveListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::RemoveNode));
    }
    // set new storage
    m_DataStorage = dataStorage;

    // if there is a new storage, add listeners
    if (!m_DataStorage.IsExpired())
    {
      currentDataStorage = m_DataStorage.Lock();

      currentDataStorage->AddNodeEvent.AddListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::AddNode));

      currentDataStorage->RemoveNodeEvent.AddListener(
        mitk::MessageDelegate1<QmitkDataStorageComboBox, const mitk::DataNode *>(this,
          &QmitkDataStorageComboBox::RemoveNode));
    }

    // reset predicate to reset the combobox
    this->Reset();
  }
}

void QmitkDataStorageComboBox::SetPredicate(const mitk::NodePredicateBase *predicate)
{
  if (m_Predicate != predicate)
  {
    m_Predicate = predicate;
    this->Reset();
  }
}

void QmitkDataStorageComboBox::AddNode(const mitk::DataNode *dataNode)
{
  // this is an event function, make sure that we didn't call ourself
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;
    // pass a -1 to the InsertNode function in order to append the datatree node to the end
    this->InsertNode(-1, dataNode);
    m_BlockEvents = false;
  }
}

void QmitkDataStorageComboBox::RemoveNode(int index)
{
  if (this->HasIndex(index))
  {
    RemoveNodeAndPropertyLists(index);
    // remove node name from combobox
    this->removeItem(index);
  }
}

void QmitkDataStorageComboBox::RemoveNode(const mitk::DataNode *dataNode)
{
  // this is an event function, make sure that we didn't call ourself
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;
    this->RemoveNode(this->Find(dataNode));
    m_BlockEvents = false;
  }
}

void QmitkDataStorageComboBox::SetNode(int index, const mitk::DataNode *dataNode)
{
  if (this->HasIndex(index))
  {
    // if node is identical, we only update the name in the QComboBoxItem
    if (dataNode == m_Nodes.at(index))
    {
      this->setItemText(index, QString::fromStdString(dataNode->GetName()));
    }
    else
    {
      this->InsertNode(index, dataNode);
    }
  }
}

void QmitkDataStorageComboBox::SetNode(const mitk::DataNode *dataNode, const mitk::DataNode *otherDataNode)
{
  this->SetNode(this->Find(dataNode), otherDataNode);
}

void QmitkDataStorageComboBox::SetAutoSelectNewItems(bool autoSelectNewItems)
{
  m_AutoSelectNewNodes = autoSelectNewItems;
}

void QmitkDataStorageComboBox::OnPropertyListChanged(const itk::Object *caller, const itk::EventObject &event)
{
  if (!m_BlockEvents)
  {
    m_BlockEvents = true;

    // check if we have a modified event
    const itk::ModifiedEvent *modifiedEvent = dynamic_cast<const itk::ModifiedEvent *>(&event);
    if (modifiedEvent)
    {
      const mitk::PropertyList *propertyList = dynamic_cast<const mitk::PropertyList *>(caller);
      UpdateComboBoxText(propertyList);
    }

    m_BlockEvents = false;
  }
}

bool QmitkDataStorageComboBox::HasIndex(unsigned int index) const
{
  return (m_Nodes.size() > 0 && index < m_Nodes.size());
}

void QmitkDataStorageComboBox::OnCurrentIndexChanged(int index)
{
  if (index >= 0 && index < this->count())
    emit OnSelectionChanged(this->GetSelectedNode());
  if (index == -1)
    emit OnSelectionChanged(nullptr);
}

void QmitkDataStorageComboBox::SetSelectedNode(const mitk::DataNode::Pointer& node)
{
  int index = this->Find(node);
  if (index == -1)
  {
    MITK_INFO << "QmitkDataStorageComboBox: item not available";
  }
  else
  {
    this->setCurrentIndex(index);
  }
}

void QmitkDataStorageComboBox::InsertNode(int index, const mitk::DataNode *dataNode)
{
  // check new or updated node first
  if (m_Predicate.IsNotNull() && !m_Predicate->CheckNode(dataNode))
    return;

  bool addNewNode = false;
  bool insertNewNode = false;
  bool changedNode = false;

  // if this->HasIndex(index), then a node shall be updated
  if (this->HasIndex(index))
  {
    // if we really have another node at this position then ...
    if (dataNode != m_Nodes.at(index))
    {
      // ... remove node, then proceed as usual
      this->RemoveNode(index);
      insertNewNode = true;
    }
    else
      changedNode = true;
  }
  // otherwise a new node shall be added, let index point to the element after the last element
  else
  {
    index = m_Nodes.size();
    addNewNode = true;
  }

  // const cast because we need non const nodes
  mitk::DataNode *nonConstDataNode = const_cast<mitk::DataNode *>(dataNode);
  if (!changedNode)
  {
    // break on duplicated nodes (that doesn't make sense to have duplicates in the combobox)
    if (this->Find(dataNode) != -1)
      return;

    // add modified observer
    itk::MemberCommand<QmitkDataStorageComboBox>::Pointer propertyListChangedCommand =
      itk::MemberCommand<QmitkDataStorageComboBox>::New();
    propertyListChangedCommand->SetCallbackFunction(this, &QmitkDataStorageComboBox::OnPropertyListChanged);

    // add observer for the data node property list
    mitk::PropertyList* dataNodePropertyList = nonConstDataNode->GetPropertyList();
    if (nullptr != dataNodePropertyList)
    {
      m_DataNodePropertyListObserverTags.push_back(dataNodePropertyList->AddObserver(itk::ModifiedEvent(),
        propertyListChangedCommand));
    }
    else
    {
      // fill vector with invalid value
      m_DataNodePropertyListObserverTags.push_back(-1);
    }

    mitk::PropertyList* baseDataPropertyList;
    //add observer for the base data property list
    mitk::BaseData* baseData = dynamic_cast<mitk::BaseData*>(nonConstDataNode->GetData());
    if (nullptr != baseData)
    {
      baseDataPropertyList = baseData->GetPropertyList();
      if (nullptr != baseDataPropertyList)
      {
        m_BaseDatapropertyListObserverTags.push_back(baseDataPropertyList->AddObserver(itk::ModifiedEvent(),
          propertyListChangedCommand));
      }
      else
      {
        // fill vector with invalid value
        m_BaseDatapropertyListObserverTags.push_back(-1);
      }
    }
    else
    {
      // fill vector with invalid value
      m_BaseDatapropertyListObserverTags.push_back(-1);
    }
  }

  // add node to the vector
  if (addNewNode)
    m_Nodes.push_back(nonConstDataNode);
  else if (insertNewNode)
    m_Nodes.insert(m_Nodes.begin() + index, nonConstDataNode);

  if (addNewNode)
  {
    this->addItem(QString::fromStdString(nonConstDataNode->GetName()));
    // select new node if m_AutoSelectNewNodes is true or if we have just added the first node
    if (m_AutoSelectNewNodes || m_Nodes.size() == 1)
      this->setCurrentIndex(index);
  }
  else
  {
    // update text in combobox
    this->setItemText(index, QString::fromStdString(nonConstDataNode->GetName()));
  }
}

void QmitkDataStorageComboBox::Init()
{
  connect(this, SIGNAL(currentIndexChanged(int)), this, SLOT(OnCurrentIndexChanged(int)));
}

void QmitkDataStorageComboBox::Reset()
{
  // remove all nodes first
  while (!m_Nodes.empty())
  {
    // remove last node
    // explicitly calling RemoveNode of QmitkDataStorageComboBox since derived classes may prevent the removal of all
    // nodes in their respective RemoveNode implementation. This is happening for example in
    // QmitkDataStorageComboBoxWithSelectNone.
    QmitkDataStorageComboBox::RemoveNode(m_Nodes.size() - 1);
  }

  // clear combobox
  this->clear();

  if (!m_DataStorage.IsExpired())
  {
    auto dataStorage = m_DataStorage.Lock();
    mitk::DataStorage::SetOfObjects::ConstPointer setOfObjects;

    // select all if predicate == nullptr
    if (m_Predicate.IsNotNull())
      setOfObjects = dataStorage->GetSubset(m_Predicate);
    else
      setOfObjects = dataStorage->GetAll();

    // add all found nodes
    for (mitk::DataStorage::SetOfObjects::ConstIterator nodeIt = setOfObjects->Begin(); nodeIt != setOfObjects->End();
         ++nodeIt) // for each dataNode
    {
      // add node to the node vector and to the combobox
      this->AddNode(nodeIt.Value().GetPointer());
    }
  }
}

void QmitkDataStorageComboBox::RemoveNodeAndPropertyLists(int index)
{
  // remove itk::Event observer
  mitk::DataNode *dataNode = m_Nodes.at(index);

  // remove observer from data node property list
  mitk::PropertyList* dataNodePropertyList = dataNode->GetPropertyList();
  if (nullptr != dataNodePropertyList)
  {
    dataNodePropertyList->RemoveObserver(m_DataNodePropertyListObserverTags[index]);
    // remove observer tags from lists
    m_DataNodePropertyListObserverTags.erase(m_DataNodePropertyListObserverTags.begin() + index);
  }

  // remove observer from base data property list
  mitk::BaseData* baseData = dynamic_cast<mitk::BaseData*>(dataNode->GetData());
  if (nullptr != baseData)
  {
    mitk::PropertyList* baseDataPropertyList = baseData->GetPropertyList();
    if (nullptr != dataNodePropertyList)
    {
      baseDataPropertyList->RemoveObserver(m_BaseDatapropertyListObserverTags[index]);
      // remove observer tags from lists
      m_BaseDatapropertyListObserverTags.erase(m_BaseDatapropertyListObserverTags.begin() + index);
    }
  }

  // remove node from node vector
  m_Nodes.erase(m_Nodes.begin() + index);
}

void QmitkDataStorageComboBox::UpdateComboBoxText(const mitk::PropertyList* propertyList)
{
  mitk::PropertyList* dataNodePropertyList = nullptr;
  mitk::PropertyList* baseDataPropertyList = nullptr;
  mitk::BaseData* baseData;
  for (const auto& node : m_Nodes)
  {
    dataNodePropertyList = node->GetPropertyList();

    baseData = dynamic_cast<mitk::BaseData*>(node->GetData());
    if (nullptr != baseData)
    {
      baseDataPropertyList = baseData->GetPropertyList();
    }

    if (propertyList == dataNodePropertyList
     || propertyList == baseDataPropertyList)
    {
      // if one of the property list is the one that has just been modified
      // get the node's index and set its text to the node name
      // the node name might have been changed, depending on the modified property list
      auto index = Find(node);
      // update text in combobox
      this->setItemText(index, QString::fromStdString(node->GetName()));
      return;
    }
  }
}
<|endoftext|>


<commit_before>#include "NextStageScene.h"
#include "NNInputSystem.h"
#include "NNSceneDirector.h"
#include "PlayScene.h"

CNextStageScene::CNextStageScene(void)
{
	m_pPlayer = CPlayer::GetInstance();
	SetNextStage();
	m_pPlayer->ReadyToUpgrade();
	InitButtons();
	ShowResults();
}

void CNextStageScene::InitButtons(void )
{
	std::wstring buttonpath_normal[NUMBER_OF_ZOMBIE_TYPES];
	std::wstring buttonpath_pressed[NUMBER_OF_ZOMBIE_TYPES];

	buttonpath_normal[POOR_ZOMBIE] = L"wugargar/UIbuttons/button_normal_poorZombie.png";
	buttonpath_pressed[POOR_ZOMBIE]  = L"wugargar/UIbuttons/button_pressed_poorZombie.png";
	buttonpath_normal[VOMIT_ZOMBIE] = L"wugargar/UIbuttons/button_normal_vomitZombie.png";
	buttonpath_pressed[VOMIT_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_vomitZombie.png";
	buttonpath_normal[MUSCLE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_muscleZombie.png";
	buttonpath_pressed[MUSCLE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_muscleZombie.png";
	buttonpath_normal[KAMIKAJE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_kamikazeZombie.png";
	buttonpath_pressed[KAMIKAJE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_kamikazeZombie.png";
	buttonpath_normal[SMOG_ZOMBIE] = L"wugargar/UIbuttons/button_normal_smogZombie.png";
	buttonpath_pressed[SMOG_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_smogZombie.png";
	buttonpath_normal[ICE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_iceZombie.png";
	buttonpath_pressed[ICE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_iceZombie.png";
	buttonpath_normal[HERO_ZOMBIE_SM9] = L"wugargar/UIbuttons/button_normal_sm9.png";
	buttonpath_pressed[HERO_ZOMBIE_SM9] = L"wugargar/UIbuttons/button_pressed_sm9.png";
	buttonpath_normal[BABY_HUMAN] = L"wugargar/UIbuttons/button_normal_baby.png";
	buttonpath_pressed[BABY_HUMAN] = L"wugargar/UIbuttons/button_pressed_baby.png";

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

		float xCoordOfButton = static_cast<float>(GAP_BETWEEN_UPGRADE_BUTTONS + i*(GAP_BETWEEN_UPGRADE_BUTTONS+SIZE_OF_UPGRADE_BUTTONS) );
		float yCoordOfButton = static_cast<float>(FIRST_Y_COORD_OF_UPGRADE_BUTTONS);

		// Upgrade button
		m_pUpgradeButtons[i] = CUIButton::Create(buttonpath_normal[i], buttonpath_pressed[i]);
		m_pUpgradeButtons[i]->SetPosition(xCoordOfButton, yCoordOfButton);
		AddChild( m_pUpgradeButtons[i] , 20);

		// Upgrade
		SetUpgradeText(static_cast<ZombieType>(i));

		// Upgrade Label

		m_pUpgradeButtonLabel[i] = NNLabel::Create(m_LabelBuffer[i], L" ", 15.0f);
		m_pUpgradeButtonLabel[i]->SetPosition(xCoordOfButton, yCoordOfButton + SIZE_OF_UPGRADE_BUTTONS);
		AddChild( m_pUpgradeButtonLabel[i] );
	}

}

void CNextStageScene::ShowResults( void )
{
	swprintf_s(
		m_ResultBuffer,
		_countof(m_ResultBuffer),
		L"Results\nGlobalMoney : %d \nTotal Kill : %d\nTotal Loss : %d\n",
		m_pPlayer->GetGlobalMoney(),
		m_pPlayer->GetNumberOfKillInStage(),
		m_pPlayer->GetNumberOfLossInStage()
		);
	m_pResults = NNLabel::Create(m_ResultBuffer, L" ", 15.0f);
	m_pResults->SetPosition(15, FIRST_Y_COORD_OF_RESULTS);

	AddChild(m_pResults);
}

//   ׷̵
void CNextStageScene::SetUpgradeText(ZombieType zombietype)
{
	m_UpgradeCost[zombietype] = 200 + 100*m_pPlayer->GetZombieLevel(zombietype);
	swprintf_s(
		m_LabelBuffer[zombietype],
		_countof(m_LabelBuffer[zombietype]),
		L"Level : %d\nCost : $%d",
		m_pPlayer->GetZombieLevel(zombietype),
		m_UpgradeCost[zombietype]
	);
}

void CNextStageScene::SetNextStage( void )
{
	std::wstring saveButtonPath = L"wugargar/UIbuttons/savegame.png";
	std::wstring nextLevelButtonPath = L"wugargar/UIbuttons/nextlevel.png";
	std::wstring tryagainButtonPath = L"wugargar/UIbuttons/tryagain.png";

	if ( m_pPlayer->GetPlayerStatus() == WIN ) {
		m_pNextStageButton = CUIButton::Create(nextLevelButtonPath, nextLevelButtonPath);
		m_pPlayer->IncreaseStage();
	} else {
		m_pNextStageButton = CUIButton::Create(tryagainButtonPath, tryagainButtonPath);
	}
	m_pNextStageButton->SetPosition(static_cast<float> (GAME_SCREEN_MAX_SIZE_X/2), static_cast<float> (GAME_SCREEN_MAX_SIZE_Y/2) );
	AddChild(m_pNextStageButton);

	m_pGameSaveButton = CUIButton::Create(saveButtonPath, saveButtonPath);
	m_pGameSaveButton->SetPosition(static_cast<float> (GAME_SCREEN_MAX_SIZE_X/2), static_cast<float> (GAME_SCREEN_MAX_SIZE_Y/2 + 100) );
	AddChild(m_pGameSaveButton);

}

CNextStageScene::~CNextStageScene(void)
{
}

void CNextStageScene::Render()
{
	NNObject::Render();
}

void CNextStageScene::Update( float dTime )
{
	// zombie upgrade

	if ( NNInputSystem::GetInstance()->GetKeyState(VK_LBUTTON) ) {
		// ׷̵ ư ó
		for ( int i=0 ; i<NUMBER_OF_ZOMBIE_TYPES ; ++i ) {
			if ( m_pUpgradeButtons[i]->CheckButtonArea() && (m_pPlayer->GetGlobalMoney() >= m_UpgradeCost[i]) ) {
				m_pPlayer->SetGlobalMoney( m_pPlayer->GetGlobalMoney() - m_UpgradeCost[i] );
				m_pPlayer->IncreaseZombieLevel(static_cast<ZombieType>(i));
				SetUpgradeText(static_cast<ZombieType>(i));

				// global money ǥÿ ӽ ߿  ġ 󺧷   .
				swprintf_s(
					m_ResultBuffer,
					_countof(m_ResultBuffer),
					L"Results\nGlobalMoney : %d \nTotal Kill : %d \nTotal Loss : %d \n",
					m_pPlayer->GetGlobalMoney(),
					m_pPlayer->GetNumberOfKillInStage(),
					m_pPlayer->GetNumberOfLossInStage()
					);
			}
		}

		// ̺ ư Ŭ
		if ( m_pGameSaveButton->CheckButtonArea() ) {
			m_SaveManager::Create()
		}

		//   ư Ŭ
		if ( m_pNextStageButton->CheckButtonArea() ) {
			NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance());
		}
	}

	if( NNInputSystem::GetInstance()->GetKeyState(VK_RETURN) == KEY_DOWN ) {
		NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance());
	}
}
<commit_msg>Update NextStageScene.cpp<commit_after>#include "NextStageScene.h"
#include "NNInputSystem.h"
#include "NNSceneDirector.h"
#include "PlayScene.h"

CNextStageScene::CNextStageScene(void)
{
	m_pPlayer = CPlayer::GetInstance();
	SetNextStage();
	m_pPlayer->ReadyToUpgrade();
	InitButtons();
	ShowResults();
}

void CNextStageScene::InitButtons(void )
{
	std::wstring buttonpath_normal[NUMBER_OF_ZOMBIE_TYPES];
	std::wstring buttonpath_pressed[NUMBER_OF_ZOMBIE_TYPES];

	buttonpath_normal[POOR_ZOMBIE] = L"wugargar/UIbuttons/button_normal_poorZombie.png";
	buttonpath_pressed[POOR_ZOMBIE]  = L"wugargar/UIbuttons/button_pressed_poorZombie.png";
	buttonpath_normal[VOMIT_ZOMBIE] = L"wugargar/UIbuttons/button_normal_vomitZombie.png";
	buttonpath_pressed[VOMIT_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_vomitZombie.png";
	buttonpath_normal[MUSCLE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_muscleZombie.png";
	buttonpath_pressed[MUSCLE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_muscleZombie.png";
	buttonpath_normal[KAMIKAJE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_kamikazeZombie.png";
	buttonpath_pressed[KAMIKAJE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_kamikazeZombie.png";
	buttonpath_normal[SMOG_ZOMBIE] = L"wugargar/UIbuttons/button_normal_smogZombie.png";
	buttonpath_pressed[SMOG_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_smogZombie.png";
	buttonpath_normal[ICE_ZOMBIE] = L"wugargar/UIbuttons/button_normal_iceZombie.png";
	buttonpath_pressed[ICE_ZOMBIE] = L"wugargar/UIbuttons/button_pressed_iceZombie.png";
	buttonpath_normal[HERO_ZOMBIE_SM9] = L"wugargar/UIbuttons/button_normal_sm9.png";
	buttonpath_pressed[HERO_ZOMBIE_SM9] = L"wugargar/UIbuttons/button_pressed_sm9.png";
	buttonpath_normal[BABY_HUMAN] = L"wugargar/UIbuttons/button_normal_baby.png";
	buttonpath_pressed[BABY_HUMAN] = L"wugargar/UIbuttons/button_pressed_baby.png";

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

		float xCoordOfButton = static_cast<float>(GAP_BETWEEN_UPGRADE_BUTTONS + i*(GAP_BETWEEN_UPGRADE_BUTTONS+SIZE_OF_UPGRADE_BUTTONS) );
		float yCoordOfButton = static_cast<float>(FIRST_Y_COORD_OF_UPGRADE_BUTTONS);

		// Upgrade button ����
		m_pUpgradeButtons[i] = CUIButton::Create(buttonpath_normal[i], buttonpath_pressed[i]);
		m_pUpgradeButtons[i]->SetPosition(xCoordOfButton, yCoordOfButton);
		AddChild( m_pUpgradeButtons[i] , 20);

		// Upgrade ���� ����
		SetUpgradeText(static_cast<ZombieType>(i));

		// Upgrade Label ����

		m_pUpgradeButtonLabel[i] = NNLabel::Create(m_LabelBuffer[i], L"���� ����", 15.0f);
		m_pUpgradeButtonLabel[i]->SetPosition(xCoordOfButton, yCoordOfButton + SIZE_OF_UPGRADE_BUTTONS);
		AddChild( m_pUpgradeButtonLabel[i] );
	}

}

void CNextStageScene::ShowResults( void )
{
	swprintf_s(
		m_ResultBuffer,
		_countof(m_ResultBuffer),
		L"Results\nGlobalMoney : %d \nTotal Kill : %d\nTotal Loss : %d\n",
		m_pPlayer->GetGlobalMoney(),
		m_pPlayer->GetNumberOfKillInStage(),
		m_pPlayer->GetNumberOfLossInStage()
		);
	m_pResults = NNLabel::Create(m_ResultBuffer, L"���� ����", 15.0f);
	m_pResults->SetPosition(15, FIRST_Y_COORD_OF_RESULTS);

	AddChild(m_pResults);
}

// ���� �� ���׷��̵� ���� ����
void CNextStageScene::SetUpgradeText(ZombieType zombietype)
{
	m_UpgradeCost[zombietype] = 200 + 100*m_pPlayer->GetZombieLevel(zombietype);
	swprintf_s(
		m_LabelBuffer[zombietype],
		_countof(m_LabelBuffer[zombietype]),
		L"Level : %d\nCost : $%d",
		m_pPlayer->GetZombieLevel(zombietype),
		m_UpgradeCost[zombietype]
	);
}

void CNextStageScene::SetNextStage( void )
{
	std::wstring saveButtonPath = L"wugargar/UIbuttons/savegame.png";
	std::wstring nextLevelButtonPath = L"wugargar/UIbuttons/nextlevel.png";
	std::wstring tryagainButtonPath = L"wugargar/UIbuttons/tryagain.png";

	if ( m_pPlayer->GetPlayerStatus() == WIN ) {
		m_pNextStageButton = CUIButton::Create(nextLevelButtonPath, nextLevelButtonPath);
		m_pPlayer->IncreaseStage();
	} else {
		m_pNextStageButton = CUIButton::Create(tryagainButtonPath, tryagainButtonPath);
	}
	m_pNextStageButton->SetPosition(static_cast<float> (GAME_SCREEN_MAX_SIZE_X/2), static_cast<float> (GAME_SCREEN_MAX_SIZE_Y/2) );
	AddChild(m_pNextStageButton);

	m_pGameSaveButton = CUIButton::Create(saveButtonPath, saveButtonPath);
	m_pGameSaveButton->SetPosition(static_cast<float> (GAME_SCREEN_MAX_SIZE_X/2), static_cast<float> (GAME_SCREEN_MAX_SIZE_Y/2 + 100) );
	AddChild(m_pGameSaveButton);

}

CNextStageScene::~CNextStageScene(void)
{
}

void CNextStageScene::Render()
{
	NNObject::Render();
}

void CNextStageScene::Update( float dTime )
{
	// zombie upgrade

	if ( NNInputSystem::GetInstance()->GetKeyState(VK_LBUTTON) ) {
		// ���׷��̵� ��ư ó��
		for ( int i=0 ; i<NUMBER_OF_ZOMBIE_TYPES ; ++i ) {
			if ( m_pUpgradeButtons[i]->CheckButtonArea() && (m_pPlayer->GetGlobalMoney() >= m_UpgradeCost[i]) ) {
				m_pPlayer->SetGlobalMoney( m_pPlayer->GetGlobalMoney() - m_UpgradeCost[i] );
				m_pPlayer->IncreaseZombieLevel(static_cast<ZombieType>(i));
				SetUpgradeText(static_cast<ZombieType>(i));

				// global money ǥ�ÿ� �ӽ� ���߿� ������ ��ġ�� �󺧷� ���� ���� ������.
				swprintf_s(
					m_ResultBuffer,
					_countof(m_ResultBuffer),
					L"Results\nGlobalMoney : %d \nTotal Kill : %d \nTotal Loss : %d \n",
					m_pPlayer->GetGlobalMoney(),
					m_pPlayer->GetNumberOfKillInStage(),
					m_pPlayer->GetNumberOfLossInStage()
					);
			}
		}

		// ���̺� ��ư Ŭ����
		if ( m_pGameSaveButton->CheckButtonArea() ) {
			m_SaveManager::Create();
		}

		// ���� �������� ��ư Ŭ����
		if ( m_pNextStageButton->CheckButtonArea() ) {
			NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance());
		}
	}

	if( NNInputSystem::GetInstance()->GetKeyState(VK_RETURN) == KEY_DOWN ) {
		NNSceneDirector::GetInstance()->ChangeScene(CPlayScene::GetInstance());
	}
}
<|endoftext|>


<commit_before>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  TransformAxis.cpp                         *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Peter Loan, Frank C. Anderson, Jeffrey A. Reinbolt, Ajay Seth,  *
 *            Michael Sherman                                                 *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include <OpenSim/Common/XMLDocument.h>
#include <OpenSim/Common/Function.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Simulation/Model/Model.h>

#include "TransformAxis.h"
#include "Joint.h"
#include "Coordinate.h"
#include "SimbodyEngine.h"

//=============================================================================
// USING
//=============================================================================
using namespace std;
using namespace OpenSim;
using SimTK::Vec3; using SimTK::State; using SimTK::Vector; using SimTK::Xml;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
// Default constructor.
TransformAxis::TransformAxis() {
    setNull();
    constructProperties();
}

//_____________________________________________________________________________
// Constructor with coordinate names and axis.
TransformAxis::TransformAxis(const Array<string>& coordNames,
                             const Vec3&          axis) {
    setNull();
    constructProperties();
    setCoordinateNames(coordNames);
    setAxis(axis);
}
// Constructor from XML node.
TransformAxis::TransformAxis(Xml::Element& aNode) {
    setNull();
    constructProperties();
    updateFromXMLNode(aNode);
}

//_____________________________________________________________________________
/**
 * Perform set up functions after model has been deserialized or copied.
 *
 * @param aEngine dynamics engine containing this dof.
 * @param aJoint joint containing this dof.
 */
void TransformAxis::connectToJoint(const Joint& aJoint)
{
    string errorMessage;

    _joint = &aJoint;

    // Look up the coordinates by name.
    const Property<string>& coordNames = getProperty_coordinates();
    int nc = coordNames.size();
    const CoordinateSet& coords = _joint->getCoordinateSet();

    if (!hasFunction()) {
        SimTK_ASSERT2_ALWAYS(coordNames.size() == 0,
            "CustomJoint (%s) %s axis has no function but has coordinates.",
            _joint->getName(), getName());
        return;
    }

    for(int i=0; i< nc; ++i) {
        if (!coords.contains(coordNames[i])) {
            errorMessage += "Invalid coordinate ("
                            + coordNames[i]
                            + ") specified for TransformAxis "
                            + getName() + " in joint " + aJoint.getName();
            throw (Exception(errorMessage));
        }
    }
}

//=============================================================================
// CONSTRUCTION METHODS
//=============================================================================

//_____________________________________________________________________________
/**
 * Set the data members of this TransformAxis to their null values.
 */
void TransformAxis::setNull()
{
    _joint = NULL;
}

//_____________________________________________________________________________
// Define properties.
void TransformAxis::constructProperties() {
    constructProperty_coordinates();
    constructProperty_axis(Vec3(1,0,0)); // use x-axis by default
    constructProperty_function(Constant(0));
}

//=============================================================================
// GET AND SET
//=============================================================================
//_____________________________________________________________________________
/**
 * Get the current value of the transform.
 *
 * @return Current value of the transform.
 */
double TransformAxis::getValue(const State& s )
{
    const Property<string>& coordNames = getCoordinateNames();
    const int nc = coordNames.size();
    const CoordinateSet& coords = _joint->getCoordinateSet();

    Vector workX(nc, 0.0);
    for (int i=0; i < nc; ++i)
        workX[i] = coords.get(coordNames[i]).getValue(s);

    return getFunction().calcValue(workX);
}

//_____________________________________________________________________________
const OpenSim::Function& TransformAxis::getFunction() const
{
    const Property<Function>& function = getProperty_function();
    if (function.empty())
        throw Exception("TransformAxis::getFunction(): no Function is defined");
    return function.getValue();
}

OpenSim::Function& TransformAxis::updFunction()
{
    Property<Function>& function = updProperty_function();
    if (function.empty())
        throw Exception("TransformAxis::getFunction(): no Function is defined");
    return function.updValue();
}

//_____________________________________________________________________________
// This method takes over ownership.
void TransformAxis::setFunction(OpenSim::Function* func)
{
    Property<Function>& prop = updProperty_function();
    prop.clear();
    prop.adoptAndAppendValue(func);
}

// This method makes a copy.
void TransformAxis::setFunction(const OpenSim::Function& func)
{
    updProperty_function() = func;
}

void TransformAxis::updateFromXMLNode
   (Xml::Element& node, int versionNumber)
{
    // Version before refactoring spatialTransform.
    // TODO: this is handled in CustomJoint's updateFromXMLNode() method
    // but should be dealt with here. Can't do it both places, though.

    //XMLDocument::renameChildNode(node, "coordinate", "coordinates");

    Super::updateFromXMLNode(node, versionNumber);
}<commit_msg>Pass c-string type to SimTK_Assert argument and not a std::string <commit_after>/* -------------------------------------------------------------------------- *
 *                        OpenSim:  TransformAxis.cpp                         *
 * -------------------------------------------------------------------------- *
 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation.  *
 * See http://opensim.stanford.edu and the NOTICE file for more information.  *
 * OpenSim is developed at Stanford University and supported by the US        *
 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA    *
 * through the Warrior Web program.                                           *
 *                                                                            *
 * Copyright (c) 2005-2012 Stanford University and the Authors                *
 * Author(s): Peter Loan, Frank C. Anderson, Jeffrey A. Reinbolt, Ajay Seth,  *
 *            Michael Sherman                                                 *
 *                                                                            *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may    *
 * not use this file except in compliance with the License. You may obtain a  *
 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0.         *
 *                                                                            *
 * Unless required by applicable law or agreed to in writing, software        *
 * distributed under the License is distributed on an "AS IS" BASIS,          *
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
 * See the License for the specific language governing permissions and        *
 * limitations under the License.                                             *
 * -------------------------------------------------------------------------- */

//=============================================================================
// INCLUDES
//=============================================================================
#include <OpenSim/Common/XMLDocument.h>
#include <OpenSim/Common/Function.h>
#include <OpenSim/Common/Constant.h>
#include <OpenSim/Simulation/Model/Model.h>

#include "TransformAxis.h"
#include "Joint.h"
#include "Coordinate.h"
#include "SimbodyEngine.h"

//=============================================================================
// USING
//=============================================================================
using namespace std;
using namespace OpenSim;
using SimTK::Vec3; using SimTK::State; using SimTK::Vector; using SimTK::Xml;

//=============================================================================
// CONSTRUCTOR(S) AND DESTRUCTOR
//=============================================================================
//_____________________________________________________________________________
// Default constructor.
TransformAxis::TransformAxis() {
    setNull();
    constructProperties();
}

//_____________________________________________________________________________
// Constructor with coordinate names and axis.
TransformAxis::TransformAxis(const Array<string>& coordNames,
                             const Vec3&          axis) {
    setNull();
    constructProperties();
    setCoordinateNames(coordNames);
    setAxis(axis);
}
// Constructor from XML node.
TransformAxis::TransformAxis(Xml::Element& aNode) {
    setNull();
    constructProperties();
    updateFromXMLNode(aNode);
}

//_____________________________________________________________________________
/**
 * Perform set up functions after model has been deserialized or copied.
 *
 * @param aEngine dynamics engine containing this dof.
 * @param aJoint joint containing this dof.
 */
void TransformAxis::connectToJoint(const Joint& aJoint)
{
    string errorMessage;

    _joint = &aJoint;

    // Look up the coordinates by name.
    const Property<string>& coordNames = getProperty_coordinates();
    int nc = coordNames.size();
    const CoordinateSet& coords = _joint->getCoordinateSet();

    if (!hasFunction()) {
        SimTK_ASSERT2_ALWAYS(coordNames.size() == 0,
            "CustomJoint (%s) %s axis has no function but has coordinates.",
            _joint->getName().c_str(), getName().c_str());
        return;
    }

    for(int i=0; i< nc; ++i) {
        if (!coords.contains(coordNames[i])) {
            errorMessage += "Invalid coordinate ("
                            + coordNames[i]
                            + ") specified for TransformAxis "
                            + getName() + " in joint " + aJoint.getName();
            throw (Exception(errorMessage));
        }
    }
}

//=============================================================================
// CONSTRUCTION METHODS
//=============================================================================

//_____________________________________________________________________________
/**
 * Set the data members of this TransformAxis to their null values.
 */
void TransformAxis::setNull()
{
    _joint = NULL;
}

//_____________________________________________________________________________
// Define properties.
void TransformAxis::constructProperties() {
    constructProperty_coordinates();
    constructProperty_axis(Vec3(1,0,0)); // use x-axis by default
    constructProperty_function(Constant(0));
}

//=============================================================================
// GET AND SET
//=============================================================================
//_____________________________________________________________________________
/**
 * Get the current value of the transform.
 *
 * @return Current value of the transform.
 */
double TransformAxis::getValue(const State& s )
{
    const Property<string>& coordNames = getCoordinateNames();
    const int nc = coordNames.size();
    const CoordinateSet& coords = _joint->getCoordinateSet();

    Vector workX(nc, 0.0);
    for (int i=0; i < nc; ++i)
        workX[i] = coords.get(coordNames[i]).getValue(s);

    return getFunction().calcValue(workX);
}

//_____________________________________________________________________________
const OpenSim::Function& TransformAxis::getFunction() const
{
    const Property<Function>& function = getProperty_function();
    if (function.empty())
        throw Exception("TransformAxis::getFunction(): no Function is defined");
    return function.getValue();
}

OpenSim::Function& TransformAxis::updFunction()
{
    Property<Function>& function = updProperty_function();
    if (function.empty())
        throw Exception("TransformAxis::getFunction(): no Function is defined");
    return function.updValue();
}

//_____________________________________________________________________________
// This method takes over ownership.
void TransformAxis::setFunction(OpenSim::Function* func)
{
    Property<Function>& prop = updProperty_function();
    prop.clear();
    prop.adoptAndAppendValue(func);
}

// This method makes a copy.
void TransformAxis::setFunction(const OpenSim::Function& func)
{
    updProperty_function() = func;
}

void TransformAxis::updateFromXMLNode
   (Xml::Element& node, int versionNumber)
{
    // Version before refactoring spatialTransform.
    // TODO: this is handled in CustomJoint's updateFromXMLNode() method
    // but should be dealt with here. Can't do it both places, though.

    //XMLDocument::renameChildNode(node, "coordinate", "coordinates");

    Super::updateFromXMLNode(node, versionNumber);
}
<|endoftext|>


<commit_before>AliAnalysisTaskEmcalQGTagging* AddTaskEmcalQGTagging(const char * njetsBase,
                                                     const char * njetsUS,
						     const char * njetsTrue,
                                                     const char * njetsPartLevel,
						     const Double_t R,
						     const char * nrhoBase,
						     const char * ntracks,
                                                     const char * ntracksUS,
                                                     const char *ntracksPartLevel,
						     const char * nclusters,
						     const char * ntracksTrue,
						     const char *type,
						     const char *CentEst,
						     Int_t       pSel,
						     TString     trigClass      = "",
						     TString     kEmcalTriggers = "",
						     TString     tag            = "",
						     AliAnalysisTaskEmcalQGTagging::JetShapeType jetShapeType = AliAnalysisTaskEmcalQGTagging::kMCTrue,
						     AliAnalysisTaskEmcalQGTagging::JetShapeSub jetShapeSub = AliAnalysisTaskEmcalQGTagging::kNoSub,
						     AliAnalysisTaskEmcalQGTagging::JetSelectionType jetSelection = AliAnalysisTaskEmcalQGTagging::kInclusive,
                 Float_t minpTHTrigger =0.,  Float_t maxpTHTrigger =0., AliAnalysisTaskEmcalQGTagging::DerivSubtrOrder derivSubtrOrder = AliAnalysisTaskEmcalQGTagging::kSecondOrder ) {

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
    {
      Error("AddTaskEmcalQGTagging","No analysis manager found.");
      return 0;
    }
  Bool_t ismc=kFALSE;
  ismc = (mgr->GetMCtruthEventHandler())?kTRUE:kFALSE;

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler())
    {
      ::Error("AddTaskEmcalQGTagging", "This task requires an input event handler");
      return NULL;
    }

  TString wagonName1 = Form("JetQGTaggings_%s_TC%s%s",njetsBase,trigClass.Data(),tag.Data());
  TString wagonName2 = Form("JetQGTaggings_%s_TC%s%sTree",njetsBase,trigClass.Data(),tag.Data());
  //Configure jet tagger task
  AliAnalysisTaskEmcalQGTagging *task = new AliAnalysisTaskEmcalQGTagging(wagonName1.Data());

  //task->SetNCentBins(4);
  task->SetJetShapeType(jetShapeType);
  task->SetJetShapeSub(jetShapeSub);
  task->SetJetSelection(jetSelection);
  task->SetDerivativeSubtractionOrder(derivSubtrOrder);

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) task->SetPtTriggerSelections(minpTHTrigger, maxpTHTrigger);

  TString thename(njetsBase);
  //if(thename.Contains("Sub")) task->SetIsConstSub(kTRUE);
  //task->SetVzRange(-10.,10.);

  AliParticleContainer *trackCont;// = task->AddTrackContainer(ntracks);

  if ((jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) && ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kData) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kDetEmbPartPythia) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef))){
    trackCont = task->AddParticleContainer(ntracks);}
  else trackCont = task->AddTrackContainer(ntracks);

  //Printf("tracks() = %s, trackCont =%p", ntracks, trackCont);
  AliParticleContainer *trackContUS  = task->AddTrackContainer(ntracksUS);
  //Printf("tracksUS() = %s", ntracksUS);
  AliParticleContainer *trackContTrue = task->AddMCParticleContainer(ntracksTrue);
  //Printf("ntracksTrue() = %s, trackContTrue=%p ", ntracksTrue, trackContTrue);

  AliParticleContainer *trackContPartLevel=0;

  if ((jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) && ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kMCTrue) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef))){
    trackContPartLevel = task->AddParticleContainer(ntracksPartLevel);
  }
  else trackContPartLevel = task->AddMCParticleContainer(ntracksPartLevel);

   //Printf("ntracksPartLevel() = %s, trackContPartLevel=%p ", ntracksPartLevel, trackContPartLevel);

  AliClusterContainer *clusterCont = task->AddClusterContainer(nclusters);

  AliJetContainer *jetContBase=0x0;
  AliJetContainer *jetContUS=0x0;
  AliJetContainer *jetContTrue=0x0;
  AliJetContainer *jetContPart=0x0;
  TString strType(type);

  if ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kMCTrue || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kGenOnTheFly))) {
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackContPartLevel);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(0.6);
    }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kData){
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(0.6);
      if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) jetContBase->SetAreaEmcCut(-2);
    }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kDetEmbPartPythia){
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(0.6);

      if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) jetContBase->SetAreaEmcCut(-2);
    }

    jetContTrue = task->AddJetContainer(njetsTrue,strType,R);
    if(jetContTrue) {
      jetContTrue->SetRhoName(nrhoBase);
      jetContTrue->ConnectParticleContainer(trackContTrue);
      jetContTrue->SetPercAreaCut(0.6);

    }

    if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub){
      jetContUS=task->AddJetContainer(njetsUS,strType,R);
      if(jetContUS) {
        jetContUS->SetRhoName(nrhoBase);
        jetContUS->ConnectParticleContainer(trackContUS);
        jetContUS->SetPercAreaCut(0.6);

      }
    }

     jetContPart = task->AddJetContainer(njetsPartLevel,strType,R);
      if(jetContPart) {
        jetContPart->SetRhoName(nrhoBase);
        jetContPart->ConnectParticleContainer(trackContPartLevel);
        jetContPart->SetPercAreaCut(0.6);

      }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef){

    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(0.6);
    }

    jetContTrue = task->AddJetContainer(njetsTrue,strType,R);
    if(jetContTrue) {
      jetContTrue->SetRhoName(nrhoBase);
      jetContTrue->ConnectParticleContainer(trackContTrue);
      jetContTrue->SetPercAreaCut(0.6);

    }

    if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub){
      jetContUS=task->AddJetContainer(njetsUS,strType,R);
      if(jetContUS) {
        jetContUS->SetRhoName(nrhoBase);
        jetContUS->ConnectParticleContainer(trackContUS);
        jetContUS->SetPercAreaCut(0.6);

      }
    }

    jetContPart = task->AddJetContainer(njetsPartLevel,strType,R);
    if(jetContPart) {
      jetContPart->SetRhoName(nrhoBase);
      jetContPart->ConnectParticleContainer(trackContPartLevel);
      jetContPart->SetPercAreaCut(0.6);
    }

  }

  task->SetCaloTriggerPatchInfoName(kEmcalTriggers.Data());
  task->SetCentralityEstimator(CentEst);
  task->SelectCollisionCandidates(pSel);
  task->SetUseAliAnaUtils(kFALSE);

  mgr->AddTask(task);

  //Connnect input
  mgr->ConnectInput (task, 0, mgr->GetCommonInputContainer() );

  //Connect output
  TString contName1(wagonName1);
  TString contName2(wagonName2);

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kMCTrue) contName1 += "_MCTrue";
  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kData) contName1 += "_Data";

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kPythiaDef) contName1 +="_PythiaDef";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kNoSub) contName1 += "_NoSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kConstSub) contName1 += "_ConstSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kDerivSub) contName1 += "_DerivSub";

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kInclusive) contName1 += "_Incl";
  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) {

  TString recoilTriggerString = Form("_Recoil_%.0f_%0.f", minpTHTrigger, maxpTHTrigger);
  contName1 += recoilTriggerString;
  }

    if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kMCTrue) contName2 += "_MCTrue";
  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kData) contName2 += "_Data";

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kPythiaDef) contName2 +="_PythiaDef";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kNoSub) contName2 += "_NoSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kConstSub) contName2 += "_ConstSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kDerivSub) contName2 += "_DerivSub";

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kInclusive) contName2 += "_Incl";
  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) {

  TString recoilTriggerString = Form("_Recoil_%.0f_%0.f", minpTHTrigger, maxpTHTrigger);
  contName2 += recoilTriggerString;
  }

  TString outputfile = Form("%s",AliAnalysisManager::GetCommonFileName());
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer(contName1.Data(), TList::Class(),AliAnalysisManager::kOutputContainer,outputfile);
   mgr->ConnectOutput(task,1,coutput1);

   AliAnalysisDataContainer *coutput2 = mgr->CreateContainer(contName2.Data(), TTree::Class(),AliAnalysisManager::kOutputContainer,outputfile);
  mgr->ConnectOutput(task,2,coutput2);

  return task;

}

<commit_msg>removing the hardcoded are cut<commit_after>AliAnalysisTaskEmcalQGTagging* AddTaskEmcalQGTagging(const char * njetsBase,
                                                     const char * njetsUS,
						     const char * njetsTrue,
                                                     const char * njetsPartLevel,
						     const Double_t R,
						     const char * nrhoBase,
						     const char * ntracks,
                                                     const char * ntracksUS,
                                                     const char *ntracksPartLevel,
						     const char * nclusters,
						     const char * ntracksTrue,
						     const char *type,
						     const char *CentEst,
						     Int_t       pSel,
						     TString     trigClass      = "",
						     TString     kEmcalTriggers = "",
						     TString     tag            = "",
						     AliAnalysisTaskEmcalQGTagging::JetShapeType jetShapeType = AliAnalysisTaskEmcalQGTagging::kMCTrue,
						     AliAnalysisTaskEmcalQGTagging::JetShapeSub jetShapeSub = AliAnalysisTaskEmcalQGTagging::kNoSub,
						     AliAnalysisTaskEmcalQGTagging::JetSelectionType jetSelection = AliAnalysisTaskEmcalQGTagging::kInclusive,
						     Float_t minpTHTrigger =0.,  Float_t maxpTHTrigger =0., Float_t acut =0.6, AliAnalysisTaskEmcalQGTagging::DerivSubtrOrder derivSubtrOrder = AliAnalysisTaskEmcalQGTagging::kSecondOrder ) {

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr)
    {
      Error("AddTaskEmcalQGTagging","No analysis manager found.");
      return 0;
    }
  Bool_t ismc=kFALSE;
  ismc = (mgr->GetMCtruthEventHandler())?kTRUE:kFALSE;

  // Check the analysis type using the event handlers connected to the analysis manager.
  //==============================================================================
  if (!mgr->GetInputEventHandler())
    {
      ::Error("AddTaskEmcalQGTagging", "This task requires an input event handler");
      return NULL;
    }

  TString wagonName1 = Form("JetQGTaggings_%s_TC%s%s",njetsBase,trigClass.Data(),tag.Data());
  TString wagonName2 = Form("JetQGTaggings_%s_TC%s%sTree",njetsBase,trigClass.Data(),tag.Data());
  //Configure jet tagger task
  AliAnalysisTaskEmcalQGTagging *task = new AliAnalysisTaskEmcalQGTagging(wagonName1.Data());

  //task->SetNCentBins(4);
  task->SetJetShapeType(jetShapeType);
  task->SetJetShapeSub(jetShapeSub);
  task->SetJetSelection(jetSelection);
  task->SetDerivativeSubtractionOrder(derivSubtrOrder);

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) task->SetPtTriggerSelections(minpTHTrigger, maxpTHTrigger);

  TString thename(njetsBase);
  //if(thename.Contains("Sub")) task->SetIsConstSub(kTRUE);
  //task->SetVzRange(-10.,10.);

  AliParticleContainer *trackCont;// = task->AddTrackContainer(ntracks);

  if ((jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) && ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kData) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kDetEmbPartPythia) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef))){
    trackCont = task->AddParticleContainer(ntracks);}
  else trackCont = task->AddTrackContainer(ntracks);

  //Printf("tracks() = %s, trackCont =%p", ntracks, trackCont);
  AliParticleContainer *trackContUS  = task->AddTrackContainer(ntracksUS);
  //Printf("tracksUS() = %s", ntracksUS);
  AliParticleContainer *trackContTrue = task->AddMCParticleContainer(ntracksTrue);
  //Printf("ntracksTrue() = %s, trackContTrue=%p ", ntracksTrue, trackContTrue);

  AliParticleContainer *trackContPartLevel=0;

  if ((jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) && ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kMCTrue) || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef))){
    trackContPartLevel = task->AddParticleContainer(ntracksPartLevel);
  }
  else trackContPartLevel = task->AddMCParticleContainer(ntracksPartLevel);

   //Printf("ntracksPartLevel() = %s, trackContPartLevel=%p ", ntracksPartLevel, trackContPartLevel);

  AliClusterContainer *clusterCont = task->AddClusterContainer(nclusters);

  AliJetContainer *jetContBase=0x0;
  AliJetContainer *jetContUS=0x0;
  AliJetContainer *jetContTrue=0x0;
  AliJetContainer *jetContPart=0x0;
  TString strType(type);

  if ((jetShapeType==AliAnalysisTaskEmcalQGTagging::kMCTrue || (jetShapeType==AliAnalysisTaskEmcalQGTagging::kGenOnTheFly))) {
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackContPartLevel);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(acut);
    }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kData){
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(acut);
      if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) jetContBase->SetAreaEmcCut(-2);
    }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kDetEmbPartPythia){
    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->SetRhoName(nrhoBase);
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(acut);

      if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub) jetContBase->SetAreaEmcCut(-2);
    }

    jetContTrue = task->AddJetContainer(njetsTrue,strType,R);
    if(jetContTrue) {
      jetContTrue->SetRhoName(nrhoBase);
      jetContTrue->ConnectParticleContainer(trackContTrue);
      jetContTrue->SetPercAreaCut(acut);

    }

    if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub){
      jetContUS=task->AddJetContainer(njetsUS,strType,R);
      if(jetContUS) {
        jetContUS->SetRhoName(nrhoBase);
        jetContUS->ConnectParticleContainer(trackContUS);
        jetContUS->SetPercAreaCut(acut);

      }
    }

     jetContPart = task->AddJetContainer(njetsPartLevel,strType,R);
      if(jetContPart) {
        jetContPart->SetRhoName(nrhoBase);
        jetContPart->ConnectParticleContainer(trackContPartLevel);
        jetContPart->SetPercAreaCut(acut);

      }
  }

  if (jetShapeType==AliAnalysisTaskEmcalQGTagging::kPythiaDef){

    jetContBase = task->AddJetContainer(njetsBase,strType,R);
    if(jetContBase) {
      jetContBase->ConnectParticleContainer(trackCont);
      jetContBase->ConnectClusterContainer(clusterCont);
      jetContBase->SetPercAreaCut(acut);
    }

    jetContTrue = task->AddJetContainer(njetsTrue,strType,R);
    if(jetContTrue) {
      jetContTrue->SetRhoName(nrhoBase);
      jetContTrue->ConnectParticleContainer(trackContTrue);
      jetContTrue->SetPercAreaCut(acut);

    }

    if(jetShapeSub==AliAnalysisTaskEmcalQGTagging::kConstSub){
      jetContUS=task->AddJetContainer(njetsUS,strType,R);
      if(jetContUS) {
        jetContUS->SetRhoName(nrhoBase);
        jetContUS->ConnectParticleContainer(trackContUS);
        jetContUS->SetPercAreaCut(acut);

      }
    }

    jetContPart = task->AddJetContainer(njetsPartLevel,strType,R);
    if(jetContPart) {
      jetContPart->SetRhoName(nrhoBase);
      jetContPart->ConnectParticleContainer(trackContPartLevel);
      jetContPart->SetPercAreaCut(acut);
    }

  }

  task->SetCaloTriggerPatchInfoName(kEmcalTriggers.Data());
  task->SetCentralityEstimator(CentEst);
  task->SelectCollisionCandidates(pSel);
  task->SetUseAliAnaUtils(kFALSE);

  mgr->AddTask(task);

  //Connnect input
  mgr->ConnectInput (task, 0, mgr->GetCommonInputContainer() );

  //Connect output
  TString contName1(wagonName1);
  TString contName2(wagonName2);

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kMCTrue) contName1 += "_MCTrue";
  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kData) contName1 += "_Data";

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kPythiaDef) contName1 +="_PythiaDef";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kNoSub) contName1 += "_NoSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kConstSub) contName1 += "_ConstSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kDerivSub) contName1 += "_DerivSub";

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kInclusive) contName1 += "_Incl";
  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) {

  TString recoilTriggerString = Form("_Recoil_%.0f_%0.f", minpTHTrigger, maxpTHTrigger);
  contName1 += recoilTriggerString;
  }

    if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kMCTrue) contName2 += "_MCTrue";
  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kData) contName2 += "_Data";

  if (jetShapeType == AliAnalysisTaskEmcalQGTagging::kPythiaDef) contName2 +="_PythiaDef";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kNoSub) contName2 += "_NoSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kConstSub) contName2 += "_ConstSub";
  if (jetShapeSub == AliAnalysisTaskEmcalQGTagging::kDerivSub) contName2 += "_DerivSub";

  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kInclusive) contName2 += "_Incl";
  if (jetSelection == AliAnalysisTaskEmcalQGTagging::kRecoil) {

  TString recoilTriggerString = Form("_Recoil_%.0f_%0.f", minpTHTrigger, maxpTHTrigger);
  contName2 += recoilTriggerString;
  }

  TString outputfile = Form("%s",AliAnalysisManager::GetCommonFileName());
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer(contName1.Data(), TList::Class(),AliAnalysisManager::kOutputContainer,outputfile);
   mgr->ConnectOutput(task,1,coutput1);

   AliAnalysisDataContainer *coutput2 = mgr->CreateContainer(contName2.Data(), TTree::Class(),AliAnalysisManager::kOutputContainer,outputfile);
  mgr->ConnectOutput(task,2,coutput2);

  return task;

}

<|endoftext|>