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

//////////////////////////////////////////////////////////
AdvSliceQE::AdvSliceQE()
{
    Initialize();
}

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

ElementContainer AdvSliceQE::
Slice(ElementContainerArray *eca, double lowerValue, double upperValue){

//////////////////////////////////////////////////
//initialize
    ElementContainer *ec   = new ElementContainer();
    ElementContainer *ec0  = new ElementContainer();

    UInt4 num_of_Q;
    Int4 num_of_mask;
    Int4 num_of_ec;
    Int4 mask;

    num_of_Q = eca->PutTableSize();
    std::vector<double> yvalue;
    std::vector<double> ysum_org;
    std::vector<double> ysum;

    std::vector<double> yError;
    std::vector<double> ysumError2;
    std::vector<double> ysumError;
    std::vector<double> y0value;

    ysum_org.clear();
    ysum.clear();

    ysumError.clear();
    ysumError2.clear();

    y0value = eca->PutPointer(0)->PutY();

    ysum_org.resize(y0value.size());
    ysum.resize(y0value.size());

    ysumError.resize(y0value.size());
    ysumError2.resize(y0value.size());
    num_of_mask = 0;
    num_of_ec   = 0;

    for (UInt4 Qbin=0; Qbin<num_of_Q; Qbin++)
        {
        yvalue.clear();
        yError.clear();
        ec0 = eca->PutPointer(Qbin);
        std::vector<double> xrange;
        xrange = ec0->PutHeaderPointer()->PutDoubleVector( "XRANGE" );
        Double xrangeCenter = (xrange.at(0)+xrange.at(1))*0.5;
        if (ec0->PutHeaderPointer()->CheckKey("MASKED")==0)
            {
            mask = 0;
            }
        else if (ec0->PutHeaderPointer()->CheckKey("MASKED")==1)
            {
            mask = ec0->PutHeaderPointer()->PutInt4( "MASKED" );
            }

        if(( xrangeCenter >= lowerValue) && ( xrangeCenter < upperValue))
            {
            yvalue = ec0->PutY();
            yError = ec0->PutE();
            num_of_ec = num_of_ec +1;
            if(mask == 1)
                {
                num_of_mask = num_of_mask +1;
                }

            else if (mask ==0)
                {
                for(UInt4 i=0;i<yvalue.size();i++)
                    {
                    ysum_org[i] += yvalue[i];
                    ysumError2[i] += yError[i]*yError[i];
                    }
                }
            }
        }

    for(UInt4 j=0;j<ysum_org.size();j++)
        {
        if(num_of_ec != num_of_mask)
            {
            ysum[j] = ysum_org[j]/(num_of_ec - num_of_mask);
            ysumError[j] = sqrt(ysumError2[j])/(num_of_ec - num_of_mask);
            }
        if(num_of_ec == num_of_mask)
            {
            ysum[j] = 0;
            ysumError[j] = 0;
            }
        }

    ec->Add(ec0->PutXKey(), ec0->PutX());
    ec->Add(ec0->PutYKey(), ysum);
    ec->Add(ec0->PutEKey(), ysumError);
    ec->SetKeys( ec0->PutXKey(), ec0->PutYKey(), ec0->PutEKey() );

    double Total = 0;
    for (UInt4 l=0;l<ysum.size();l++)
        {
        Total = ysum[l] + Total;
        }

    if (isnan(Total))
        {
        Total =0;
        }

    std::vector<double> xrange;
    xrange.push_back(lowerValue);
    xrange.push_back(upperValue);
    HeaderBase hh;
    hh = eca->PutHeader();
    ec->InputHeader(hh);
    ec->AddToHeader(std::string("XRANGE"), xrange );
    ec->AddToHeader(std::string("NumOfMask"), num_of_mask );
    ec->AddToHeader(std::string("NumOfOrigEC"), num_of_ec );
    ec->AddToHeader(std::string("TotalCounts"), Total );

    return *ec;
    }
