#include "BoseFactorChoppers.hh"
//////////////////////////////////////////////////////////
BoseFactorChoppers::
BoseFactorChoppers()
{
    Initialize();
}

//////////////////////////////////////////////////////////
BoseFactorChoppers::
BoseFactorChoppers( ElementContainerMatrix *ecm )
{
    Initialize();
    SetTarget(ecm);
    CheckECM();
}

//////////////////////////////////////////////////////////
BoseFactorChoppers::
BoseFactorChoppers( ElementContainerMatrix *ecm, double temp )
{
    Initialize();
    SetTarget(ecm);
    CheckECM();
    SetTemperature(temp);
}

//////////////////////////////////////////////////////////
BoseFactorChoppers::
~BoseFactorChoppers()
{

}

//////////////////////////////////////////////////////////
void BoseFactorChoppers::
Initialize(){
    Process_Key = "BoseFactorChoppers";
    commentHead = Process_Key+" >> ";
}

//////////////////////////////////////////////////////////
void BoseFactorChoppers::
CheckECM(){
    ElementContainerMatrix *ecm = Put();
    if (CheckDataProcessed( ecm, Process_Key )){
        throw "ARGUMENT ERROR: This Correction has been done";
    }
    if (!CheckDataProcessed( ecm, "TOF TO ENERGY TRANSFER" )){
        throw "ARGUMENT ERROR: TOF to Energy Transfer must be done before this correction.";
    }
    
}
//////////////////////////////////////////////////////////
void BoseFactorChoppers::
SetTemperature( double temp ){
    if (temp>0){
        TargetTemp = temp;
    }
    else{
        throw "ERROR: given temperature is invalid";
    }
}

//////////////////////////////////////////////////////////
void BoseFactorChoppers::
DoCorrection(){

    ElementContainerMatrix *ecm = Put();
    CheckECM();

    ElementContainerArray *eca;
    ElementContainer *ec;

    vector<Double> hw_vect, int_vect, err_vect;
    string hw_title,int_title,err_title;
    //string hw_unit,int_unit,err_unit;
    double ene,bf;
    
    for (UInt4 i=0; i<ecm->PutTableSize(); i++){
        eca = ecm->PutPointer(i);
        for (UInt4 j=0; j<eca->PutTableSize(); j++){
            ec = eca->PutPointer(j);

            hw_vect  = ec->PutX();
            int_vect = ec->PutY();
            err_vect = ec->PutE();
            hw_title = ec->PutXKey();
            int_title = ec->PutYKey();
            err_title = ec->PutEKey();
            
            for (UInt4 k=0; k<int_vect.size(); k++){
                ene = (hw_vect[k]+hw_vect[k+1])/2.0;
                if (ene!=0.0){
                    bf = 1.0/(1.0-exp(-1.0*fabs(ene)/TargetTemp*11.6048));
                    int_vect[k] = int_vect[k]/bf;
                    err_vect[k] = err_vect[k]/bf;
                }else{
                    int_vect[k] = 0.0;
                    err_vect[k] = 0.0;
                }
            }
            ec->Replace(int_title,int_vect);
            ec->Replace(err_title,err_vect);
            ec->SetKeys(hw_title,int_title,err_title);
        }
    }
}
