#ifndef UTSUSEMIGETHISTOGRAMTEMPLATE
#define UTSUSEMIGETHISTOGRAMTEMPLATE

/* Header.hh should be included on the top to avoid environments
 * specific issues (see Header.hh for the detail).
 */
#include "Header.hh"
#include "UtsusemiHeader.hh"
#include  <boost/filesystem.hpp>
#include "ElementContainerMatrix.hh"
#include "StringTools.hh"
#include "UtsusemiAnaEnvironReader.hh"
#include "UtsusemiTofOriginCorrection.hh"
#include "UtsusemiSetMask.hh"

////////////////////////////////////
// UtsusemiGetHistogramTemplate
///////////////////////////////////

//! Creates Histogram from event data
/*!
 *   - read WiringInfo
 *   - Set runNo and read suitable WiringInfo
 *   - Set Histgram conversion parameter
 *   - Set many parameters for the condition of histogram
 *   - rewrite WiringInfo by given parameters
 *   - create histogram from rewritten WiringInfo and DetectorInfo
 *
 *   T1 : UtsusemiWiringInfoEditorXXX
 *   T2 : UtsusemiDetectorInfoEditorXXX
 *
 *   Neuunet : T1=UtsusemiWiringInfoEditorNeunet
 *             T2=UtsusemiDetectorInfoEditorBbase
 *
 *   RPMT    : T1=UtsusemiWiringInfoEditorBase
 *             T2=UtsusemiDetectorInfoEditorBbase
 */

template <typename T1, typename T2>
class UtsusemiGetHistogramTemplate
{
private:
    T1 *_WE;  // UtsusemiWiringInfoEditorXXX
    T2 *_DE;  // UtsusemiDetectorInfoEditorXXX

    StringTools* _stools;
    std::string _MessageTag;

protected:
    UInt4 _runNo;
    std::vector<UInt4> _runNos;
    std::string _AnaEnvironFile;
    std::string _DetType;
    bool _withPH;
    std::pair<Double,Double> _TimeRangeSec;
    std::pair<std::string,std::string> _TimeRangeDateTime;
    std::vector<Double> _TimeSlicingList;
    std::string _UtsusemiUserXmlPath;
    std::string _UtsusemiUserPrivPath;
    Int4 _tofOriginShiftByLambda_type;
    std::vector<Double> _tofOriginShiftByLambda_params;
    std::vector<Double> _tofOriginShiftByLambda_lambda;
    double _L1;
    std::vector<double> _SamplePosition;
    std::string _CaseInfoFilePath;
    bool _isLoadFileOfTimeDependBackGround;
    std::string _pathFileOfTimeDependBackGround;

    //[inamura 160830]-->
    bool _SetMask( ElementContainerMatrix* _ecm ){
        std::string mask_path = _WE->_maskInfoPath;
        if (mask_path!=""){
            UtsusemiSetMask* USM = new UtsusemiSetMask(_ecm);
            if (USM->ReadFile( mask_path )){
                if (USM->Execute()){
                }else{
                    UtsusemiError( _MessageTag+"_SetMask >>> Fails SetMask::Execute " );
                    return false;
                }
            }else{
                UtsusemiError( _MessageTag+"_SetMask >>> Fails SetMask::ReadFile "+mask_path );
                return false;
            }
            delete USM;
            UtsusemiMessage( _MessageTag+"SetMask >>> MaskInfo = "+mask_path);
        }
        return true;
    }
    //<--[inamura 160830]

public:
    //////////////////////////////////////////////////////////////////////////
    UtsusemiGetHistogramTemplate(){
        Initialize();
    }
    //!< Constructor
    /*!<
     */

    //////////////////////////////////////////////////////////////////////////
    ~UtsusemiGetHistogramTemplate(){
        if (_stools!=NULL) delete _stools;
        if (_WE!=NULL) delete _WE;
        if (_DE!=NULL) delete _DE;
    }
    //!< Destructor
    /*!<
     */

    //////////////////////////////////////////////////////////////////////////
    // public variables
    //////////////////////////////////////////////////////////////////////////
    bool _Status;
    //////////////////////////////////////////////////////////////////////////
    // public functions
    //////////////////////////////////////////////////////////////////////////
    void Initialize(){
        _WE = new T1();
        _DE = new T2();

        _stools = new StringTools();
        _MessageTag = "UtsusemiGetHistogramTemplate::";
        _Status = false;
        _AnaEnvironFile = "";
        _DetType = UTSUSEMI_KEY_HEAD_DETTYPE_PSD;
        _withPH = false;
        _TimeRangeSec.first = -1.0;
        _TimeRangeSec.second= -1.0;
        _TimeRangeDateTime.first = "";
        _TimeRangeDateTime.second= "";
        _TimeSlicingList.clear();
        _L1 = -1.0;
        _SamplePosition.clear();
        _CaseInfoFilePath = "";

        std::string utsusemi_inst_path = UtsusemiEnvGetInstDir(); // python-utsusemi/XXX
        if (utsusemi_inst_path==""){
            UtsusemiError(_MessageTag+"Initialize >> Not found Environment Variable UTSUSEMI_BASE_DIR or UTSUSEMI_INST_CODE");
            return;
        }
        char utsusemi_inst_xml_path_c[200];
        std::snprintf( utsusemi_inst_xml_path_c, sizeof(utsusemi_inst_xml_path_c), "%s/%s", utsusemi_inst_path.c_str(), UTSUSEMIUSERPRIVXMLFILEPATH.c_str() );
        std::string utsusemi_inst_xml_path( utsusemi_inst_xml_path_c );
        _UtsusemiUserXmlPath = utsusemi_inst_xml_path;

        std::string utsusemi_priv_path = UtsusemiEnvGetUserDir();
        if (utsusemi_priv_path==""){
            UtsusemiError(_MessageTag+"Initialize >> Not found Environment Variable UTSUSEMI_USR_DIR");
            return;
        }
        _UtsusemiUserPrivPath = utsusemi_priv_path;

        _tofOriginShiftByLambda_type = -1;
        _tofOriginShiftByLambda_params.clear();
        _tofOriginShiftByLambda_lambda.clear();
        _Status=true;

        _isLoadFileOfTimeDependBackGround = false;
        _pathFileOfTimeDependBackGround = "";
    }

    //////////////////////////////////////////////////////////////////////////
    bool GetStatus(){ return _Status; }
    //!< Puts Status
    /*!<
     *       bool GetStatus()
     *
     *   @param None
     *   @retval true  command execution succeeded
     *   @retval false command execution failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetRunNo( UInt4 runNo, UInt4 mode_no=0, std::string env_file="" ){
        if (_WE->SetRunNo( runNo, mode_no, env_file )){
        }else{
            return false;
        }

        if (_DE->SetRunNo( runNo, mode_no, env_file )){
        }else{
            return false;
        }

        _AnaEnvironFile = env_file;
        _runNo = _WE->_runNo;
        _runNos = _WE->_runNos;

        return true;
    }
    //!< sets run No and environ_ana.xml
    /*!< This set run number and read environ_ana.xml
     *   to select WiringInfo and DetecorInfo suitable for the run number.
     *   If evn_file is empty(), this uses UTSUSEMI_USR_DIR/ana/xml(_UtsusemiUserXmlPath)/environ_ana.xml.
     *   If evn_file is set, the path of env_file is used as _UtsusemiUserXmlPath.
     *       bool SetRunNo( UInt4 runNo, std::string env_file="" )
     *       bool SetRunNo( std::string runNos, std::string env_file="" )
     *
     *   @param runNo    (UInt4)  run number
     *   @param mode_no  (UInt4)  Mode number defined in environ_ana.xml
     *   @param env_file (std::string) environ_ana.xml which includes several WiringInfo and DetectorInfo for each run number.
     *   @retval true     : succeeded
     *   @retval false    : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetRunNo( std::string runNos, std::string mode_no="0", std::string env_file="" ){
        if (_WE->SetRunNo( runNos, mode_no, env_file )){
        }else{
            return false;
        }

        if (_DE->SetRunNo( runNos, mode_no, env_file )){
        }else{
            return false;
        }

        _AnaEnvironFile = env_file;
        _runNo = _WE->_runNo;
        _runNos = _WE->_runNos;

        return true;
    }
    //!< sets run No and environ_ana.xml
    /*!< This set run number and read environ_ana.xml
     *   to select WiringInfo and DetecorInfo suitable for the run number.
     *   If evn_file is empty(), this uses UTSUSEMI_USR_DIR/ana/xml(_UtsusemiUserXmlPath)/environ_ana.xml.
     *   If evn_file is set, the path of env_file is used as _UtsusemiUserXmlPath.
     *       bool SetRunNo( UInt4 runNo, std::string env_file="" )
     *       bool SetRunNo( std::string runNos, std::string env_file="" )
     *
     *   @param runNos   (std::string) run numbers. format : "1234,1235"
     *   @param mode_no  (UInt4)  Mode number defined in environ_ana.xml
     *   @param env_file (std::string) environ_ana.xml which includes several WiringInfo and DetectorInfo for each run number.
     *   @retval true     : succeeded
     *   @retval false    : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetRunNo( std::string runNos, std::string wfile, std::string dfile, std::string mode_no ){
        if ((wfile=="-")||(wfile=="")){
            if (_WE->SetRunNo( runNos, mode_no, "" )){
            }else{
                return false;
            }
        }else{
            if (_WE->SetRunNoWithWiringInfo( runNos, wfile )){
            }else{
                UtsusemiError(_MessageTag+"SetRunNo >> WiringInfo is invalid. ("+wfile+")" );
                return false;
            }
        }
        if ((dfile=="")||(dfile=="-")){
            if (_DE->SetRunNo( runNos, mode_no, "" )){
            }else{
                return false;
            }
        }else{
            if (_DE->SetRunNoWithDetectorInfo( runNos, dfile )){
            }else{
                UtsusemiError(_MessageTag+"SetRunNo >> DetectorInfo is invalid. ("+dfile+")" );
                return false;
            }
        }

        _AnaEnvironFile = "";
        _runNo = _WE->_runNo;
        _runNos = _WE->_runNos;

        return true;
    }
    //!< sets run No and environ_ana.xml
    /*!< This set run number and read environ_ana.xml
     *   to select WiringInfo and DetecorInfo suitable for the run number.
     *   If evn_file is empty(), this uses UTSUSEMI_USR_DIR/ana/xml(_UtsusemiUserXmlPath)/environ_ana.xml.
     *   If evn_file is set, the path of env_file is used as _UtsusemiUserXmlPath.
     *       bool SetRunNo( UInt4 runNo, std::string env_file="" )
     *       bool SetRunNo( std::string runNos, std::string env_file="" )
     *
     *   @param runNos   (std::string) run numbers. format : "1234,1235"
     *   @param wfile    (std::string) WiringInfo.xml if required to indicate directly
     *   @param dfile    (std::string) DetectorInfo.xml if required to indicate directly
     *   @param mode_no  (UInt4)  Mode number defined in environ_ana.xml
     *   @retval true     : succeeded
     *   @retval false    : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetRunNo( UInt4 runNo, std::string wfile, std::string dfile, std::string mode_no ){
        std::string runNos = _stools->UInt4ToString( runNo );
        return SetRunNo( runNos, wfile, dfile, mode_no );
    }
    //!< sets run No and environ_ana.xml
    /*!< This set run number and read environ_ana.xml
     *   to select WiringInfo and DetecorInfo suitable for the run number.
     *   If evn_file is empty(), this uses UTSUSEMI_USR_DIR/ana/xml(_UtsusemiUserXmlPath)/environ_ana.xml.
     *   If evn_file is set, the path of env_file is used as _UtsusemiUserXmlPath.
     *       bool SetRunNo( UInt4 runNo, std::string env_file="" )
     *       bool SetRunNo( std::string runNos, std::string env_file="" )
     *
     *   @param runNo    (UInt4)  run number
     *   @param wfile    (std::string) WiringInfo.xml if required to indicate directly
     *   @param dfile    (std::string) DetectorInfo.xml if required to indicate directly
     *   @param mode_no  (UInt4)  Mode number defined in environ_ana.xml
     *   @retval true     : succeeded
     *   @retval false    : failed
     */


    //////////////////////////////////////////////////////////////////////////
    bool SetConversionParameter( std::string params, UInt4 _ptnId=0 ){
        return _WE->SetConversionParameter( params, _ptnId );
    }
    //!< sets conversion parameter for histogram creations
    /*!<     bool SetConversionParameter( std::string params, UInt4 _ptnId=0 )
     *       Format of params
     *        TOF
     *         delta-TOF const :  tof,<min_tof>,<max_tof>,<delta_tof>
     *         d-TOF/TOF const : rtof,<min_tof>,<max_tof>,<racio>
     *
     *        TOF with time forcusing
     *          delta-TOF const : tf-tof,<min_tof>,<max_tof>,<delta_tof>
     *          d-TOF/TOF const : tf-rtof,<min_tof>,<max_tof>,<racio>
     *
     *        Lambda
     *          delta-lambda const        :  lambda,<min_lambda>,<max_lambda>,<delta_lambda>
     *          delta-lambda/lambda const : rlambda,<min_lambda>,<max_lambda>,<racio>
     *
     *        Energy
     *           energy,<min_energy>,<max_energy>,<delta_energy>
     *
     *        Momentum Transfer
     *            q,<min_Q>,<max_Q>,<delta_Q>[,<ki_x>,<ki_y>,<ki_z>]
     *
     *        Energy Transfer
     *            hw,<Ei>,<min_hw>,<max_hw>,<delta_hw>[,<t0_shift>]
     *
     *        d-value
     *            d,<min_d-val>,<max_d-val>,<delta_d-val>
     *
     *   @param params   (std::string) parameters for histogram ceration
     *   @param _ptnId   (UInt4)  ID of this parameters in WiringInfo
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetDetRange( std::string params="All" ){
        std::string param_trim = "";
        for (std::string::size_type c=params.find_first_of(" "); c!=std::string::npos; c=params.find_first_of(" ") )
            params.erase(c,1);
        if (param_trim!="") params = param_trim;
        std::vector<Int4> bankIds = _DE->PutBankIdList();
        if (bankIds.empty()){
        }else{
            std::string new_params = "";

            std::vector<std::string> tmp = _stools->SplitString(params,",");
            for (std::vector<std::string>::iterator it=tmp.begin(); it!=tmp.end(); ++it){
                std::string body=(*it);
                std::string num_of_pixel_s="";
                std::string::size_type ii1 = body.find( ":" );
                if (ii1!=std::string::npos){
                    body=(*it).substr(0,ii1);
                    num_of_pixel_s = (*it).substr(ii1);
                }

                for (std::vector<Int4>::iterator it_b=bankIds.begin(); it_b!=bankIds.end(); ++it_b){
                    std::vector<std::string> bankInfo = _DE->PutBankInfo( (*it_b) );
                    if (bankInfo.size()<2) break;
                    if (bankInfo[1]=="") break;
                    if (body==bankInfo[0]){
                        std::string rep_param = "";
                        for (UInt4 i=1;i<bankInfo.size(); i++)
                            rep_param += (bankInfo[i] + num_of_pixel_s + ",");
                        new_params += rep_param;
                    }
                }
            }
            if (new_params!="") params = new_params.substr( 0, new_params.size()-1);

        }
        return _WE->SetDetRange( params );
    }
    //!< sets detector range for histogram creations
    /*!<     bool SetDetRange( std::string params="All" )
     *       Format of params
     *        "All[:<number_of_pixels>]"                     : use all detectors
     *        "<startDetId>-<endDetId>[:<number_of_pixels>]" : use detectors from <startDetId> to <endDetId>
     *        ( "X-Y:Z,A-B:C,D-E:F..." can be used for more settings in my plan )
     *        "<BankName>[:<number_of_pixels>[,<BankName>...]]": use detectors in the bank(s) described in DetectorInfo.xml
     *
     *   @param params   (std::string) parameters for histogram ceration
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetFrameInfo( std::string params="None" ){
        return _WE->SetFrameInfo( params );
    }
    //!< sets Frame Info for histogram creations
    /*!<     bool SetFrameInfo( std::string params )
     *       Format of params
     *        "<detType>[,<LLD_min> [,<LLD_max>] ]"
     *            - detType in {"psd","n2mon","psd-ph","n2mon-ph"}
     *            - "-PH" means that Pulse Height is calculated at the same time
     *
     *   @param params   (std::string) parameters for histogram ceration
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetDetParam( std::string params="psd" ){
        bool ret = _WE->SetDetParam( params );
        if (ret){
            _DetType = _WE->_DetType;
            _withPH = _WE->_withPH;
        }
        return ret;
    }
    //!< sets detector parameter to use for histogram creations
    /*!<     bool SetDetParam( std::string params="psd" )
     *       Format of params
     *        "<detType>[,<LLD_min> [-<LLD_max>] ]"
     *            - detType in {"psd","n2mon","psd-ph","n2mon-ph"}
     *            - "-PH" means that Pulse Height is calculated at the same time
     *            - default values for LLD are min=0, max=10000
     *
     *   @param params   (std::string) detector parameters for histogram ceration
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetMaskInfo( std::string params="NoFile", UInt4 _ptnId=0 ){
        return _WE->SetMaskInfo( params, _ptnId );
    }
    //!< sets MASK for histogram creations
    /*!<     bool SetMaskInfo( std::string params="NoFile", UInt4 _ptnId=0 )
     *       Format of params
     *        "<Mask.xml>[,<TOF-Mask from>-< to > [,<TOF-Mask from>-<to>] ]"
     *            - Mask.xml = "NoFile" if no mask.
     *
     *   @param params   (std::string) detector parameters for histogram ceration
     *   @param _ptnId   (UInt4)  ID of this parameters in WiringInfo
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetTimeDependBackGroundInfo( std::string params="None" ){
        return _WE->SetTimeDependBackGroundInfo( params );
    }
    //!< sets Tof region to be used for TimeDependBackground correction
    /*!<     bool SetTimeDependBackGroundRegionInfo( std::string params="None" )
     *       Format of params
     *        "None" : not used this background correction
     *        "tof0-tof1" : tof0 is start tof of region, tof1 is last of region
     *
     *   @param params   (std::string) TimeDepend BackGroundRegion
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    void SetSaveFileOfTimeDependBackGround( std::string path ){
        _isLoadFileOfTimeDependBackGround = false;
        _pathFileOfTimeDependBackGround = path;
    }
    //!< sets the file name to store the time-depend background information
    /*!<     bool SetSaveFileOfTimeDependBackGround( std::string path )
     *
     *   @param path (std::string) the full path of file
     *   @retval None
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetFileOfTimeDependBackGround( std::string path ){
        std::string found_path = FindParamFilePath( path );
        if (found_path=="") return false;
        _isLoadFileOfTimeDependBackGround = true;
        _pathFileOfTimeDependBackGround = found_path;
        return true;
    }
    //!< sets the file name which store the time-depend background information
    /*!<     bool SetFileOfTimeDependBackGround( std::string path )
     *       Format of params
     *        "None" : not used this background correction
     *        "tof0-tof1" : tof0 is start tof of region, tof1 is last of region
     *
     *   @param params   (std::string) the name of the file (fullpath or only name)
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetTimeRange( std::string params="All" ){
        _TimeRangeSec.first = -1.0;
        _TimeRangeSec.second= -1.0;
        _TimeRangeDateTime.first = "";
        _TimeRangeDateTime.second= "";
        _TimeSlicingList.clear();

        std::string check_st( params );
        transform( check_st.begin(), check_st.end(), check_st.begin(), ::toupper);
        if (check_st=="ALL") return true;

        std::vector<std::string> tmp = _stools->SplitString( params, "," );
        if (tmp.size()==1){
            std::string ret_path = FindParamFilePath( params );
            if (ret_path!=""){
                std::ifstream ifs(ret_path.c_str());
                if (ifs.fail()){
                    UtsusemiError(_MessageTag+"SetTimeRange >>  Failed to read "+ret_path);
                    ifs.close();
                    return false;
                }
                std::string a_line;
                while (getline(ifs,a_line)){
                    if (a_line.substr(0,1)!="#"){
                        std::vector<std::string> conts = _stools->SplitString( a_line, "," );
                        if (conts.size()==2){
                            _TimeSlicingList.push_back( _stools->StringToDouble( conts[0] ) );
                            _TimeSlicingList.push_back( _stools->StringToDouble( conts[1] ) );
                        }else{
                            UtsusemiWarning(_MessageTag+"SetTimeRange : invalid text line ("+a_line+")" );
                        }
                    }
                }
                if (!_TimeSlicingList.empty()){
                    _CaseInfoFilePath = "";
                    return true;
                }else UtsusemiWarning(_MessageTag+"SetTimeRange : file found but no content" );
            }
        }
        if ( (tmp.size()!=2)&&(tmp.size()!=4) ){
            return false;
        }
        if (tmp.size()==2){
            for (UInt4 i=0; i<tmp.size(); i++){
                if (i==0) _TimeRangeSec.first = _stools->StringToDouble( tmp[i] );
                else _TimeRangeSec.second = _stools->StringToDouble( tmp[i] );
            }
        }else if ((tmp[0].find("/")!=std::string::npos)&&(tmp[1].find(":")!=std::string::npos)&&
                  (tmp[2].find("/")!=std::string::npos)&&(tmp[3].find(":")!=std::string::npos)){
            std::string tmp_date_time = "";
            for (UInt4 i=0; i<tmp.size(); i+=2){
                std::vector<std::string> tmp_date_sp = _stools->SplitString( tmp[i], "/" );
                std::vector<std::string> tmp_time_sp = _stools->SplitString( tmp[i+1], ":" );
                if ( (tmp_date_sp.size()!=3)||(tmp_time_sp.size()!=3) ){
                    UtsusemiError( _MessageTag+"SetTimeRange : parameters format is invalide. params="+params );
                    return false;
                }
                tmp_date_time = tmp_date_sp[0]+","+tmp_date_sp[1]+","+tmp_date_sp[2]+",";
                tmp_date_time+= tmp_time_sp[0]+","+tmp_time_sp[1]+","+tmp_time_sp[2]+",0.0";
                UtsusemiMessage( _MessageTag+"SetTImeRange >> Time Slice (Date form) = "+tmp_date_time );

                if (i==0) _TimeRangeDateTime.first = tmp_date_time;
                else _TimeRangeDateTime.second = tmp_date_time;
            }

        }else{
            UtsusemiError( _MessageTag+"SetTimeRange : parameters format is invalide. params="+params );
            return false;
        }

        return true;
    }
    //!< sets Time range for histogram creations
    /*!<     bool SetTimeRange( std::string params="All" )
     *       Format of params
     *        "All"                   : use all detectors
     *        "<startSec>,<endSec>"   : use events in measurement from <startSec> to <endSec> [sec]
     *                                    which Time format is the passed time from measurement start.
     *        "<startDate>,<startTime>,<endDate>,<endTime>"
     *                                : use events in period of these params
     *                                  "YYYY/MM/DD","hh:mm:ss","YYYY/MM/DD","hh:mm:ss"
     *
     *   @param params   (std::string) parameters for histogram ceration
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetCaseInfo( std::string params="None" ){
        std::vector<std::string> tmp = _stools->SplitString( params, "," );
        if (tmp.size()==1){
            std::string a_word( tmp[0] );
            transform( tmp[0].begin(), tmp[0].end(), a_word.begin(), ::toupper);
            if (a_word.find("NONE")!=std::string::npos){
                return true;
            }else{
                //_CaseInfoFilePath=a_word;
                _CaseInfoFilePath = FindParamFilePath(tmp[0]);
                if (_CaseInfoFilePath==""){
                    UtsusemiError(_MessageTag+"SetCaseInfo : not found parameter file = "+tmp[0]);
                    return false;
                }
            }
        }
        return true;
    }
    //!< sets case info for histogram creations
    /*!<     bool SetCaseInfo( std::string params="None" )
     *       Format of params
     *         (not defined)
     *
     *   @param params   (std::string) parameters for histogram ceration
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetTofShiftInfo( std::string params ){
        std::vector<std::string> v_params = _stools->SplitString( params, "," );
        if (v_params.empty()){
            UtsusemiError( _MessageTag+"SetTofShiftInfo >> params are invalid." );
            return false;
        }
        UInt4 ptnId = _stools->StringToUInt4( v_params[0] );
        std::string xparams = "";
        if (v_params.size()>1){
            for (UInt4 i=0; i<(v_params.size()-2); i++) xparams += ( v_params[i+1] + "," );
            xparams += v_params.back();
        }

        return SetTofShiftInfo( ptnId, xparams, "" );
    }
    //!< sets Tof shift info for histogram creations
    /*!<     bool SetTofShiftInfo( UInt4 ptnId )
     *       bool SetTofShiftInfo( std::string params )
     *       bool SetTofShiftInfo( std::string ptnId, std::string xparams="", std::string lambdas="" )
     *
     *       params format : <ptnId>[,p1,p2,p3,...]
     *
     *   @param params   (std::string) Pattern ID and its parameters as std::string
     *   @param ptnId    (UInt4) Pattern ID for a method to calculate TOF shift.
     *   @param xparams   (std::string) parameters for this Pattern ID method ( if need )
     *   @param lambdas  (std::string) if scattered data in lambda axis, use this.
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    bool SetTofShiftInfo( UInt4 ptnId, std::string xparams="", std::string lambdas="" ){
        bool ret = false;

        _tofOriginShiftByLambda_type = ptnId;

        if (_tofOriginShiftByLambda_type==0){
            std::vector<std::string> v_params = _stools->SplitString( xparams, "," );
            std::vector<std::string> v_lambda = _stools->SplitString( lambdas, "," );
            if ( (v_params.size())==(v_lambda.size()) ){
                _tofOriginShiftByLambda_params.clear();
                _tofOriginShiftByLambda_lambda.clear();
                _tofOriginShiftByLambda_params.resize( v_params.size() );
                _tofOriginShiftByLambda_lambda.resize( v_params.size() );
                for (UInt4 i=0; i<(v_params.size()); i++){
                    _tofOriginShiftByLambda_params[i] = _stools->StringToDouble( v_params[i] );
                    _tofOriginShiftByLambda_lambda[i] = _stools->StringToDouble( v_lambda[i] );
                }
                ret = true;
            }else{
                UtsusemiWarning( _MessageTag+"SetTofShiftInfo >> two params conflict " );
            }
        }else{
            UtsusemiTofOriginCorrection* UTO = new UtsusemiTofOriginCorrection();
            if (UTO->SetTofOriginCorrectionType( _tofOriginShiftByLambda_type )){
                if (xparams.empty()) ret = true;
                else{
                    std::vector<std::string> v_params = _stools->SplitString( xparams, "," );
                    if (v_params.size() == (UTO->PutNumOfParam())){
                        _tofOriginShiftByLambda_params.clear();
                        _tofOriginShiftByLambda_params.resize( v_params.size() );
                        for (UInt4 i=0; i<(v_params.size()); i++)
                            _tofOriginShiftByLambda_params[i] = _stools->StringToDouble( v_params[i] );
                        ret = true;
                    }else{
                        UtsusemiError( _MessageTag+"SetTofShiftInfo >> params size is not match. " );
                    }
                }
            }else{
                UtsusemiError( _MessageTag+"SetTofShiftInfo >> ptnId is invalid.("+_stools->UInt4ToString( _tofOriginShiftByLambda_type )+")" );
            }
        }

        if (ret){
        }else{
            _tofOriginShiftByLambda_type = -1;
            _tofOriginShiftByLambda_params.clear();
            _tofOriginShiftByLambda_lambda.clear();
        }

        return ret;
    }

    //////////////////////////////////////////////////////////////////////////
    std::string MakeTempWiringInfo( std::string priv_path=""){
        return _WE->MakeTempWiringInfo( priv_path );
    }
    //!< make and save the temporal wiring info to create histogram
    /*!< this returns a path of the saved temporal wiring info file
     *       std::string MakeTempWiringInfo()
     *
     *   @param None
     *   @return (std::string) : the path of output wiring info file
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetL1( Double l1 ){
        _L1 = l1;
        return true;
    }
    //!< sets L1 on DetectorInfo
    /*!< L1 means the distance between neutron source (moderator) and a sample
     *       bool SetL1( Double l1 )
     *
     *   @param l1   (Double)
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    //////////////////////////////////////////////////////////////////////////
    bool SetSamplePosition( Double px, Double py, Double pz ){
        _SamplePosition.clear();
        _SamplePosition.push_back(px);
        _SamplePosition.push_back(py);
        _SamplePosition.push_back(pz);
        return true;
    }
    //!< sets SamplePosition on DetectorInfo
    /*!< Sample Positions are set the absolute position of Sample
     *       bool SetSamplePosition( Double px, Double py, Double pz )
     *
     *   @param  px   (Double)
     *   @param  py   (Double)
     *   @param  pz   (Double)
     *   @retval true    : succeeded
     *   @retval false   : failed
     */

    UInt4 PutNumOfPixelForDet(UInt4 _detId=0){ return _WE->PutNumOfPixelForDet(_detId); }
    Double PutL1(){ return _DE->PutInstL1(); }
    Double PutTypicalL2(){ return _DE->PutInstTypicalL2(); }
    Double PutTypicalDS(){ return _DE->PutInstTypicalDS(); }
    //////////////////////////////////////////////////////////////////////////
    std::string MakeTempDetectorInfo(){
        if (_L1<0.0){
        }else{
            if (_DE->SetInstInfoL1( _L1 )){
            }else{
                UtsusemiError( _MessageTag+"MakeTempDetectorInfo >> Failed to set L1="+_stools->DoubleToString(_L1) ) ;
                return "";
            }
        }
        if (_SamplePosition.empty()){
        }else{
            if (_DE->SetInstInfoSamplePosition( _SamplePosition[0], _SamplePosition[1], _SamplePosition[2] )){
            }else{
                UtsusemiError( _MessageTag+"MakeTempDetectorInfo >> Failed to set SamplePosition=" );
                return "";
            }
        }
        return _DE->MakeTempDetectorInfo();
    }
    //!< make and save the temporal detector info to create histogram
    /*!< this returns a path of the saved temporal detector info file
     *       std::string MakeTempDetectorInfo()
     *
     *   @param None
     *   @return (std::string) : the path of output detector info file
     */

    //////////////////////////////////////////////////////////////////////////
    virtual std::vector<std::string> MakeTempInfoFiles(){
        // Setting Parameter files
        std::vector<std::string> pfiles;
        UtsusemiAnaEnvironReader *UAR = new UtsusemiAnaEnvironReader( _AnaEnvironFile );
        if (UAR->_Status){
            pfiles = UAR->PutParamFiles( _runNo );
            if (pfiles.empty()){
                UtsusemiMessage(_MessageTag+"MakeTempInfoFiles >> Filed to get parameter files from given runNo." );
                return pfiles;
            }
        }else{
            UtsusemiMessage(_MessageTag+"MakeTempInfoFiles >> Failed AnaEnvironReader Initialization" );
            delete UAR;
            pfiles.clear();
            return pfiles;
        }
        delete UAR;

        // set wiring info file
        pfiles[0] = MakeTempWiringInfo();
        if (pfiles[0]==""){
            UtsusemiMessage(_MessageTag+"MakeTempInfoFiles >> No SetRunNo " );
            return pfiles;
        }
        // set detector info file
        pfiles[1] = MakeTempDetectorInfo();
        if (pfiles[1]==""){
            UtsusemiError( _MessageTag+"MakeTempInfoFiles >> ERROR to make detectroInfo " );
            return pfiles;
        }

        // set detector info file or wiring
        for (UInt4 i=2; i<(pfiles.size()); i++){
            if (pfiles[i]!=""){
                char pathc[200];
                std::snprintf( pathc, sizeof(pathc), "%s/%s", _UtsusemiUserXmlPath.c_str(), pfiles[i].c_str() );
                std::string path( pathc );
                FILE* fp;
                if ((fp=fopen( path.c_str(), "r" ))==NULL){
                    char pathc2[200];
                    std::snprintf( pathc2, sizeof(pathc2), "%s/%s/%s", _UtsusemiUserPrivPath.c_str(), UTSUSEMIUSERPRIVXMLFILEPATH.c_str(), pfiles[i].c_str() );
                    std::string path2( pathc2 );
                    if ((fp=fopen( path2.c_str(), "r" ))==NULL){
                        UtsusemiError( _MessageTag+"MakeTempInfoFiles >> Not found file = "+pfiles[i] );
                        return pfiles;
                    }
                    path = path2;
                }
                fclose(fp);
                pfiles[i] = path;
            }
        }
        return pfiles;
    }
    //!< make the temporal all info files to create histogram
    /*!< this returns a path of the info files ex. WiringInfo,DetectorInfo and CaseInfo
     *       std::vector<std::string> MakeTempInfoFiles()
     *
     *   @param None
     *   @return (std::vector<std::string>) : pathes for info files [0]=WiringInfo, [1]=DetectorInfo, [2]=CaseInfo
     */

};
#endif
