#include "RPMTSetMaskBy2theta.hh"
//////////////////////////////////////////////////////////
RPMTSetMaskBy2theta::
RPMTSetMaskBy2theta()
{
    _Status = false;
    _AE = new UtsusemiAnaEnvironReader(UTSUSEMIDEFAULTANAENVIRONFILE);
    _Status = _AE->_Status;
    _runNo = 0;
}

//////////////////////////////////////////////////////////
RPMTSetMaskBy2theta::
RPMTSetMaskBy2theta(ElementContainerMatrix *ecm, Double angle, bool isOutSide )
{
    _Status = false;
    _AE = new UtsusemiAnaEnvironReader(UTSUSEMIDEFAULTANAENVIRONFILE);
    _Status = _AE->_Status;
    if (_Status){
        SetTarget(ecm);
        _Status = SetRunNo(0);
        if (_Status){
            if (angle>0.0) _Status = SetAngle(angle, isOutSide);
        }
    }
}

//////////////////////////////////////////////////////////
RPMTSetMaskBy2theta::
~RPMTSetMaskBy2theta()
{
    delete _AE;
}
//////////////////////////////////////////////////////////
bool RPMTSetMaskBy2theta::SetRunNo(UInt4 runNo){
    if (runNo==0){
        ElementContainerMatrix* ecm = Put();
        if (ecm!=NULL){
            if (ecm->PutHeaderPointer()->CheckKey(UTSUSEMI_KEY_HEAD_RUNNUMBER)==1){
                std::string runNo_s = ecm->PutHeaderPointer()->PutString(UTSUSEMI_KEY_HEAD_RUNNUMBER);
                StringTools ST;
                std::vector<std::string> sp = ST.SplitString(runNo_s,",");
                runNo = ST.StringToUInt4(sp[0]);
            }
        }
        if (runNo==0){
            return false;
        }
    }
    _runNo = runNo;
    return true;
}
//////////////////////////////////////////////////////////
bool RPMTSetMaskBy2theta::SetAngle(Double angle, bool isOutSide){
    if (angle<=0.0) return false;
    _angle = angle;
    _isOutSide = isOutSide;
    return true;
}
//////////////////////////////////////////////////////////
bool RPMTSetMaskBy2theta::Execute(){
    UInt4 modeNo = 5;
    bool isFullPath = true;
    std::vector<std::string> pfiles = _AE->PutParamFiles( _runNo, modeNo, isFullPath );
    if (pfiles.size()<2){
        return false;
    }

    ElementContainerMatrix* ecm = Put();

    SASDetectorInfoEditorRPMT SDE(pfiles[1], true);
    double b = SDE.PutIncidentGravityParam();
    std::vector<Double> v0 = ecm->PutPointer(0)->PutPointer(0)->PutHeaderPointer()->PutDoubleVector(UTSUSEMI_KEY_HEAD_PIXELPOSITION);
    Double r_ang = v0[2] * tan(_angle / 180.0 * M_PI);

    std::string ekey = ecm->PutPointer(0)->PutPointer(0)->PutEKey();
    for (UInt4 i=0; i<(ecm->PutSize()); i++){
        ElementContainerArray* eca = ecm->PutPointer(i);
        HeaderBase* hh = eca->PutHeaderPointer();
        bool isMasked = false;
        if (hh->CheckKey(UTSUSEMI_KEY_HEAD_MASKED) == 0) isMasked = false;
        else if (hh->PutInt4(UTSUSEMI_KEY_HEAD_MASKED) == 1) isMasked = true;
        else isMasked = false;
        if (isMasked) continue;

        UInt4 cnt_ec = 0;
        for (UInt4 j=0; j<(eca->PutSize()); j++){
            ElementContainer* ec = eca->PutPointer(j);
            HeaderBase* hh_ec = ec->PutHeaderPointer();
            if ((hh_ec->CheckKey(UTSUSEMI_KEY_HEAD_MASKED) == 0) || (hh->PutInt4(UTSUSEMI_KEY_HEAD_MASKED) == 0)){
                std::vector<Double> *errv = ec->PutP(ekey);
                std::vector<Double> lamv = ec->Put("Lamb");
                std::vector<Double> pv = hh_ec->PutDoubleVector(UTSUSEMI_KEY_HEAD_PIXELPOSITION);
                UInt4 cnt_lam = 0;
                for (UInt4 k=0; k<(lamv.size()); k++){
                    bool setMask = false;
                    Double cy = -1.0 * b * lamv[k] * lamv[k];
                    Double d = sqrt((pv[0] * pv[0]) + (pv[1] - cy) * (pv[1] - cy) );
                    if (_isOutSide){
                        if (d > r_ang) setMask = true;
                    }else{
                        if (d <= r_ang) setMask = true;
                    }
                    if (setMask){
                        //errv->at(k) = -1.0 * errv->at(k);
                        if (errv->at(k) == 0.0) errv->at(k) = UTSUSEMIMASKERRORVALUE;
                        else if (errv->at(k) > 0.0) errv->at(k) = -1.0 * errv->at(k);
                        cnt_lam ++;
                    }
                }
                if (cnt_lam == lamv.size()){
                    hh_ec->OverWrite(UTSUSEMI_KEY_HEAD_MASKED, 1);
                    cnt_ec ++;
                }
            }
        }
        if (cnt_ec == eca->PutSize())
            hh->OverWrite(UTSUSEMI_KEY_HEAD_MASKED, 1);
    }
    return true;
}
