#include "UtsusemiSqeCalcXtalParams.hh"
//////////////////////////////////////////////////////////
UtsusemiSqeCalcXtalParams::UtsusemiSqeCalcXtalParams( std::string filepath ){
    Initialize( filepath );
}
//////////////////////////////////////////////////////////
UtsusemiSqeCalcXtalParams::~UtsusemiSqeCalcXtalParams(){
    if (_xml!=NULL) delete _xml;
    delete _st;
}

//////////////////////////////////////////////////////////
void UtsusemiSqeCalcXtalParams::
Initialize( std::string filepath ){
    _xml=NULL;
    _st = new StringTools();
    _uVec.clear();
    _uVec.resize(3,0.0);
    _vVec.clear();
    _vVec.resize(3,0.0);
    _isUBpriority=false;
    _ubMatrix.clear();
    _ubMatrix.resize(9,0.0);

    if (filepath==""){
        SetExampleParams();
        return;
    }

    bool ret = LoadFile( filepath );
    if (ret) return;
    else{

    }
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetLatticeConstants( Double a, Double b, Double c, Double alpha, Double beta, Double gamma ){
    _latticeConsts.clear();
    _latticeConsts.resize(6,0.0);
    _latticeConsts[0] = a;
    _latticeConsts[1] = b;
    _latticeConsts[2] = c;
    _latticeConsts[3] = alpha;
    _latticeConsts[4] = beta;
    _latticeConsts[5] = gamma;

    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetLatticeConstants( PyObject* LC ){
    std::vector<Double> lcv = __gCppToPython.ListToDoubleVector( LC );
    if ((lcv.empty())||(lcv.size()!=6)){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetLatticeConstants >> Arguments must be list with size of 6" );
        return false;
    }
    return SetLatticeConstants( lcv[0], lcv[1], lcv[2], lcv[3], lcv[4], lcv[5] );
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetUVvector( Double ux, Double uy, Double uz, Double vx, Double vy, Double vz, bool isPriority ){
    _uVec.clear();
    _uVec.resize(3);
    _uVec[0] = ux;
    _uVec[1] = uy;
    _uVec[2] = uz;

    _vVec.clear();
    _vVec.resize(3);
    _vVec[0] = vx;
    _vVec[1] = vy;
    _vVec[2] = vz;

    _isUBpriority = !(isPriority);
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetUVvector( PyObject* UV, PyObject* VV, bool isPriority ){
    std::vector<Double> uv = __gCppToPython.ListToDoubleVector( UV );
    std::vector<Double> vv = __gCppToPython.ListToDoubleVector( VV );
    if ((uv.empty())||(uv.size()!=3)){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetUVvector >> UV Argument must be list with size of 3" );
        return false;
    }
    if ((vv.empty())||(vv.size()!=3)){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetUVvector >> VV Argument must be list with size of 3" );
        return false;
    }
    return SetUVvector( uv[0], uv[1], uv[2], vv[0], vv[1], vv[2], isPriority );
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetUBMatrix( PyObject* UB, bool isPriority ){
    std::vector<Double> ubmat = __gCppToPython.ListToDoubleVector( UB );
    if ((ubmat.empty())||(ubmat.size()!=9)){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetUBMatrix >> Given UB Argument must be list with size of 9" );
        return false;
    }
    _ubMatrix.clear();
    _ubMatrix.resize(9,0.0);
    copy( ubmat.begin(), ubmat.end(), _ubMatrix.begin() );
    _isUBpriority=isPriority;
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
AddRotationStep( std::string axis, double degree ){
    std::pair<std::string,Double> tmp;
    transform( axis.begin(), axis.end(), axis.begin(), ::toupper);
    if ((axis=="X")||(axis=="Y")||(axis=="Z")){
        tmp.first = axis;
        tmp.second= degree;
        _rotateSteps.push_back(tmp);
    }else{
        UtsusemiError( "UtsusemiSqeCalcXtalParams::AddRotationStep >> Invalid format = "+axis );
        return false;
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetRotationSteps( std::string steps ){
    bool ret = ClearRotationStep();
    std::vector<std::string> step_v = _st->SplitString( steps, "," );
    for (UInt4 i=0; i<step_v.size(); i++){
        std::vector<std::string> v = _st->SplitString( step_v[i], ":" );
        if (v.size()!=2){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetRotationSteps >> Invalid format = "+step_v[i] );
            return false;
        }
        ret = AddRotationStep( v[0], _st->StringToDouble(v[1]) );
        if (!ret) break;
    }
    return ret;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
ClearRotationStep(){
    _rotateSteps.clear();
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetSampleInfoToData( ElementContainerMatrix* ecm ){
    HeaderBase* hh = ecm->PutHeaderPointer();
    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS,_latticeConsts);
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS,_latticeConsts);

    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_UVECT)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_UVECT,_uVec);
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_UVECT,_uVec);

    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_VVECT)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_VVECT,_vVec);
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_VVECT,_vVec);

    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX,_ubMatrix);
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX,_ubMatrix);

    std::string pri=UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS;
    if (_isUBpriority)
        pri=UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX;
    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_UBPRIORITY)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_UBPRIORITY,pri);
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_UBPRIORITY,pri);

    std::vector<Double> rotSteps;
    for (UInt4 i=0; i<_rotateSteps.size(); i++ ){
        Double axis_num=-1.0;
        if (_rotateSteps[i].first=="X") axis_num = 0.0;
        else if (_rotateSteps[i].first=="Y") axis_num = 1.0;
        else if (_rotateSteps[i].first=="Z") axis_num = 2.0;
        if (axis_num>=0.0){
            rotSteps.push_back( axis_num );
            rotSteps.push_back( _rotateSteps[i].second );
        }
    }
    if (hh->CheckKey(UTSUSEMI_KEY_HEAD_SAMPLE_ROTATESTEPS)==1)
        hh->OverWrite(UTSUSEMI_KEY_HEAD_SAMPLE_ROTATESTEPS, rotSteps );
    else
        hh->Add(UTSUSEMI_KEY_HEAD_SAMPLE_ROTATESTEPS, rotSteps );

    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetProjectionAxis( std::string _id, double va, double vb, double vc, double ve, std::string title, std::string unit ){
    if ((_id!="0")&&(_id!="1")&&(_id!="2")&&(_id!="3")){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> id is invalid : given id="+_id );
        return false;
    }

    std::pair< std::vector<Double>,std::vector<std::string> > tmp;
    tmp.first.clear();
    tmp.first.resize(4,0.0);
    tmp.first[0] = va;
    tmp.first[1] = vb;
    tmp.first[2] = vc;
    tmp.first[3] = ve;
    tmp.second.resize(2,"");
    tmp.second[0] = title;
    tmp.second[1] = unit;

    if (_projectionAxes.Check( _id )==1)
        _projectionAxes.Remove(_id);

    _projectionAxes.Add( _id, tmp );
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetProjectionAxes( PyObject* arg_ax1, PyObject* arg_ax2, PyObject* arg_ax3, PyObject* arg_ax4 ){
    if ((!PyList_Check(arg_ax1))||(!PyList_Check(arg_ax2))||(!PyList_Check(arg_ax3))||(!PyList_Check(arg_ax4))){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> arguments must be python-list" );
        return false;
    }
    std::vector<PyObject*> pyo(4);
    pyo[0] = arg_ax1;
    pyo[1] = arg_ax2;
    pyo[2] = arg_ax3;
    pyo[3] = arg_ax4;

    for (UInt4 i=0; i<pyo.size(); i++){
        UInt4 size = (UInt4) PyList_Size( pyo[i] );
        std::string axis_title ="";
        if ((size!=5)&&(size!=6)){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid size of List ax="+_st->UInt4ToString(i) );
            return false;
        }
        std::vector<Double> ax(4,0.0);
        for (UInt4 j=0; j<ax.size(); j++){
            if( PyFloat_CheckExact( PyList_GetItem( pyo[i], j ) ) ){
                ax[j] = PyFloat_AsDouble( PyList_GetItem( pyo[i], j ) );
            }
#ifdef IS_PY3
            else if( PyLong_CheckExact( PyList_GetItem( pyo[i], j ) ) ){
                ax[j] = ( Double )( PyLong_AsLong( PyList_GetItem( pyo[i], j ) ) );
            }
#else
            else if( PyInt_CheckExact( PyList_GetItem( pyo[i], j ) ) ){
                ax[j] = ( Double )( PyInt_AsLong( PyList_GetItem( pyo[i], j ) ) );
            }
#endif
            else{
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid List" );
                return false;
            }
        }
#ifdef IS_PY3
        if (!PyUnicode_CheckExact( PyList_GetItem( pyo[i], 4 ) ) ){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid List (error at last object)" );
            return false;
        }
        std::string title_ax = PyUnicode_AsUTF8( PyList_GetItem( pyo[i], 4 ) );
        std::string unit_ax="";
        if (size==6){
            if (!PyUnicode_CheckExact( PyList_GetItem( pyo[i], 5 ) ) ){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid List (error at last object)" );
                return false;
            }
            unit_ax=PyUnicode_AsUTF8( PyList_GetItem( pyo[i], 5 ) );
        }
#else
        if (!PyString_CheckExact( PyList_GetItem( pyo[i], 4 ) ) ){
            if (!PyUnicode_CheckExact( PyList_GetItem( pyo[i], 4 ) ) ){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid List (error at last object)" );
                std::cout << "i="<<i<<std::endl;
                return false;
            }
        }
        std::string title_ax = PyString_AsString( PyList_GetItem( pyo[i], 4 ) );
        std::string unit_ax="";
        if (size==6){
            if (!PyString_CheckExact( PyList_GetItem( pyo[i], 5 ) ) ){
                if (!PyUnicode_CheckExact( PyList_GetItem( pyo[i], 5 ) ) ){
                    UtsusemiError( "UtsusemiSqeCalcXtalParams::SetProjectionAxes >> Invalid List (error at last object)" );
                    std::cout << "i="<<i<<std::endl;
                    return false;
                }
            }
            unit_ax = PyString_AsString( PyList_GetItem( pyo[i], 5 ) );
        }
#endif
        std::string _key = _st->UInt4ToString(i);
        if (SetProjectionAxis( _key, ax[0], ax[1], ax[2], ax[3], title_ax, unit_ax )){
        }else{
            return false;
        }
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetSliceAxis( std::string _id, std::string _type, double _min, double _max, double _width, double _folding ){
    if ((_id!="0")&&(_id!="1")&&(_id!="2")&&(_id!="3")){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetPlotAxis >> id is invalid : given id="+_id );
        return false;
    }
    transform( _type.begin(), _type.end(), _type.begin(), ::tolower );
    if ((_type!="x")&&(_type!="y")&&(_type!="t")&&(_type!="z")){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetPlotAxis >> type is invalid : given type="+_type );
        return false;
    }

    std::pair< std::string,std::vector<Double> > tmp;
    tmp.first = _type;
    tmp.second.resize(4,0.0);
    tmp.second[0] = _min;      // min
    tmp.second[1] = _max;      // max
    tmp.second[2] = _width;    // bin-width
    tmp.second[3] = _folding;  // folding

    if (_plotAxis.Check(_id)==1) _plotAxis.Remove(_id);

    _plotAxis.Add(_id, tmp);
    return true;
}
//////////////////////////////////////////////////////////
/*
bool UtsusemiSqeCalcXtalParams::
SetSliceAxes( std::string ax1_type, PyObject* arg_ax1, std::string ax2_type, PyObject* arg_ax2, std::string ax3_type, PyObject* arg_ax3, std::string ax4_type, PyObject* arg_ax4 ){
    std::vector<Double> ax1 = __gCppToPython.ListToDoubleVector( arg_ax1 );
    std::vector<Double> ax2 = __gCppToPython.ListToDoubleVector( arg_ax2 );
    std::vector<Double> ax3 = __gCppToPython.ListToDoubleVector( arg_ax3 );
    std::vector<Double> ax4 = __gCppToPython.ListToDoubleVector( arg_ax4 );
    bool ret = false;
    if (ax1.size()==3){
        ret = SetSliceAxis( "0", ax1_type, ax1[0], ax1[1], ax1[2], -1.0 );
    }else if (ax1.size()==4){
        ret = SetSliceAxis( "0", ax1_type, ax1[0], ax1[1], ax1[2], ax1[3] );
    }
    if (!ret){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> ax1 argument is invalid." );
        return false;
    }

    ret = false;
    if (ax2.size()==3){
        ret = SetSliceAxis( "1", ax2_type, ax2[0], ax2[1], ax2[2], -1.0 );
    }else if (ax2.size()==4){
        ret = SetSliceAxis( "1", ax2_type, ax2[0], ax2[1], ax2[2], ax2[3] );
    }
    if (!ret){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> ax2 argument is invalid." );
        return false;
    }

    ret = false;
    if (ax3.size()==3){
        ret = SetSliceAxis( "2", ax3_type, ax3[0], ax3[1], ax3[2], -1.0 );
    }else if (ax3.size()==4){
        ret = SetSliceAxis( "2", ax3_type, ax3[0], ax3[1], ax3[2], ax3[3] );
    }
    if (!ret){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> ax3 argument is invalid." );
        return false;
    }

    ret = false;
    if (ax4.size()==3){
        ret = SetSliceAxis( "3", ax4_type, ax4[0], ax4[1], ax4[2], -1.0 );
    }else if (ax4.size()==4){
        ret = SetSliceAxis( "3", ax4_type, ax4[0], ax4[1], ax4[2], ax4[3] );
    }
    if (!ret){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> ax4 argument is invalid." );
        return false;
    }

    return true;
}
*/
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetSliceAxes( PyObject* Ax1, PyObject* Ax2, PyObject* Ax3, PyObject* Ax4, bool isForced ){
    if ((!PyList_Check(Ax1))||(!PyList_Check(Ax2))||(!PyList_Check(Ax3))||(!PyList_Check(Ax4))){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> arguments must be python-list" );
        return false;
    }
    std::vector<PyObject*> pyo(4);
    pyo[0] = Ax1;
    pyo[1] = Ax2;
    pyo[2] = Ax3;
    pyo[3] = Ax4;

    std::vector< std::vector<Double> > Axr(4);
    std::vector<std::string> AxesType(4,"");
    std::vector<Double> Folding(4,-1.0);
    for (UInt4 i=0; i<pyo.size(); i++){
        UInt4 size = (UInt4) PyList_Size( pyo[i] );
        if (size<1){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> Invalid List ax="+_st->UInt4ToString(i) );
            return false;
        }
#ifdef IS_PY3
        if (!PyUnicode_CheckExact( PyList_GetItem( pyo[i], 0 ) ) ){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List : first object must be unicode" );
            return false;
        }
        std::string t = PyUnicode_AsUTF8( PyList_GetItem( pyo[i], 0 ) );
#else
        if (!PyString_CheckExact( PyList_GetItem( pyo[i], 0 ) ) ){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List : first object must be string" );
            return false;
        }
        std::string t = PyString_AsString( PyList_GetItem( pyo[i], 0 ) );
#endif
        transform( t.begin(), t.end(), t.begin(), ::toupper);
        if ((t!="X")&&(t!="Y")&&(t!="Z")&&(t!="T")){
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> Invalid List : first object must be X,Y,Z or T" );
            return false;
        }

        if ((t=="X")||(t=="Y")||(t=="Z")){
            std::vector<Double> cont;
            if (_ConvPyListToDoubleVect(pyo[i],&cont,1)){
                if (cont.size()==3){
                    for (UInt4 j=0; j<3; j++)
                        Axr[i].push_back( cont[j] );
                }else if (cont.size()==4){
                    for (UInt4 j=0; j<3; j++)
                        Axr[i].push_back( cont[j] );
                    Folding[i] = cont[3];
                }else{
                    UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List : the number of later objects must be 3 or 4 at type=X, Y or Z" );
                    return false;
                }
            }else{
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes >> Invalid List : invalid latter objects." );
                return false;
            }
        }else if (t=="T"){
            std::vector<Double> cont;
            if (_ConvPyListToDoubleVect(pyo[i],&cont,1)){
                if (cont.size()==2){
                    for (UInt4 j=0; j<2; j++)
                        Axr[i].push_back( cont[j] );
                }else if ((cont.size()==3)||(cont.size()==4)) {
                    for (UInt4 j=0; j<2; j++)
                        Axr[i].push_back( cont[j] );
                    Folding[i] = cont.back();
                }else{
                    UtsusemiError("UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List : the number of latter objects must be 2 or 3 at type=T." );
                    return false;
                }
            }else{
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List : invalid latter objects at type=T." );
                return false;
            }
        }else{
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List" );
            return false;
        }

        AxesType[i]=t;
    }

    UInt4 n_X = 0;
    UInt4 n_Y = 0;
    UInt4 n_Z = 0;
    UInt4 n_T = 0;
    for (UInt4 i=0; i<4; i++){
        if (AxesType[i]=="X") n_X++;
        if (AxesType[i]=="Y") n_Y++;
        if (AxesType[i]=="Z") n_Z++;
        if (AxesType[i]=="T") n_T++;
    }
    if ((isForced)||( ((n_X==1)&&(n_Y==1)&&(n_T==2)) || ((n_X==1)&&(n_Y==1)&&(n_Z==1)&&(n_T==1)) )){
        bool ret = false;
        for (UInt4 i=0; i<4; i++){
            std::string _key = _st->UInt4ToString(i);
            if (AxesType[i]=="T")
                ret = SetSliceAxis( _key, AxesType[i], Axr[i][0], Axr[i][1], Axr[i][1]-Axr[i][0], Folding[i] );
            else
                ret = SetSliceAxis( _key, AxesType[i], Axr[i][0], Axr[i][1], Axr[i][2], Folding[i] );
            if (!ret){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List" );
                return false;
            }
        }
    }else{
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetSliceAxes  >> Invalid List Arguments" );
        return false;
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetDiagFolding( std::string _type, UInt4 ax1, UInt4 ax2 ){
    if ((_type!="0")&&(_type!="1")&&(_type!="2")&&(_type!="3")){
        return false;
    }

    _diagFolding.first = _type;
    _diagFolding.second.clear();
    _diagFolding.second.resize(2,0);
    _diagFolding.second[0] = ax1;
    _diagFolding.second[1] = ax2;
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SetDiagFolding( PyObject* Dfold ){
    if (!PyList_Check(Dfold)){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetDiagFolding >> arguments must be python-list" );
        return false;
    }
    UInt4 size = (UInt4) PyList_Size( Dfold );
    if (size==3){
        std::vector<Double> cont;
        if (_ConvPyListToDoubleVect( Dfold, &cont, 0)){
            std::string _type = _st->UInt4ToString( (UInt4)(cont[0]) );
            UInt4 ax1 = (UInt4)(cont[1]);
            UInt4 ax2 = (UInt4)(cont[2]);
            return SetDiagFolding( _type, ax1, ax2 );
        }else{
            UtsusemiError( "UtsusemiSqeCalcXtalParams::SetDiagFolding >> Invalid DiagFolding List" );
            return false;
        }
    }else if (size==0) return true;
    else{
        UtsusemiError( "UtsusemiSqeCalcXtalParams::SetDiagFolding >> Invalid DiagFolding List" );
        return false;
    }
}
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_LATTICECONST=1;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_ORIENTATION=2;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_PROJECTION=4;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_SLICINGINFO=8;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_DIAGONALFOLD=16;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_UBMATRIX=32;
const UInt4 UtsusemiSqeCalcXtalParams::TOXML_ALL=255;
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
LoadFile( std::string filepath, UInt4 flags ){
    std::string found_filepath = FindParamFilePath( filepath );
    if (found_filepath==""){
        UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> File not found ("+filepath+")" );
        return false;
    }
    //filePath = found_filepath;

    return DecodeFromXml(found_filepath, flags);
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
DecodeFromXml(std::string conts, UInt4 flags){
    if (_xml!=NULL) delete _xml;
    _xml = new BoostXmlParser( conts );
    std::string filepath = "";
    if (_xml->isLoadXmlString()) filepath = "given strings";
    else filepath = conts;

    _xml->SetQuiet( !(UtsusemiEnvGetDebugMode()) );

    //_rotateSteps.clear();

    std::string path="";
    if (_xml->hasPath("visualContParams")){
        version = _xml->PutContent("visualContParams","version");
        path = "visualContParams/sampleInformation/name";
        if (_xml->hasPath(path)){
            name = _xml->PutContent(path);
        }else{
            UtsusemiWarning( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get name from "+filepath );
            name = "NotFound";
        }

        std::vector<Double> LC = PutLatticeConsts();
        if (LC.empty()) LC.resize(6,0.0);
        //std::vector<Double> LC(6,0.0);
        path = "visualContParams/sampleInformation/latticeInfo/latticeConst";
        if ((_xml->hasPath(path))&&((flags&TOXML_LATTICECONST)!=0)){
            std::vector<std::string> LC_list = _st->SplitString( _xml->PutContent(path), "," );
            if (LC_list.size()!=3){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get Lattice Constants from "+filepath );
                return false;
            }else{
                for (UInt4 i=0; i<3; i++)
                    LC[i] = _st->StringToDouble( LC_list[i] );
            }
        }
        path = "visualContParams/sampleInformation/latticeInfo/latticeAngle";
        if (_xml->hasPath(path)){
            std::vector<std::string> LA_list = _st->SplitString( _xml->PutContent(path), "," );
            if (LA_list.size()!=3){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get Lattice Constants Angles from "+filepath );
                return false;
            }else{
                for (UInt4 i=0; i<3; i++)
                    LC[3+i] = _st->StringToDouble( LA_list[i] );
            }
        }

        if (!SetLatticeConstants( LC[0],LC[1],LC[2],LC[3],LC[4],LC[5] )) return false;

        std::vector<Double> UV(6,0.0);
        std::vector<Double> uvec = PutUVector();
        std::vector<Double> vvec = PutVVector();
        for (UInt4 i=0; i<uvec.size(); i++) UV[i]=uvec[i];
        for (UInt4 i=0; i<vvec.size(); i++) UV[i+3]=vvec[i];

        path = "visualContParams/sampleInformation/orientation/Uvector";
        if ((_xml->hasPath(path))&&((flags&TOXML_ORIENTATION)!=0)){
            std::vector<std::string> Uvec = _st->SplitString( _xml->PutContent(path), "," );
            if (Uvec.size()!=3){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get U-vector from "+filepath );
                return false;
            }else{
                for (UInt4 i=0; i<3; i++)
                    UV[i] = _st->StringToDouble( Uvec[i] );
            }
        }
        path = "visualContParams/sampleInformation/orientation/Vvector";
        if ((_xml->hasPath(path))&&((flags&TOXML_ORIENTATION)!=0)){
            std::vector<std::string> Vvec = _st->SplitString( _xml->PutContent(path), "," );
            if (Vvec.size()!=3){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get V-vector from "+filepath );
                return false;
            }else{
                for (UInt4 i=0; i<3; i++)
                    UV[3+i] = _st->StringToDouble( Vvec[i] );
            }
        }
        if (!SetUVvector( UV[0],UV[1],UV[2],UV[3],UV[4],UV[5] )) return false;

        path = "visualContParams/sampleInformation/ubMatrix";
        if ((_xml->hasPath(path))&&((flags&TOXML_UBMATRIX)!=0)){
            std::vector<std::string> ubmat = _st->SplitString( _xml->PutContent(path), "," );
            if (ubmat.size()!=9){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get UBmatrix from "+filepath );
                return false;
            }else{
                for (UInt4 i=0; i<9; i++)
                    _ubMatrix[i] = _st->StringToDouble( ubmat[i] );
            }
        }
        path = "visualContParams/sampleInformation/priority";
        if (_xml->hasPath(path)){
            std::string pri=_xml->PutContent(path);
            if (pri==UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX) _isUBpriority=true;
            else _isUBpriority=false;
        }

        path = "visualContParams/sampleInformation/orientation/rotateSteps";
        if ((_xml->hasPath(path))&&((flags&TOXML_ORIENTATION)!=0)){
            if (_xml->PutContent(path)!=""){
                std::vector<std::string> rot;
                std::vector<std::string> split_cont = _st->SplitString( _xml->PutContent(path), "," );
                for (UInt4 i=0; i<split_cont.size(); i++){
                    std::vector<std::string> tmp_rot = _st->SplitString( split_cont[i], ":" );
                    if (tmp_rot.size()<2){
                        //UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get rotation info from "+filepath );
                        //return false;
                        rot.push_back( tmp_rot[0] );
                    }else{
                        rot.push_back( tmp_rot[0] );
                        rot.push_back( tmp_rot[1] );
                    }
                }
                if (((rot.size())%2)!=0){
                    UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get rotation info from "+filepath );
                    return false;
                }
                if (!(rot.empty())) _rotateSteps.clear();
                for (UInt4 i=0; i<rot.size(); i+=2){
                    if (AddRotationStep(rot[i],_st->StringToDouble(rot[i+1]))){
                    }else{
                        UtsusemiWarning( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get rotation info from "+filepath );
                    }
                }
            }
        }else{
            path = "visualContParams/sampleInformation/orientation/phi";
            Double phi = _st->StringToDouble( _xml->PutContent(path) );
            if (phi!=0.0){
                if (AddRotationStep("Y",phi)){
                }else{
                    UtsusemiWarning( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get rotation info from "+filepath );
                }
            }
        }

        path = "visualContParams/slicingInformation/projectParams/axis";
        if ((_xml->hasPath(path))&&((flags&TOXML_PROJECTION)!=0)){
            for (UInt4 _i=0; _i<4; _i++){
                std::string path2 = path+",id="+_st->UInt4ToString( _i )+"/vector";
                std::vector<std::string> view = _st->SplitString( _xml->PutContent(path2), "," );
                if (view.size()!=4){
                    std::string path3 = path + ",id=" + _st->UInt4ToString(_i) + "/std::vector";
                    std::vector<std::string> view3 = _st->SplitString( _xml->PutContent(path3), "," );
                    if (view3.size() != 4){
                        UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get view info from path:" + path3 );
                        return false;
                    }
                    view.clear();
                    for (UInt4 _j = 0; _j < 4; _j++) view.push_back(view3[_j]);
                }
                std::vector<Double> v(4,0.0);
                for (UInt4 j=0; j<4; j++)
                    v[j] = _st->StringToDouble( view[j] );

                path2 = path+",id="+_st->UInt4ToString( _i )+"/title";
                std::string title = _xml->PutContent(path2);
                path2 = path+",id="+_st->UInt4ToString( _i )+"/unit";
                std::string unit="";
                if (_xml->hasPath(path2))
                    unit = _xml->PutContent(path2);

                if (((title.find(UTSUSEMI_KEY_ENERGY))!=std::string::npos)&&(unit=="")){
                    std::string::size_type ind1 = title.find("(");
                    std::string::size_type ind2 = title.find(")");
                    if ((ind1 != std::string::npos)&&(ind2 !=std::string::npos)){
                        unit=title.substr(ind1+1,ind2-(ind1+1));
                        title = title.substr(0,ind1);
                    }else{
                        std::string::size_type ind21 = title.find("[");
                        std::string::size_type ind22 = title.find("]");
                        if ((ind21 != std::string::npos)&&(ind22 !=std::string::npos)){
                            unit=title.substr(ind21+1,ind22-(ind21+1));
                            title = title.substr(0,ind21);
                        }
                    }
                    if (unit=="") unit = UTSUSEMI_KEY_ENERGY_UNIT;
                }
                if (unit=="") unit = UTSUSEMI_KEY_ARB_UNIT;
                if (!SetProjectionAxis( _st->UInt4ToString( _i ), v[0], v[1], v[2], v[3], title, unit )) return false;
            }
        }

        path = "visualContParams/slicingInformation/plotParams/paxis";
        if ((_xml->hasPath(path))&&((flags&TOXML_SLICINGINFO)!=0)){
            for (UInt4 _i=0; _i<4; _i++){
                std::string path2 = path+",id="+_st->UInt4ToString( _i )+"/type";
                std::string _type = _xml->PutContent(path2);
                path2 = path+",id="+_st->UInt4ToString( _i )+"/range";
                std::vector<std::string> range = _st->SplitString( _xml->PutContent(path2), "," );
                if (range.size()!=3){
                    UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get plotParams from path:"+path2 );
                    return false;
                }
                std::vector<Double> r(3,0.0);
                for (UInt4 j=0; j<3; j++)
                    r[j] = _st->StringToDouble( range[j] );

                path2 = path+",id="+_st->UInt4ToString( _i )+"/folding";
                Double f = _st->StringToDouble( _xml->PutContent(path2) );
                if (!SetSliceAxis( _st->UInt4ToString( _i ), _type, r[0], r[1], r[2], f )) return false;
            }
        }

        path = "visualContParams/slicingInformation/plotParams/diagFolding";
        if ((_xml->hasPath(path))&&((flags&TOXML_DIAGONALFOLD)!=0)){
            std::string _type = _xml->PutContent( path+"/type" );
            std::vector<std::string> ua = _st->SplitString(_xml->PutContent( path+"/usedAxis" ),",");
            if ((_type!="0")&&(ua.size()!=2)){
                UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to get Diagonal Folding from path:"+path );
                return false;
            }

            UInt4 ax1 = _st->StringToUInt4( ua[0] );
            UInt4 ax2 = _st->StringToUInt4( ua[1] );
            if (!SetDiagFolding( _type, ax1, ax2 )) return false;
        }
    }else{
        UtsusemiError( "UtsusemiSqeCalcXtalParams::LoadFile >> Failed to load file="+filepath );
        return false;
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
SaveFile( std::string filepath, UInt4 flags ){
    if (!EncodeToXml(flags)) return false;
    return _xml->Save(filepath);
}
//////////////////////////////////////////////////////////
std::string UtsusemiSqeCalcXtalParams::
PutXmlString(UInt4 flags){
    if (!EncodeToXml(flags)) return "";
    return _xml->OutAllToString();
}
//////////////////////////////////////////////////////////
bool UtsusemiSqeCalcXtalParams::
EncodeToXml(UInt4 flags){
    if (_xml!=NULL) delete _xml;
    _xml = new BoostXmlParser();
    _xml->SetQuiet( !(UtsusemiEnvGetDebugMode()) );
    std::string xmlKey="UtsusemiSqeCalc";
    std::string path="";
    bool ret = false;
    char tmp_c[400];
    std::vector<std::string> tmp_args;
    std::vector<std::string> tmp_vals;

    if (_xml->CreateNewTree(xmlKey)){
        path = "visualContParams";
        // Set Version
        tmp_args.clear();
        tmp_vals.clear();
        tmp_args.push_back("version");
        tmp_vals.push_back(version);
        ret = _xml->AddElement( xmlKey, path, tmp_args, tmp_vals );

        // Set Sample Name
        path = "visualContParams/sampleInformation/name";
        ret = _xml->AddElement( xmlKey, path, name );

        // Set Lattice Parameters #1
        if ((flags&TOXML_LATTICECONST)!=0){
            path = "visualContParams/sampleInformation/latticeInfo";
            std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g", _latticeConsts[0],_latticeConsts[1],_latticeConsts[2] );
            std::string s_LC(tmp_c);
            std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g", _latticeConsts[3],_latticeConsts[4],_latticeConsts[5] );
            std::string s_LA(tmp_c);

            ret = _xml->AddElement( xmlKey, path+"/latticeConst", s_LC );
            ret = _xml->AddElement( xmlKey, path+"/latticeAngle", s_LA );
        }

        // Set Sample Orientation #2
        if ((flags&TOXML_ORIENTATION)!=0){
            path = "visualContParams/sampleInformation/orientation";
            std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g", _uVec[0],_uVec[1],_uVec[2] );
            std::string s_UVec(tmp_c);
            std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g", _vVec[0],_vVec[1],_vVec[2] );
            std::string s_VVec(tmp_c);
            std::string s_Rot = "";
            for (UInt4 i=0; i<_rotateSteps.size(); i++){
                std::snprintf( tmp_c, sizeof(tmp_c), "%s:%g", _rotateSteps[i].first.c_str(),_rotateSteps[i].second );
                std::string s_rot_a(tmp_c);
                if (s_Rot=="") s_Rot = s_rot_a;
                else s_Rot += (","+s_rot_a);
            }
            ret = _xml->AddElement( xmlKey, path+"/Uvector", s_UVec );
            ret = _xml->AddElement( xmlKey, path+"/Vvector", s_VVec );
            ret = _xml->AddElement( xmlKey, path+"/rotateSteps", s_Rot );
        }

        // Set UBMatrix
        if ((flags&TOXML_UBMATRIX)!=0){
            std::snprintf( tmp_c, sizeof(tmp_c), "\n                 %g, %g, %g,\n                 %g, %g, %g,\n                 %g, %g, %g\n        ",
                      _ubMatrix[0],_ubMatrix[1],_ubMatrix[2],_ubMatrix[3],_ubMatrix[4],_ubMatrix[5],_ubMatrix[6],_ubMatrix[7],_ubMatrix[8] );
            std::string s_UBmat(tmp_c);
            path = "visualContParams/sampleInformation";
            ret = _xml->AddElement( xmlKey, path+"/ubMatrix", s_UBmat );
            if (_isUBpriority)
                ret = _xml->AddElement( xmlKey, path+"/priority", UTSUSEMI_KEY_HEAD_SAMPLE_UBMATRIX );
            else
                ret = _xml->AddElement( xmlKey, path+"/priority", UTSUSEMI_KEY_HEAD_SAMPLE_LATTICECONSTS );
        }

        // Set Projection Info #3
        if ((flags&TOXML_PROJECTION)!=0){
        for (UInt4 i=0; i<4; i++){
            path = "visualContParams/slicingInformation/projectParams/axis,id="+_st->UInt4ToString(i);
            std::pair< std::vector<Double>,std::vector<std::string> > pa = _projectionAxes.Put( _st->UInt4ToString(i) );
            std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g, %g", pa.first[0],pa.first[1],pa.first[2],pa.first[3]);
            std::string s_paxis(tmp_c);

            ret = _xml->AddElement( xmlKey, path+"/vector", s_paxis );
            ret = _xml->AddElement( xmlKey, path+"/title", pa.second[0] );
            ret = _xml->AddElement( xmlKey, path+"/unit", pa.second[1] );
        }
        }

        // Set Slicing Info #4
        if ((flags&TOXML_SLICINGINFO)!=0){
            for (UInt4 i=0; i<4; i++){
                path = "visualContParams/slicingInformation/plotParams/paxis,id="+_st->UInt4ToString(i);
                std::pair< std::string, std::vector<Double> > pl = _plotAxis.Put( _st->UInt4ToString(i) );
                std::snprintf( tmp_c, sizeof(tmp_c), "%g, %g, %g", pl.second[0], pl.second[1], pl.second[2] );
                std::string s_pl(tmp_c);
                std::snprintf( tmp_c, sizeof(tmp_c), "%g", pl.second[3] );
                std::string s_fol(tmp_c);

                ret = _xml->AddElement( xmlKey, path+"/type", pl.first );
                ret = _xml->AddElement( xmlKey, path+"/range", s_pl );
                ret = _xml->AddElement( xmlKey, path+"/folding", s_fol );
            }
        }

        // Set Diagonal Folding Info #5
        if ((flags&TOXML_DIAGONALFOLD)!=0){
            path = "visualContParams/slicingInformation/plotParams/diagFolding/type";
            ret = _xml->AddElement( xmlKey, path, _diagFolding.first );
            path = "visualContParams/slicingInformation/plotParams/diagFolding/usedAxis";
            std::snprintf( tmp_c, sizeof(tmp_c), "%d, %d", UInt4(_diagFolding.second[0]), UInt4(_diagFolding.second[1]) );
            std::string s_usedAxis(tmp_c);
            ret = _xml->AddElement( xmlKey, path, s_usedAxis );
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> UtsusemiSqeCalcXtalParams::
PutRotateSteps(){
    std::vector<Double> ret;
    for (UInt4 i=0; i<_rotateSteps.size(); i++){
        std::string t = _rotateSteps[i].first;
        Double ind = -1.0;
        if ((t=="x")||(t=="X")) ind = 0.0;
        else if ((t=="y")||(t=="Y")) ind = 1.0;
        else if ((t=="z")||(t=="Z")) ind = 2.0;
        else
            continue;

        if (ind>-1.0){
            ret.push_back( ind );
            ret.push_back( _rotateSteps[i].second );
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> UtsusemiSqeCalcXtalParams::
PutViewAxes(){
    std::vector<Double> ret;
    for (UInt4 i=0; i<4; i++){
        std::pair< std::vector<Double>,std::vector<std::string> > pa = _projectionAxes.Put( _st->UInt4ToString(i) );
        for (UInt4 j=0; j<4; j++)
            ret.push_back( pa.first[j] );
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<std::string> UtsusemiSqeCalcXtalParams::
PutViewAxesLabels(){
    std::vector<std::string> ret(4,"");
    for (UInt4 i=0; i<4; i++){
        std::pair< std::vector<Double>,std::vector<std::string> > pa = _projectionAxes.Put( _st->UInt4ToString(i) );
        ret[i] = pa.second[0];
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<std::string> UtsusemiSqeCalcXtalParams::
PutViewAxesUnits(){
    std::vector<std::string> ret(4,"");
    for (UInt4 i=0; i<4; i++){
        std::pair< std::vector<Double>,std::vector<std::string> > pa = _projectionAxes.Put( _st->UInt4ToString(i) );
        ret[i] = pa.second[1];
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> UtsusemiSqeCalcXtalParams::
PutAxRange( UInt4 ind, bool useAxTypeInfo ){
    //Map< std::pair< std::string, std::vector<Double> > > _plotAxis;
    std::pair< std::string, std::vector<Double> > tmp = _plotAxis.Put( _st->UInt4ToString( ind ) );
    std::vector<Double> ret(3,0.0);
    if (useAxTypeInfo){
        if (tmp.first=="t"){
            ret[0] = tmp.second[0];
            ret[1] = tmp.second[1];
            ret[2] = ret[1]-ret[0];
        }else{
            for (UInt4 i=0; i<3; i++)
                ret[i] = tmp.second[i];
        }
    }else{
        for (UInt4 i=0; i<3; i++)
            ret[i] = tmp.second[i];
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<std::string> UtsusemiSqeCalcXtalParams::
PutAxType(){
    std::vector<std::string> ret;
    for (UInt4 i=0; i<4; i++){
        std::pair< std::string, std::vector<Double> > tmp = _plotAxis.Put( _st->UInt4ToString( i ) );
        ret.push_back( tmp.first );
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<std::string> UtsusemiSqeCalcXtalParams::
PutAxLabels(){
    std::vector<std::string> ret(4,"");
    for (UInt4 i=0; i<4; i++){
        std::pair< std::string, std::vector<Double> > tmp = _plotAxis.Put( _st->UInt4ToString( i ) );
        std::string title = _projectionAxes.Put( _st->UInt4ToString( i ) ).second[0];
        if (tmp.first=="x") ret[0] = title;
        if (tmp.first=="y") ret[1] = title;
        if (tmp.first=="z") ret[2] = title;
        if (tmp.first=="t"){
            if (ret[3]=="") ret[3] = title;
            else{
                std::string tmp = ret[3];
                ret[2] = tmp;
                ret[3] = title;
            }
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<std::string> UtsusemiSqeCalcXtalParams::
PutAxUnits(){
    std::vector<std::string> ret(4,"");
    for (UInt4 i=0; i<4; i++){
        std::pair< std::string, std::vector<Double> > tmp = _plotAxis.Put( _st->UInt4ToString( i ) );
        std::string unit = _projectionAxes.Put( _st->UInt4ToString( i ) ).second[1];
        if (tmp.first=="x") ret[0] = unit;
        if (tmp.first=="y") ret[1] = unit;
        if (tmp.first=="z") ret[2] = unit;
        if (tmp.first=="t"){
            if (ret[3]=="") ret[3] = unit;
            else{
                std::string tmp = ret[3];
                ret[2] = tmp;
                ret[3] = unit;
            }
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> UtsusemiSqeCalcXtalParams::
PutFolding(){
    std::vector<Double> ret;
    for (UInt4 i=0; i<4; i++){
        std::pair< std::string, std::vector<Double> > tmp = _plotAxis.Put( _st->UInt4ToString( i ) );
        ret.push_back( tmp.second[3] );
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<UInt4> UtsusemiSqeCalcXtalParams::
PutDiagFolding(){
    if (_diagFolding.first!="0"){
        std::vector<UInt4> ret(3,0);
        ret[0] = _st->StringToUInt4( _diagFolding.first );
        ret[1] = _diagFolding.second[0];
        ret[2] = _diagFolding.second[1];
        return ret;
    }else{
        std::vector<UInt4> empty;
        return empty;
    }
}
//////////////////////////////////////////////////////////
void UtsusemiSqeCalcXtalParams::
Dump(){
    std::cout << "--------------------------------------------------" << std::endl;
    std::cout << " UtsusemiSqeCalcXtalParams::Dump()" << std::endl;
    std::cout << "--------------------------------------------------" << std::endl;
    std::cout << std::endl;
    std::cout << " File Path = " << filePath << std::endl;
    std::cout << " Sample Name = " << name << std::endl;
    std::cout << "--------------------------------------------------" << std::endl;
    std::cout << std::endl;
    std::cout << " Latice Constants " << std::endl;
    std::cout << "------------------" << std::endl;
    std::cout << " a : " << _latticeConsts[0] << std::endl;
    std::cout << " b : " << _latticeConsts[1] << std::endl;
    std::cout << " c : " << _latticeConsts[2] << std::endl;
    std::cout << " alpha : " << _latticeConsts[3] << std::endl;
    std::cout << " beta  : " << _latticeConsts[4] << std::endl;
    std::cout << " gamma : " << _latticeConsts[5] << std::endl;
    std::cout << std::endl;
    std::cout << " Orientation " << std::endl;
    std::cout << "-------------" << std::endl;
    std::cout << " U vector : " << _uVec[0] << "," << _uVec[1] << "," << _uVec[2] << std::endl;
    std::cout << " V vector : " << _vVec[0] << "," << _vVec[1] << "," << _vVec[2] << std::endl;
    std::cout << " Rotation : ";
    for (UInt4 i=0; i<_rotateSteps.size(); i++)
        std::cout << _rotateSteps[i].first << "=" << _rotateSteps[i].second << ",";
    std::cout << std::endl;
    std::cout << "------------" << std::endl;
    std::cout << "UB matrix = " << _ubMatrix[0] << ", " << _ubMatrix[1] << ", " << _ubMatrix[2] << std::endl;
    std::cout << "            " << _ubMatrix[3] << ", " << _ubMatrix[4] << ", " << _ubMatrix[5] << std::endl;
    std::cout << "            " << _ubMatrix[6] << ", " << _ubMatrix[7] << ", " << _ubMatrix[8] << std::endl;
    std::cout << "------------" << std::endl;
    if (_isUBpriority){
        std::cout << "UB matrix is used with high priorigy." << std::endl;
    }else{
        std::cout << "U and V vectors are used with high priorigy." << std::endl;
    }
    std::cout << std::endl;
    std::cout << " Projection " << std::endl;
    std::cout << "------------" << std::endl;
    for (UInt4 i=0; i<4; i++){
        std::pair< std::vector<Double>,std::vector<std::string> > pa = _projectionAxes.Put( _st->UInt4ToString(i) );
        std::cout << "Ax" << i << " : " << pa.first[0] << "," << pa.first[1] << "," << pa.first[2] <<"," << pa.first[3] << " : " << pa.second[0] <<","<< pa.second[1] << std::endl;
    }
    std::cout << std::endl;
    std::cout << " Slice Information" << std::endl;
    std::cout << "-------------------" << std::endl;
    for (UInt4 i=0; i<4; i++){
        std::pair< std::string, std::vector<Double> > pl = _plotAxis.Put( _st->UInt4ToString(i) );
        std::cout << "Ax" << i << " :" << std::endl;
        std::cout << "      Type = " << pl.first << std::endl;
        std::cout << "     Range = " << pl.second[0] << "," << pl.second[1] << "," << pl.second[2] << std::endl;
        std::cout << "   Folding = " << pl.second[3] << std::endl;
        std::cout << "------" << std::endl;
    }
    std::cout << std::endl;
    std::cout << " Diagonal Folding" << std::endl;
    std::cout << "------------------" << std::endl;
    std::cout << " Type=" << _diagFolding.first << ", Axes = " << _diagFolding.second[0] << "," << _diagFolding.second[1] << std::endl;

}
//////////////////////////////////////////////////////////
void UtsusemiSqeCalcXtalParams::
SetExampleParams(){
    filePath = "XtalParam_sample.xml";
    name = "SampleName";
    version = "0.3";

    bool ret = false;
    ret = SetLatticeConstants( 4.81,8.47,2.941,90.0,90.0,90.0 );
    ret = SetUVvector( 0.0,1.0,0.0, 0.0,0.0,1.0 );

    _rotateSteps.clear();

    _projectionAxes.Clear();
    ret = SetProjectionAxis( "0", 1.0, 0.0, 0.0, 0.0, "Qa", "rlu" );
    ret = SetProjectionAxis( "1", 0.0, 1.0, 0.0, 0.0, "Qb", "rlu" );
    ret = SetProjectionAxis( "2", 0.0, 0.0, 1.0, 0.0, "Qc", "rlu" );
    ret = SetProjectionAxis( "3", 0.0, 0.0, 0.0, 1.0, UTSUSEMI_KEY_HW, "meV" );

    _plotAxis.Clear();
    ret = SetSliceAxis("0","t",-5.0,5.0,0.05,-1.0);
    ret = SetSliceAxis("1","t",-5.0,5.0,0.05,-1.0);
    ret = SetSliceAxis("2","x",-5.0,5.0,0.05,-1.0);
    ret = SetSliceAxis("3","y",-5.0,5.0,0.05,-1.0);

    ret = SetDiagFolding("0",0,0);
}
//////////////////////////////////////////////////////////
bool  UtsusemiSqeCalcXtalParams::
_ConvPyListToDoubleVect( PyObject *ax, std::vector<double> *ret, UInt4 s ){
    UInt4 size = (UInt4) PyList_Size( ax );
    for (UInt4 i=s; i<size; i++){
        if( PyFloat_CheckExact( PyList_GetItem( ax, i ) ) ){
            ret->push_back( PyFloat_AsDouble( PyList_GetItem( ax, i ) ) );
        }
#ifdef IS_PY3
        else if( PyLong_CheckExact( PyList_GetItem( ax, i ) ) ){
            ret->push_back( ( Double )( PyLong_AsLong( PyList_GetItem( ax, i ) ) ) );
        }
#else
        else if( PyInt_CheckExact( PyList_GetItem( ax, i ) ) ){
            ret->push_back( ( Double )( PyInt_AsLong( PyList_GetItem( ax, i ) ) ) );
        }
#endif
        else{
            return false;
        }
    }
    return true;
}
