#include "UtsusemiTofOriginCorrection.hh"

//////////////////////////////////////////////////////////
UtsusemiTofOriginCorrection::
UtsusemiTofOriginCorrection(){
}
//////////////////////////////////////////////////////////
UtsusemiTofOriginCorrection::
~UtsusemiTofOriginCorrection(){
}
//////////////////////////////////////////////////////////
void UtsusemiTofOriginCorrection::
Initialize(){
    _TofOriginCorrType = 0;

}
//////////////////////////////////////////////////////////
Double UtsusemiTofOriginCorrection::
UtsusemiPutTofShiftFunc01( Double lambda, std::vector<Double> *params ){
    Double A1=5.0;
    Double A2=8.464;
    Double A3=2.08765;
    Double A4=1.23477;
    Double A5=5.32657;

    if ((params!=NULL)&&(params->size()==5)){
        A1=params->at(0);
        A2=params->at(1);
        A3=params->at(2);
        A4=params->at(3);
        A5=params->at(4);
    }

    return (A1/(exp(-A2*(lambda-A3))+A4))+(A5*lambda);
}
UInt4 UtsusemiTofOriginCorrection::
UtsusemiPutTofShiftFunc01_NumOfParams(){
    return 5;
}

//////////////////////////////////////////////////////////
bool UtsusemiTofOriginCorrection::
SetTofOriginCorrectionType( UInt4 cType, std::vector<Double> params ){

    if ( SetTofOriginCorrectionType( cType ) ){
        _Params.resize( params.size(),0.0 );
        copy( params.begin(), params.end(), _Params.begin() );
        return true;
    }else{
        return false;
    }
}
//////////////////////////////////////////////////////////
bool UtsusemiTofOriginCorrection::
SetTofOriginCorrectionType( UInt4 cType ){
    if (cType==0){
        PutTofShiftFunc = NULL;
        PutTofShiftNumParams = NULL;
    }else if (cType==1){
        PutTofShiftFunc = UtsusemiPutTofShiftFunc01;
        PutTofShiftNumParams = UtsusemiPutTofShiftFunc01_NumOfParams;
    }else{
        return false;
    }

    _TofOriginCorrType = cType;
    _Params.clear();

    return true;
}
//////////////////////////////////////////////////////////
Double UtsusemiTofOriginCorrection::
TofOriginShiftByLambda( Double lambda ){
    Double ret = 0.0;
    if (_TofOriginCorrType==0){
        if ((_DiscreteLambda.empty())||(_DiscreteTofShift.empty())){
        }else{
            for (UInt4 i=0; i<(_DiscreteLambda.size()-1); i++)
                if (( lambda>=_DiscreteLambda[i] )&&( lambda<_DiscreteLambda[i+1] ))
                    ret = (_DiscreteTofShift[i+1]-_DiscreteTofShift[i])/(_DiscreteLambda[i+1]-_DiscreteLambda[i])*(lambda - _DiscreteLambda[i]) - _DiscreteTofShift[i];
        }
    }else{
        if (_Params.empty()){
            std::vector<Double> *p=NULL;
            ret = PutTofShiftFunc( lambda, p );
        }else{
            ret = PutTofShiftFunc( lambda, &_Params );
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> UtsusemiTofOriginCorrection::
TofOriginShiftByLambda( std::vector<Double> vlambda ){
    std::vector<Double> ret( vlambda.size(), 0.0 );
    for (UInt4 i=0; i<(vlambda.size()); i++)
        ret[i] = TofOriginShiftByLambda( vlambda[i] );
    return ret;
}
//////////////////////////////////////////////////////////
bool UtsusemiTofOriginCorrection::
SetDiscreteData( std::vector<Double> lambda_list, std::vector<Double> tofshift_list ){
    if (lambda_list.size()!=tofshift_list.size()){
        return false;
    }
    _DiscreteLambda.clear();
    _DiscreteTofShift.clear();
    _DiscreteLambda.resize( lambda_list.size() );
    _DiscreteTofShift.resize( lambda_list.size() );
    copy( lambda_list.begin(), lambda_list.end(), _DiscreteLambda.begin() );
    copy( tofshift_list.begin(), tofshift_list.end(), _DiscreteTofShift.begin() );
    return true;
}
//////////////////////////////////////////////////////////
UInt4 UtsusemiTofOriginCorrection::
PutNumOfParam(){
    UInt4 ret = 0;
    if (PutTofShiftNumParams!=NULL) ret = PutTofShiftNumParams();
    return ret;
}
