#include "AdvILambdaCorrectionDNA.hh"
// AS 120229 start

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

//////////////////////////////////////////////////////////
AdvILambdaCorrectionDNA::
~AdvILambdaCorrectionDNA()
{
}
//////////////////////////////////////////////////////////
void AdvILambdaCorrectionDNA::
Initialize(){
    commentHead = "AdvILambdaCorrectionDNA >> ";
    stools = new StringTools();
}
//////////////////////////////////////////////////////////

ElementContainerMatrix AdvILambdaCorrectionDNA::
ILCorrection(ElementContainerMatrix ecm, ElementContainer ec0, bool UseMonitorEfficiency, std::string filepath, bool isMonAtSmp){
  ElementContainerMatrix* ret_ecm;
  ILCorrection(ret_ecm,  &ecm,  ec0, UseMonitorEfficiency, filepath, isMonAtSmp);
  return *ret_ecm;
}

bool AdvILambdaCorrectionDNA::
ILCorrection(ElementContainerMatrix* ret_ecm, ElementContainerMatrix* ecm, ElementContainer ec0, bool UseMonitorEfficiency, std::string filepath, bool isMonAtSmp){
//////////////////////////////////////////////////
//initialize

    ElementContainerArray eca;
    ElementContainer ec;
    ElementContainer EC2;

    HeaderBase hhm;
    hhm = ecm->PutHeader();
    ret_ecm->InputHeader(hhm);

///////////

    ElementContainer ec_null;

    std::vector<double> y0 = ecm->PutPointer(0)->PutPointer(0)->PutY();
    std::vector<double> MaskedNull;

    for(UInt4 i=0;i<y0.size();i++)
        {
        MaskedNull.push_back(0);
        }

    ec_null.Add("Intensity", MaskedNull);
    ec_null.Add("Error", MaskedNull);
    //ec_null.Add("HW", ec_buf.PutX());
    ec_null.Add("HW", ecm->PutPointer(0)->PutPointer(0)->PutX());
    ec_null.SetKeys( "HW", "Intensity", "Error" );

///////////

    if (UseMonitorEfficiency)
        {
        AdvNeutronMonitorDNA *NeuMon = new AdvNeutronMonitorDNA(filepath);
        if (!(NeuMon->Status())){
            UtsusemiError("ERROR :: AdvILambdaCorrectionDNA::ICorrection >> AdvNeutronMonitorDNA constructor returns false.");
            return false;
        }
        if (isMonAtSmp) NeuMon->GetProfileUseMonAtSample(ec0,EC2);
        else NeuMon->GetIntensityAtSample(ec0,EC2);
        delete NeuMon;
        }
    else
        {
        EC2=ec0;
        }

    UInt4 num_of_psd, num_of_pixel;
    num_of_psd = ecm->PutTableSize();

//////////////////////////////////////////////////
// psd loop
    std::cout <<std::endl;
    std::cout << "AdvILambdaCorrectionDNA-start"<<std::endl;

    for (UInt4 psd=0;psd<num_of_psd;psd++)
        {
        if(psd%22==1){std::cout << "  "<<psd/22*10<<" %"<<std::endl;}
            eca = ecm->Put(psd);

        ElementContainerArray *ECA = new ElementContainerArray(eca.PutHeader() );

//////////////////////////////////////////////////////
// pixel loop

        num_of_pixel = eca.PutTableSize();
        for (UInt4 pixel=0; pixel<num_of_pixel; pixel++)
            {
            std::vector<double> Xin, X0in, X0out;
            double ef;

            Xin.clear();
            X0in.clear();
            X0out.clear();
            ec = eca.Put(pixel);
            ef = ec.PutHeaderPointer()->PutDouble("Ef"); // Get Ef value

            Xin = ec.PutX();
            X0in = EC2.PutX();

//////////////////////////////////////////////////////////////////

            ElementContainer *ec_corr = new ElementContainer(ec.PutHeader());

            int mask;
            mask = ec.PutHeaderPointer()->PutInt4("MASKED");

            if(mask==0)
                {
                for(UInt4 i=0; i<X0in.size(); i++)
                    {
                    X0out.push_back(X0in[i]-ef);
                    }

                ElementContainer *ec_shift = new ElementContainer(ec.PutHeader());
                ElementContainer *ec_shift_bin = new ElementContainer(ec.PutHeader());

                ec_shift->Add("HW", X0out);
                ec_shift->Add("Intensity", EC2.PutY());
                ec_shift->Add("Error", EC2.PutE());
                ec_shift->SetKeys( "HW", "Intensity", "Error" );

                *ec_shift_bin=ec_shift->Binning(Xin);

                //*ec_corr = (ec) / (*ec_shift);
                *ec_corr = (ec) / (*ec_shift_bin);

                delete ec_shift;
                delete ec_shift_bin;
                }
            else if(mask==1)
                {
                *ec_corr = ec_null ;
                }

//////////////////////////////////////////////////////////////////

            double Total = 0;
            std::vector<double> Y_corr = ec_corr->PutY();

            for (UInt4 i=0;i<Y_corr.size();i++)
                {
                Total = Y_corr[i] + Total;
                }

            HeaderBase hh;
            hh = ec.PutHeader();
            hh.Erase("TotalCounts");
            hh.Add("TotalCounts",Total);
            //[inamura 140410]-->
            if (hh.CheckKey("isHistogram")==1)
                hh.Erase("isHistogram");
            hh.Add("isHistogram",0);
            //<--[inamura 140410]
            ec_corr->InputHeader(hh);

            ECA->Add( *ec_corr );

            delete ec_corr;
            }
        //[inamura 140410]-->
        HeaderBase *hh_eca=ECA->PutHeaderPointer();
        if (hh_eca->CheckKey("isHistogram")==1)
            hh_eca->Erase("isHistogram");
        hh_eca->Add("isHistogram",0);
        //<--[inamura 140410]
        //ECM.Add(*ECA);
        ret_ecm->Add(*ECA);
        delete ECA;
        }
    //[inamura 140410]-->
    HeaderBase *hh_ecm=ret_ecm->PutHeaderPointer();
    if (hh_ecm->CheckKey("isHistogram")==1)
        hh_ecm->Erase("isHistogram");
    hh_ecm->Add("isHistogram",0);
    //<--[inamura 140410]

    std::cout << "AdvILambdaCorrectionDNA-end"<<std::endl;

    return true;

    }// ILCorrection end

//////////////////////////////////////////////////////////

ElementContainer AdvILambdaCorrectionDNA::
DummyECCreate(ElementContainerMatrix *ecm){

    ElementContainerArray *eca;
    ElementContainer *ec;

    std::cout << "dummy-ec-create-start"<<std::endl;

    eca = ecm->PutPointer(40);
    ec = eca->PutPointer(30);

    std::cout << "dummy-ec-create--end"<<std::endl;

    return *ec;
    }
