#ifndef UTSUSEMIEVENTDATACONVERTERTEMPLATE_CC
#define UTSUSEMIEVENTDATACONVERTERTEMPLATE_CC

#include "UtsusemiEventDataConverterTemplate.hh"
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
UtsusemiEventDataConverterTemplate<T1,T2>::
UtsusemiEventDataConverterTemplate(){
    Initialize();
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
UtsusemiEventDataConverterTemplate<T1,T2>::
~UtsusemiEventDataConverterTemplate(){
    Clear(0);
    delete _EventDecoder;
    delete _CaseDecoder;
    ClearTimeDependBackGroundList();
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
Clear( UInt4 type ){

    if ((type==0)||(type==2)){
        if (_gslHist!=NULL){
            if (!(_gslHist->empty())){
                for (UInt4 i=0; i<_gslHist->size(); i++){
                    if ((_gslHist->at(i))!=NULL) {
                        delete (_gslHist->at(i));
                        //std::cout << "### delete gslHist i=" << i << std::endl;
                    }
                }
            }
            delete _gslHist;
            _gslHist=NULL;
        }
        _isUnReadDetId.clear();
    }

    if (type==0){
        if (_convOuterPixelIdToInnerId!=NULL){
            delete _convOuterPixelIdToInnerId;
        }
        _convOuterPixelIdToInnerId=NULL;

        if (!(_tofRangePointers.empty())){
            for (UInt4 i=0; i<_tofRangePointers.size(); i++){
                delete [] _tofRangePointers[i];
            }
        }

        delete _stools;
    }

}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
Initialize(){
    _tofRangePointers.clear();
    _gslHist = NULL;
    _EventDecoder = new T1();
    _CaseDecoder = new T2();
    _numOfInnerPixels = 0;
    _numOfCases = 0;
    _eventSize = 0;
    _stools = new StringTools();
    _MessageTag = "UtsusemiEventDataConverterTemplate >> ";
    _convOuterPixelIdToInnerId = NULL;
    _runNumber = 0;
    _instCode = "";
    _isReady = true;
    _dataFileList.Clear();
    _t0dataFileList.Clear();
    _isUnReadDetId.clear();
    _dataPathes.first = "";
    _dataPathes.second = "";

    _NumOfMulTh = UtsusemiGetNumOfMulTh();
    _numOfAdditionalClocks = 3;
    UtsusemiCheckLogQuiet();

    _timeDependBackGroundList = NULL;
    _isLoadedTimeDependBackGroundList = false;
    _timeDependBackGroundNormalizeFactor = 0.0;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
bool UtsusemiEventDataConverterTemplate<T1,T2>::
SetEventParams( std::string wiring_file, std::string detector_file ){
    Int4 ret = _EventDecoder->SetParametersFromFiles( wiring_file, detector_file );
    if (ret<0) {
        UtsusemiError( _MessageTag+"Fails to load parameter files ");
        return false;
    }
    _eventSize = _EventDecoder->_EventSize;
    _numOfInnerPixels = _EventDecoder->PutNumOfInnerPixels();
    _instCode = _EventDecoder->_instCode;
    return true;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetCaseInfoParams( std::string pathToCaseInfo ){
    _CaseDecoder->ReadCaseInfoFile( pathToCaseInfo );
}
//////////////////////////////////////////////////////////
//template <typename T1, typename T2>
//void UtsusemiEventDataConverterTemplate<T1,T2>::
//ReadCaseEventFiles( std::vector<std::string> files ){
//    _CaseDecoder->ReadCaseEventFiles( files );
//}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
ReadCaseEventFiles( UInt4 index, std::vector<std::string> evt_files, std::vector<std::string> t0b_files ){
    _CaseDecoder->ReadCaseEventFiles( index, evt_files, t0b_files );
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
ReadCaseEvent( UInt4 index, std::vector<std::string> evt_files, std::vector<std::string> t0b_files ){
    _CaseDecoder->ReadCaseEvent( index, evt_files, t0b_files );
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetFlagOfPulseIdCheck( bool flag ){
    _CaseDecoder->isCheckedPulseId = flag;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
AllocateGslHist( UInt4 numOfPixel, UInt4 numOfCases ){

    if ((numOfPixel==0)&&(_numOfInnerPixels==0)){
        UtsusemiError("Invalid Allocation numOfPixel=0");
        return;
    }

    if ((numOfCases==0)&&(_numOfCases==0)&&(_CaseDecoder->_NumOfCases==0)){
        UtsusemiError("Invalid Allocation numOfCases=0");
        return;
    }

    if (numOfPixel!=0) _numOfInnerPixels = numOfPixel;
    if (numOfCases!=0) {
        _numOfCases = numOfCases;
    }else{
        _numOfCases = _CaseDecoder->_NumOfCases;
    }

    UInt4 total_pixels = _numOfInnerPixels * _numOfCases;
    Clear(2);

    _gslHist = new std::vector<GslHistogram*>( total_pixels, NULL );
    UtsusemiMessage( _MessageTag+"AllocateGslHist : total_pixels = "+_stools->UInt4ToString(total_pixels));
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetHistBin( UInt4 innerPixelId, Double *tof, UInt4 Size ){

#ifdef MULTH
    GslHistogram *gs = new GslHistogram( tof, Size, _NumOfMulTh );
#else
    GslHistogram *gs = new GslHistogram( tof, Size );
#endif
    if (( _gslHist->at(innerPixelId) )!=NULL) {
        delete _gslHist->at(innerPixelId);
        UtsusemiError( "GSL_HIST is not empty" );
    }

    _gslHist->at(innerPixelId) = gs;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetHistBin( UInt4 innerPixelId, std::vector<Double> tof ){
    if (tof.empty()){
        std::string msg = _MessageTag + " SetHistBin >> tof argument is empty at innerPixelId = "+_stools->UInt4ToString(innerPixelId);
        UtsusemiError(msg);
        //std::cout << msg << std::endl;
        return;
    }
    Double* _tofRange = new Double [ tof.size() ];
    _tofRangePointers.push_back(_tofRange);
    for( UInt4 i=0; i<tof.size(); i++ ){
        _tofRange[i] = tof[i];
    }
    for (UInt4 i=0;i<_numOfCases;i++){
      SetHistBin( (_numOfInnerPixels*i + innerPixelId), _tofRange, (UInt4)(tof.size()) );
    }
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetHistBin(){
    std::vector<UInt4> outerPixelIdList = _EventDecoder->PutPixelIdList(true);
    for (UInt4 i=0; i<outerPixelIdList.size(); i++){
        SetHistBin( _EventDecoder->ConvertPixelIdToInnerId(outerPixelIdList[i]),
                    _EventDecoder->PutHistBin( outerPixelIdList[i] ));
    }
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetHistBin(ElementContainerMatrix *ecm, std::string _key){
    for (UInt4 i=0; i<(ecm->PutSize()); i++){
        for (UInt4 j=0; j<(ecm->PutPointer(i)->PutSize()); j++){
            ElementContainer* ec = ecm->PutPointer(i)->PutPointer(j);
            HeaderBase* hh = ec->PutHeaderPointer();
            if (hh->CheckKey( UTSUSEMI_KEY_HEAD_PIXELID )==1){
                if ((_key=="")||(ec->CheckKey(_key)==1))  _key="TofBin";
                ec->Add( _key, _EventDecoder->PutHistBin( (UInt4)(hh->PutInt4(UTSUSEMI_KEY_HEAD_PIXELID))  ) );
            }
        }
    }
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetHistAllocation(UInt4 num_of_multh){
    if (num_of_multh!=0) _NumOfMulTh=num_of_multh;
    AllocateGslHist();
    SetHistBin();
    InitTimeDependBackGroundList();
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
Increment(UInt4 daqId, UInt4 moduleNo, const UChar* data, UInt4 size, UInt4 ThNum, std::vector<Double>* Offset, std::vector<UInt4>* Case ){

    UInt4 index = 0;
    UInt4 pixelId = 0;
    Double tof = 0.0;
    UInt4 caseId = 0;
    UInt4 histId = 0;
    UInt4 ret = 0;

    _EventDecoder->ClearPrevT0Event(ThNum);
    for (UInt4 i=0; i<size; i++){
        index = i*_eventSize;

        ret = _EventDecoder->DecodeEventData( daqId, moduleNo, (data+index), &pixelId, &tof, Offset, ThNum );

        if (_EventDecoder->IsNeutronEvent(ret)){

            if (Case==NULL){
                caseId = 1;
            }else if (Case->size()==1){
                caseId = Case->at(0);
            }else{
                caseId = _CaseDecoder->GetCaseFromTof( pixelId, &tof, Case );
            }

            if (caseId!=0){
                //std::cout << "@@@@@ histId ::caseId=" << caseId << ",_numOfInnderPixels=" << _numOfInnerPixels << ",innerPixelId=" << _EventDecoder->ConvertPixelIdToInnerId( pixelId ) << std::endl;
                histId = _numOfInnerPixels*(caseId-1) + _EventDecoder->ConvertPixelIdToInnerId( pixelId );
                if ((histId+1)>(*_gslHist).size()){
                    std::cout << _MessageTag << " Increment : histId is too large; histId(size)=" << histId << "(" << _gslHist->size() << ")"<< std::endl;
                }else{
                    //std::cout << "histid="<<histId <<",tof="<< tof <<",tof="<<_CaseDecoder->CalcIncrementPosi( &tof, &pixelId, &caseId )<<std::endl;
                    _gslHist->at(histId)->Increment( _CaseDecoder->CalcIncrementPosi( &tof, &pixelId, &caseId ),
                                                    ThNum,
                                                    _EventDecoder->CalcIncrementVal( &tof, &pixelId ) );
                }
            }else{
                //std::cout << "caseId=" << caseId << std::endl;
            }


        }else{
            //std::cout << "ret=" << ret << std::endl;
        }
    }
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, std::vector<UInt8> T0Table, std::vector<Double> ClockTable, std::vector<std::vector<UInt4>*> *CaseTable ){
    //std::cout << "--- PreIncrement " << std::endl;
    UInt8 size = T0Table[ T0Table.size()-1 ];
    UInt4 TableSize = (UInt4)(T0Table.size());
    UInt4 num_of_preClocks = (UInt4)(ClockTable.size())-TableSize;
    UChar *CopyData = new UChar [ size * _eventSize ];
    bool isUseCases = true;
    if (CaseTable->empty()) isUseCases=false;

#ifdef MULTH
    omp_set_num_threads( _NumOfMulTh );
#endif

#pragma omp parallel for
#if (_OPENMP >= 200805)  // OpenMP 3.0 and later
    for( UInt4 i=0; i<size*_eventSize; i++ ){
#else
    for( Int4 i=0; i<size*_eventSize; i++ ){
#endif
        CopyData[i] = data[i];
    }

#ifdef MULTH
#pragma omp parallel for
#if (_OPENMP >= 200805)  // OpenMP 3.0 and later
    for( UInt4 i=0; i<TableSize-1; i++ ){
#else
    for( Int4 i=0; i<(Int4)TableSize-1; i++ ){
#endif
        //std::cout << "PreIncrement i/n=" << i << "/" << (TableSize-1);
        UInt8 Ini = T0Table[i];
        UInt4 ThNum = 0;
        UInt4 DataSize = (UInt4)(T0Table[i+1]-T0Table[i]);
        std::vector<Double>* Clock = new std::vector<Double>(_numOfAdditionalClocks,0.0);
        if (i==0){
            if (num_of_preClocks>0) Clock->at(1)=ClockTable[num_of_preClocks-1];
            Clock->at(2)=ClockTable[0+num_of_preClocks]+(Clock->at(1));
        }else if (i==1){
            Clock->at(1)=ClockTable[1+num_of_preClocks];
            Clock->at(2)=ClockTable[0+num_of_preClocks]+(Clock->at(1));
        }else{
            Clock->at(1)=ClockTable[i+num_of_preClocks];
            if ( (Clock->at(1)) > (_EventDecoder->_MicroSec_Par_Frame+1000.0))
                Clock->at(2)=Clock->at(1);
            else
                Clock->at(2)=ClockTable[i+num_of_preClocks-1]+(Clock->at(1));
        }

        std::vector<UInt4>* Case = NULL;
        if (isUseCases) {
            Case = CaseTable->at(i);
            //std::cout << "Case size=" << Case->size() << ":" << Case->at(0) <<","<< Case->at(1) << std::endl;
        }

#ifdef MULTH
        ThNum = omp_get_thread_num();
#endif
        try{
            //std::cout <<"Increment st i="<<i<<std::endl;
            Increment( daqId, moduleNo, CopyData+(Ini*_eventSize), DataSize, ThNum, Clock, Case );
            //std::cout <<"Increment fin i="<<i;
        }
        catch(...){
            UtsusemiError( _MessageTag+"PreIncrement >> Increment Error; ThNum="+_stools->UInt4ToString(ThNum) );
        }
        //std::cout << "fin" << std::endl;
        delete Clock;

    }

#else
    // added by VIC -->
    std::vector<UInt4>* Case = NULL;
    if (isUseCases) {
        Case = CaseTable->at(TableSize-1);
    }
    Increment( daqId, moduleNo, CopyData, T0Table[T0Table.size()-1], 0, &ClockTable, Case );
    // <-- VIC
#endif

  delete [] CopyData;
  //std::cout << "fin PreIncrement" << std::endl;
}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, std::vector<UInt8> T0Table ){
    //std::cout << "--- PreIncrement " << std::endl;
    UInt4 TableSize = (UInt4)(T0Table.size());
    UInt8 size = T0Table[ TableSize-1 ];
    UChar *CopyData = new UChar [ size * _eventSize ];

#ifdef MULTH
    omp_set_num_threads( _NumOfMulTh );
#endif

#pragma omp parallel for
#if (_OPENMP >= 200805)  // OpenMP 3.0 and later
    for( UInt4 i=0; i<size*_eventSize; i++ ){
#else
    for( Int4 i=0; i<size*_eventSize; i++ ){
#endif
        CopyData[i] = data[i];
    }

#ifdef MULTH
#pragma omp parallel for
#if (_OPENMP >= 200805)  // OpenMP 3.0 and later
    for( UInt4 i=0; i<TableSize-1; i++ ){
#else
    for( Int4 i=0; i<(Int4)TableSize-1; i++ ){
#endif
        UInt8 Ini = T0Table[i];
        UInt4 ThNum = 0;
        UInt4 DataSize = (UInt4)(T0Table[i+1]-T0Table[i]);
        std::vector<Double>* Clock = new std::vector<Double>(_numOfAdditionalClocks,0.0);
        std::vector<UInt4>* Case = NULL;

#ifdef MULTH
        ThNum = omp_get_thread_num();
#endif
        try{
            Increment( daqId, moduleNo, CopyData+(Ini*_eventSize), DataSize, ThNum, Clock, Case );
        }
        catch(...){
            UtsusemiError( _MessageTag+"PreIncrement >> Increment Error; ThNum="+_stools->UInt4ToString(ThNum) );
        }
        delete Clock;

    }

#else
    std::vector<Double>* Clock = new std::vector<Double>(_numOfAdditionalClocks,0.0);
    std::vector<UInt4>* Case = NULL;
    Increment( daqId, moduleNo, CopyData, T0Table[T0Table.size()-1], 0, Clock, Case );
    delete Clock;
#endif

  delete [] CopyData;
  //std::cout << "fin PreIncrement" << std::endl;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetDataPath(std::string dataPath, std::string t0Path, UInt4 runNo, bool isReset,
             std::vector< std::vector< std::vector< std::vector<Int4>* >* >* >* _PixelInfoStore,
             std::vector< std::pair<UInt4,UInt4> >* maskModules, bool makeT0b )
{
    std::vector<UInt4> runNumbers( 1, runNo );
    SetDataPath( dataPath, t0Path, runNumbers, isReset, _PixelInfoStore, maskModules, makeT0b );

}

//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetDataPath( std::string dataPath, std::string t0Path, std::vector<UInt4> runNumbers, bool isReset,
             std::vector< std::vector< std::vector< std::vector<Int4>* >* >* >* _PixelInfoStore,
             std::vector< std::pair<UInt4,UInt4> >* maskModules, bool makeT0b )
{
    dataPath=FindRootDataFolder(dataPath);
    if (dataPath=="")
        UtsusemiError(_MessageTag+"SetPathToData : Not Found Data Path");

    if (isReset){
    }else if ((_dataPathes.first==dataPath)&&(_dataPathes.second==t0Path)){
        if (_runNumbers.size()!=runNumbers.size()){
        }else{
            _isReady = true;
            for (UInt4 i=0; i<_runNumbers.size(); i++){
                if (_runNumbers[i]!=runNumbers[i]) {
                    _isReady=false;
                    break;
                }
            }
            if (_isReady) return;
        }
    }

    _isReady=false;

    // Check whether the given dataPath and t0Path are existed or not
    if (t0Path!=""){
        const boost::filesystem::path dpath(t0Path.c_str());
        if ((boost::filesystem::exists(dpath)) && (boost::filesystem::is_directory(dpath))){
        }else{
            UtsusemiError( _MessageTag+"SetDataPath : not found t0Path= "+t0Path );
            return;
        }
    }

    // Set run numbers into internal variables
    _runNumbers.clear();
    _runNumbers.resize( runNumbers.size() );
    for (UInt4 i=0; i<runNumbers.size(); i++)
        _runNumbers[i] = runNumbers[i];
    _runNumber = _runNumbers.back();

    // check whether instrument data path (/data/XXX) exists;
    // /data/XXX, /data/XXX00, /data/XXX01 ...
    std::vector<std::string> pathToDataInstVect = FindInstDataFolders( _instCode, dataPath );

    // If not found /data/XXX or /data/XXXnn
    if ( (pathToDataInstVect.size()==1)&&(pathToDataInstVect[0]=="") ){
        UtsusemiError( _MessageTag +"SetPathToData : There is no path(pathToDataInst) such as " + pathToDataInstVect[0]);
        return;
    }

    _dataFileList.Clear();    // Map< std::vector<std::string> >
    _t0dataFileList.Clear();  // Map< std::vector<std::string> >
    //[inamura 160623]-->
    _MeasTimeList.clear();
    _MeasTimeList.resize( _runNumbers.size()*14, 0.0 );
    //<--[inamura 160623]
    // Steps for checking data path and files
    // 1. make list of needed modules
    // 2. Set expected pathes to t0b files
    // 3. make std::maps of edb and t0b files for each run number
    //    - make list of existing data files
    //    - make std::map by needed modules
    //    - search not-found T0B files in given t0Path, same dir as edb and $HOME/ana/xml
    //    - make not-found T0B files
    //    - add list of edb files for this run to _dataFileList
    //    - add list of t0b files for this run to _t0dataFileList
    //    - repeat these steps for each run number

    // make list of needed modules
    /*
    if (_PixelInfoStore==NULL){
        std::cout << _MessageTag+"SetDataPath2 >>> There is no information about pixels from WiringInfo.xml" << std::endl;
        return;
    }
    */
    std::vector< std::pair<UInt4,UInt4> > useModules;
    if (_PixelInfoStore!=NULL){
        for (UInt4 daq=0; daq<(_PixelInfoStore->size()); daq++){
            if (_PixelInfoStore->at(daq)!=NULL){
                for (UInt4 mod=0; mod<(_PixelInfoStore->at(daq)->size()); mod++){
                    if (_PixelInfoStore->at(daq)->at(mod)!=NULL){
                        bool isMaskModule = false;
                        if (maskModules!=NULL)
                            for (UInt4 i=0; i<(*maskModules).size(); i++)
                                if (( daq==(maskModules->at(i).first) )&&( mod==(maskModules->at(i).second ))){
                                    isMaskModule = true;
                                    break;
                                }
                        if (isMaskModule){
                        }else{
                            std::pair<UInt4,UInt4> tmp;
                            tmp.first = daq;
                            tmp.second= mod;
                            useModules.push_back( tmp );
                        }
                    }
                }
            }
        }
    }

    _dataPathes.first = dataPath;
    _dataPathes.second= t0Path;

    // Set expected pathes to t0b files
    // try to search in UTSUSEMI_USR_PRIV_DIR+"/ana/tmp"
    std::string homeT0Path = FindTempFilePath();
    if (homeT0Path==""){
        UtsusemiError( _MessageTag+"SetPathToData : Cannot find path to store temploral files such as ~/ana/tmp");
        return;
    }

    std::vector<std::string> t0PathList(3,"");
    t0PathList[0] = t0Path;      // Path to t0b files as given argument
    t0PathList[1] = "";          // Path to same directory as edb files
    t0PathList[2] = homeT0Path;  // Path to temporary files like ~/ana/tmp

    bool isFoundFirstRun = false;
    // make std::map of edb and t0b files for each run number
    for (UInt4 i_run=0; i_run<_runNumbers.size(); i_run++){
        Map< std::vector<std::string> > dataFileList;    // key=(daq,module), value=full_path_to_edb
        Map< std::vector<std::string> > t0dataFileList;  // key=(daq,module), value=full_path_to_edb

        std::vector< std::pair<std::string,std::string> > existEdbFiles; // full-path to edb files : first=path_to_folder second filename
        std::vector< std::pair<std::string,std::string> > existT0bFiles; // full-path to t0b files

        std::vector<std::string> runFolderPathList=FindRunDataFolders( _instCode, _runNumbers[i_run], pathToDataInstVect );
        if (runFolderPathList.empty()){
            return;
        }
        char runcodec[10];
        std::snprintf( runcodec, sizeof(runcodec), "%3s%06d",_instCode.c_str(), _runNumbers[i_run] );
        std::string runCode( runcodec );
        for (std::vector<std::string>::iterator it=runFolderPathList.begin(); it!=runFolderPathList.end(); ++it){
            UtsusemiMessage(_MessageTag+"SetDataPath >>> Search in "+(*it));
            const boost::filesystem::path runFolder((*it).c_str());
            if ((boost::filesystem::exists(runFolder)) && (boost::filesystem::is_directory(runFolder))){
                BOOST_FOREACH( const boost::filesystem::path& dFile,
                       std::make_pair( boost::filesystem::directory_iterator(runFolder),
                       boost::filesystem::directory_iterator()))
                {
                    std::string aFile = dFile.filename().string();
                    if (aFile.size()==24){
                        if (aFile.find( runCode )==std::string::npos) continue;
                        std::string::size_type ind_edb = aFile.find( ".edb" );
                        std::string::size_type ind_t0b = aFile.find( ".t0b" );
                        if (ind_edb==(aFile.size()-4)){
                            std::pair<std::string,std::string> path_to_edb_file;
                            path_to_edb_file.first = (*it);
                            path_to_edb_file.second= aFile;
                            existEdbFiles.push_back(path_to_edb_file);
                            if (_PixelInfoStore==NULL){
                                std::pair<UInt4,UInt4> tmp_modkey;
                                tmp_modkey.first = atoi(aFile.substr(10,2).c_str());  // XXXnnnnnn_??_mmm_sss.edb
                                tmp_modkey.second= atoi(aFile.substr(13,4).c_str());  // XXXnnnnnn_dd_???_sss.edb
                                if ( find( useModules.begin(), useModules.end(), tmp_modkey )==useModules.end() ){
                                    //std::cout << "#### add daq,mod="<< tmp_modkey.first << "," << tmp_modkey.second << std::endl;
                                    useModules.push_back( tmp_modkey );
                                }
                            }
                            isFoundFirstRun = true;
                        }else if (ind_t0b==(aFile.size()-4)){
                            std::pair<std::string,std::string> path_to_t0b_file;
                            path_to_t0b_file.first = (*it);
                            path_to_t0b_file.second= aFile;
                            existT0bFiles.push_back(path_to_t0b_file);
                        }else{
                        }
                    }
                }
            }
        }

        if (existEdbFiles.empty()){
            UtsusemiWarning(_MessageTag+"SetDataPath : There is no data file of "+runCode);
            continue;
        }

        // make std::map by needed modules for each run Number
        Map< bool > notFoundT0bKeyList;
        notFoundT0bKeyList.Clear();
        for (UInt4 i=0; i<useModules.size(); i++){
            char modkeyc[7];
            std::snprintf( modkeyc, sizeof(modkeyc), "%02d_%03d",useModules[i].first, useModules[i].second ); // make 00_123 as key
            std::string modkey(modkeyc);
            //std::cout << "##### modkey= "<< modkey << std::endl;
            std::vector< std::pair<std::string,std::string> > foundEdbFiles;
            for (UInt4 j=0; j<existEdbFiles.size(); j++){
                std::string::size_type ind_edb = existEdbFiles[j].second.find( modkey );
                if (ind_edb==10){  // <- find XXX123456_modkey_000.edb ?
                    bool isUnique = true;
                    for (UInt4 k=0; k<foundEdbFiles.size(); k++){
                        std::string::size_type ind_same_file = foundEdbFiles[k].second.find( existEdbFiles[j].second );
                        if (ind_same_file==0) isUnique = false;
                    }
                    if (isUnique){
                        foundEdbFiles.push_back( existEdbFiles[j] );
                        std::string addingPath( existEdbFiles[j].first );
                        _addPath( &addingPath, &(existEdbFiles[j].second) );
                        std::vector<std::string> key_files;
                        key_files.clear();
                        if (dataFileList.Check( modkey )!=0){
                            key_files = dataFileList.Put( modkey );
                            dataFileList.Remove( modkey );
                        }
                        key_files.push_back( addingPath );
                        sort( key_files.begin(), key_files.end() );
                        dataFileList.Add( modkey, key_files );
                    }
                }else{

                }
            }

            std::vector< std::pair<std::string,std::string> > foundT0bFiles;
            for (UInt4 j=0; j<existT0bFiles.size(); j++){
                std::string::size_type ind_t0b = existT0bFiles[j].second.find( modkey );
                if (ind_t0b==10){  // <- find XXX123456_modkey_000.t0b ?
                    bool isUnique = true;
                    for (UInt4 k=0; k<foundT0bFiles.size(); k++){
                        std::string::size_type ind_same_file = foundT0bFiles[k].second.find( existT0bFiles[j].second );
                        if (ind_same_file==0) isUnique = false;
                    }
                    if (isUnique){
                        foundT0bFiles.push_back( existT0bFiles[j] );
                        std::string addingPath( existT0bFiles[j].first );
                        _addPath( &addingPath, &(existT0bFiles[j].second) );
                        std::vector<std::string> key_files;
                        key_files.clear();
                        if (t0dataFileList.Check( modkey )!=0){
                            key_files = t0dataFileList.Put( modkey );
                            t0dataFileList.Remove( modkey );
                        }
                        key_files.push_back( addingPath );
                        sort( key_files.begin(), key_files.end() );
                        t0dataFileList.Add( modkey, key_files );
                    }
                }
            }
            if (t0dataFileList.Check( modkey )==0) notFoundT0bKeyList.Add( modkey, true );
        }

        // search not-found T0B files in given t0_path or $HOME/ana/xml
        if (notFoundT0bKeyList.Empty()){
        }else{
            for (UInt4 j=0; j<t0PathList.size(); j++){
                if (t0PathList[j]=="") continue;
                const boost::filesystem::path dir(t0PathList[j].c_str());
                if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                    BOOST_FOREACH( const boost::filesystem::path& dp,
                                   std::make_pair( boost::filesystem::directory_iterator(dir),
                                   boost::filesystem::directory_iterator())){
                        std::string aFile = dp.filename().string();
                        std::string::size_type ind_run = aFile.find( runCode );
                        if (ind_run!=std::string::npos){
                            std::string::size_type ind_t0b = aFile.find( ".t0b" );
                            if (ind_t0b!=std::string::npos){
                                if ((ind_run==0)&&(ind_t0b==20)){
                                    std::string key( aFile.substr(10,6) );
                                    if (notFoundT0bKeyList.Check( key )==1){
                                        std::vector<std::string> files;
                                        files.clear();
                                        if (t0dataFileList.Check( key )==1){
                                            files = t0dataFileList.Put( key );
                                            t0dataFileList.Remove( key );
                                        }
                                        std::string adding_path( t0PathList[j] );
                                        _addPath( &adding_path, &aFile );
                                        files.push_back( adding_path );
                                        t0dataFileList.Add( key, files );
                                        notFoundT0bKeyList.Remove( key );
                                    }
                                }
                            }
                        }
                    }
                }else{
                }
            }
        }

        // make not-found T0B files
        if (makeT0b){
            UInt4 num_of_unfound_t0b = notFoundT0bKeyList.PutTableSize();
            for (UInt4 j=0; j<num_of_unfound_t0b; j++){
                std::string key = notFoundT0bKeyList.PutKey(j);
                std::vector<std::string> edb_files;
                if (dataFileList.Check( key )==1)
                    edb_files = dataFileList.Put( key );
                if (edb_files.empty()){
                }else{
                    std::string dir_of_edb = edb_files[0].substr(0, (edb_files[0].size()-24));
                    const boost::filesystem::path dir(dir_of_edb.c_str());
                    if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                    }else{
                        UtsusemiError( _MessageTag+"SetDataPath2 : not found path="+dir_of_edb );
                        return;
                    }
                    sort( edb_files.begin(), edb_files.end() );
                    Int4 ret=_CaseDecoder->PutT0TreatTools()->readOrgEvent( edb_files );
                    if (ret>0){
                        std::string msg = _MessageTag+"SetDataPath2 : can not read using default T0TreatTools, file=\n";
                        for (UInt4 k=0; k<edb_files.size(); k++) msg+="      "+edb_files[k]+"\n";
                        UtsusemiWarning( msg );
                        //return;
                    }else{
                        t0PathList[1] = dir_of_edb;
                        //std::string savedT0b = "";
                        std::vector<std::string> savedT0bList;
                        for (UInt4 k=0; k<t0PathList.size(); k++){
                            if (t0PathList[k]!=""){
                                char t0_file_name_c[30];
                                std::snprintf( t0_file_name_c, sizeof(t0_file_name_c), "%s_%s_000.t0b", runCode.c_str(), key.c_str() );
                                std::string t0_file_name( t0_file_name_c );
                                std::string path_to_t0b( t0PathList[k] );
                                _addPath( &path_to_t0b, &t0_file_name );
                                Int4 ret = _CaseDecoder->PutT0TreatTools()->saveT0IndexEvent( path_to_t0b );
                                if (ret==0) {
                                    //savedT0b = path_to_t0b;
                                    savedT0bList.push_back(path_to_t0b);
                                    break;
                                }
                            }
                        }

                        if (savedT0bList.empty()){
                            UtsusemiWarning(_MessageTag+"SetDataPath2 : Fails to create .t0b files for key= "+key);

                        }else{
                            //std::vector<std::string> tmp_t0_file(1, savedT0b );
                            //t0dataFileList.Add( key, tmp_t0_file );
                            t0dataFileList.Add( key, savedT0bList );
                        }
                    }
                }
            }
        }

        // add list of edb  files for this run to _dataFileList
        for (UInt4 i=0;i<dataFileList.Size();i++){
            std::string key = dataFileList.PutKey(i);
            if (_dataFileList.Check( key )==0)
                _dataFileList.Add( key, dataFileList.Put( key ) );
            else{
                std::vector<std::string> files0 = _dataFileList.Put( key );
                std::vector<std::string> files1 = dataFileList.Put( key );
                for (UInt4 j=0; j<files1.size(); j++)
                    files0.push_back( files1[j] );
                _dataFileList.Remove( key );
                _dataFileList.Add( key, files0 );
            }
        }
        // add list of t0b files for this run to  _t0dataFileList
        for (UInt4 i=0;i<t0dataFileList.Size();i++){
            std::string key = t0dataFileList.PutKey(i);
            if (_t0dataFileList.Check( key )==0)
                _t0dataFileList.Add( key, t0dataFileList.Put( key ) );
            else{
                std::vector<std::string> files0 = _t0dataFileList.Put( key );
                std::vector<std::string> files1 = t0dataFileList.Put( key );
                for (UInt4 j=0; j<files1.size(); j++)
                    files0.push_back( files1[j] );
                _t0dataFileList.Remove( key );
                _t0dataFileList.Add( key, files0 );
            }
        }
        //[inamura 160623]-->
        // Pick up measuement period for each run
        if (t0dataFileList.Empty()){
            UtsusemiWarning( _MessageTag+"SetDataPath > t0dataFileList is empty." );
        }else{
            std::vector<std::string> tmp_files;
            for (UInt4 i=0;i<useModules.size();i++){
                char modkeyc[7];
                std::snprintf( modkeyc, sizeof(modkeyc), "%02d_%03d",useModules[0].first, useModules[0].second ); // make 00_123 as key
                std::string modkey(modkeyc);
                if (t0dataFileList.Check(modkey)==1){
                    tmp_files = t0dataFileList.Put(modkey);
                    break;
                }
            }
            if (tmp_files.empty()){
                UtsusemiWarning( _MessageTag+"SetDataPath > t0dataFileList(0) is empty." );
            }else{
                UInt4 ret = _CaseDecoder->PutT0TreatTools()->readT0IndexEvent( tmp_files );
                if (ret==0){
                    std::vector<double> a_period=_CaseDecoder->PutT0TreatTools()->putMeasPeriodFromT0();
                    if (!a_period.empty()){
                        for (UInt4 j=0; j<14; j++)
                            _MeasTimeList[i_run*14+j] = a_period[j];
                    }else{
                        std::string msg = _MessageTag+"SetDataPath > failed to get measurement period from T0Index ";
                        for (UInt4 i=0;i<tmp_files.size();i++) msg += (","+tmp_files[i]);
                        UtsusemiWarning( msg );
                    }
                }else{
                    std::string msg = _MessageTag+"SetDataPath > failed to read T0Index";
                    for (UInt4 i=0;i<tmp_files.size();i++) msg += (","+tmp_files[i]);
                    UtsusemiWarning( msg );
                }
            }
        }
        //<--[inamura 160623]
    }

    //_dataFileList.Dump();
    //_t0dataFileList.Dump();

    // Check whether data files are existed.
    UInt4 list_size = _dataFileList.PutTableSize();
    bool isEmpty = true;
    for (UInt4 i=0; i<list_size; i++){
        std::vector<std::string> files = _dataFileList.Put(i);
        if (files.empty()){
        }else{
            isEmpty = false;
            break;
        }
    }
    if (isEmpty){
        std::string msg = _MessageTag+"SetDataPath >> No data of given run(s) = ";
        for (UInt4 i=0; i<_runNumbers.size(); i++)
            msg+=_stools->UInt4ToString(_runNumbers[i])+",";
        UtsusemiError( msg );
        return;
    }

    _isReady=true;
    return;

}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetDataPathOld(std::string dataPath, std::string t0Path, std::vector<UInt4> runNumbers, bool isReset ){
    if (isReset){
    }else if ((_dataPathes.first==dataPath)&&(_dataPathes.second==t0Path)){
        if (_runNumbers.size()!=runNumbers.size()){
        }else{
            _isReady = true;
            for (UInt4 i=0; i<_runNumbers.size(); i++){
                if (_runNumbers[i]!=runNumbers[i]) {
                    _isReady=false;
                    break;
                }
            }
            if (_isReady) return;
        }
    }

    _isReady=false;
    // Make Event Data file name
    const boost::filesystem::path dpath(dataPath.c_str());
    if ((boost::filesystem::exists(dpath)) && (boost::filesystem::is_directory(dpath))){
    }else{
        std::cout << _MessageTag+"SetDataPath : not found dataPath= "+dataPath << std::endl;
        return;
    }
    if (t0Path!=""){
        const boost::filesystem::path t0path(t0Path.c_str());
        if ((boost::filesystem::exists(t0path)) && (boost::filesystem::is_directory(t0path))){
        }else{
            std::cout << _MessageTag+"SetDataPath : not found t0Path= "+t0Path << std::endl;
            return;
        }
    }

    //_instCode = _EventDecoder->_instCode;
    _runNumbers.clear();
    _runNumbers.resize( runNumbers.size() );
    for (UInt4 i=0; i<runNumbers.size(); i++)
        _runNumbers[i] = runNumbers[i];
    //_runNumber = runNo;

    // check whether instrument data path (/data/XXX) exists;
    // /data/XXX, /data/XXX00, /data/XXX01 ...
    std::vector<std::string> pathToDataInstVect(1,"");

    BOOST_FOREACH( const boost::filesystem::path& dp,
                   std::make_pair( boost::filesystem::directory_iterator( dpath ),
                   boost::filesystem::directory_iterator())){
        std::string tmp = dp.filename().string();
        std::string::size_type ind = tmp.find( _instCode );
        if (ind!=std::string::npos){
            std::string path_tmp(dataPath);
            _addPath( &path_tmp, &tmp );
            const boost::filesystem::path dir_tmp(path_tmp.c_str());
            if ((boost::filesystem::exists(dir_tmp)) && (boost::filesystem::is_directory(dir_tmp))){
            }else{
                continue;
            }
            if (tmp.size()==3){ // dir name = "XXX"
                pathToDataInstVect[0] = path_tmp;
            }else if (tmp.size()==5) {
                unsigned char t10 = (unsigned char)(*(tmp.substr(3,1).c_str()));
                unsigned char t01 = (unsigned char)(*(tmp.substr(4,1).c_str()));
                if ( (t10<'0')||(t10>'9')||(t01<'0')||(t01>'9') ){
                    continue;
                }else{
                    UInt4 n = ( (UInt4)(t10-'0') )*10 + (UInt4)(t01-'0') + 1;
                    if (n<pathToDataInstVect.size() ){
                        pathToDataInstVect[n] = path_tmp;
                    }else{
                        pathToDataInstVect.resize( n+1, "" );
                        pathToDataInstVect[n] = path_tmp;
                    }
                }
            }
        }
    }

    if ( (pathToDataInstVect.size()==1)&&(pathToDataInstVect[0]=="") ){
        std::cout << _MessageTag << "SetPathToData : There is no path(pathToDataInst) such as " << pathToDataInstVect[0] << std::endl;
        return;
    }


    _dataFileList.Clear();    // Map< std::vector<std::string> >
    _t0dataFileList.Clear();  // Map< std::vector<std::string> >
    // How to search t0b files
    // 1. same folder as edb ( both whether t0bPath is set or not )
    // 2. t0bPath

    Map< std::vector<std::string> > dataFileList;
    Map< std::vector<std::string> > t0dataFileList;

    for (UInt4 i_run=0; i_run<_runNumbers.size(); i_run++){
        _dataPathes.first=dataPath;
        _dataPathes.second=t0Path;
        _runNumber = _runNumbers[i_run];
        dataFileList.Clear();
        t0dataFileList.Clear();

        char runcodec[10];
        std::snprintf( runcodec, sizeof(runcodec),  "%3s%06d",_instCode.c_str(), _runNumber );
        std::string runCode( runcodec );

        std::string pathToRunData="";
        for (UInt4 i=0;i<pathToDataInstVect.size();i++){
            if (pathToDataInstVect[i]!=""){
                const boost::filesystem::path dir(pathToDataInstVect[i].c_str());
                if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                }else{
                    std::cout << _MessageTag << "SetPathToData : Cannot open path(pathToDataInst) such as " << pathToDataInstVect[i] << std::endl;
                    return;
                }

                BOOST_FOREACH( const boost::filesystem::path& dp,
                               std::make_pair( boost::filesystem::directory_iterator(dir),
                               boost::filesystem::directory_iterator())){
                    std::string tmp = dp.filename().string();
                    std::string::size_type ind = tmp.find( runCode );
                    if ((ind==0)&&(tmp.size()==18)){
                        std::string path_tmp(pathToDataInstVect[i]);
                        _addPath( &path_tmp, &tmp );
                        const boost::filesystem::path dir_tmp(path_tmp.c_str());
                        if ((boost::filesystem::exists(dir_tmp)) && (boost::filesystem::is_directory(dir_tmp))){
                        }else{
                            continue;
                        }
                        BOOST_FOREACH( const boost::filesystem::path& dp2,
                                       std::make_pair( boost::filesystem::directory_iterator(dir_tmp),
                                       boost::filesystem::directory_iterator())){
                            std::string tmp2 = dp2.filename().string();
                            if (tmp2.size()==24){
                                std::string::size_type ind_edb = tmp2.find( ".edb" );
                                std::string::size_type ind_t0b = tmp2.find( ".t0b" );

                                if (ind_edb==(tmp2.size()-4)){
                                    std::string path_tmp2( path_tmp );
                                    _addPath( &path_tmp2, &tmp2 );
                                    std::string key( tmp2.substr(10,6) );
                                    std::vector<std::string> files;
                                    if (dataFileList.Check( key )==0){
                                        files.clear();
                                    }else{
                                        files = dataFileList.Put( key );
                                        dataFileList.Remove( key );
                                    }
                                    bool isUniqueFile = true;
                                    for (UInt4 j=0; j<files.size(); j++){
                                        std::string::size_type ind_same_file = files[j].find( tmp2 );
                                        if (ind_same_file!=std::string::npos) isUniqueFile = false;
                                    }
                                    if (isUniqueFile){
                                        files.push_back( path_tmp2 );
                                        sort( files.begin(), files.end() );
                                    }
                                    dataFileList.Add( key, files );
                                }

                                if (ind_t0b==(tmp2.size()-4)) {
                                    std::string path_tmp2( path_tmp );
                                    _addPath( &path_tmp2, &tmp2 );
                                    std::string key( tmp2.substr(10,6) );
                                    std::vector<std::string> files;
                                    if (t0dataFileList.Check( key )==0){
                                        files.clear();
                                    }else{
                                        files = t0dataFileList.Put( key );
                                        t0dataFileList.Remove( key );
                                    }
                                    bool isUniqueFile = true;
                                    for (UInt4 j=0; j<files.size(); j++){
                                        std::string::size_type ind_same_file = files[j].find( tmp2 );
                                        if (ind_same_file!=std::string::npos) isUniqueFile = false;
                                    }
                                    if (isUniqueFile){
                                        files.push_back( path_tmp2 );
                                        sort( files.begin(), files.end() );
                                    }
                                    t0dataFileList.Add( key, files );
                                }
                            }
                        }
                    }
                }
            }
        }

        if (t0dataFileList.Empty()){
            // if t0Path is set, search t0b in t0Path
            if (t0Path!=""){
                const boost::filesystem::path dir(t0Path.c_str());
                if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                }else{
                    std::cout << _MessageTag << "SetPathToData : Cannot open path(pathToDataInst) such as " << t0Path << std::endl;
                    return;
                }
                BOOST_FOREACH( const boost::filesystem::path& dp,
                               std::make_pair( boost::filesystem::directory_iterator(dir),
                               boost::filesystem::directory_iterator())){
                    std::string tmp = dp.filename().string();
                    std::string::size_type ind_run = tmp.find( runCode );
                    std::string::size_type ind_t0b = tmp.find( ".t0b" );
                    if ((ind_run==0)&&(ind_t0b==20)){
                        std::string key( tmp.substr(10,6) );
                        if (dataFileList.Check( key )==1){
                            std::vector<std::string> files;
                            if (t0dataFileList.Check( key )==0){
                                files.clear();
                            }else{
                                files = t0dataFileList.Put( key );
                                t0dataFileList.Remove( key );
                            }

                            std::string path_tmp(t0Path);
                            _addPath( &path_tmp, &tmp );
                            files.push_back( path_tmp );
                            t0dataFileList.Add( key, files );
                        }
                    }
                }
            } // if (t0Path!="")

            // Still t0b file is not found
            if (t0dataFileList.Empty()){
                // try to search in UTSUSEMI_USR_PRIV_DIR+"/ana/tmp"
                std::string path_dir2 = FindTempFilePath();
                const boost::filesystem::path dir(path_dir2.c_str());
                if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                    BOOST_FOREACH( const boost::filesystem::path& dp,
                                   std::make_pair( boost::filesystem::directory_iterator(dir),
                                   boost::filesystem::directory_iterator())){
                        std::string tmp = dp.filename().string();
                        std::string::size_type ind_run = tmp.find( runCode );
                        std::string::size_type ind_t0b = tmp.find( ".t0b" );
                        if ((ind_run==0)&&(ind_t0b==20)){
                            std::string key( tmp.substr(10,6) );
                            if (dataFileList.Check( key )==1){
                                std::vector<std::string> files;
                                if (t0dataFileList.Check( key )==0){
                                    files.clear();
                                }else{
                                    files = t0dataFileList.Put( key );
                                    t0dataFileList.Remove( key );
                                }

                                std::string path_tmp(path_dir2);
                                _addPath( &path_tmp, &tmp );
                                files.push_back( path_tmp );
                                t0dataFileList.Add( key, files );
                            }
                        }
                    }
                }else{
                    std::cout << _MessageTag << "SetPathToData : failed to open "<< path_dir2 <<std::endl;
                    return;
                }
            }

            // Set _dataPathes.second ( path to t0b foldar )
            if (t0dataFileList.Empty()){
                std::cout << _MessageTag << "SetPathToData : There is no t0b file in the dir same as edb."<<std::endl;
                for (UInt4 i=0;i<dataFileList.Size();i++){
                    std::vector<std::string> files = dataFileList.Put(i);
                    if (files.empty()) {
                    }else{
                        _dataPathes.second = files[0].substr(0,(files[0].size()-24));
                    }
                }
            }else{
                for (UInt4 i=0;i<t0dataFileList.Size();i++){
                    std::vector<std::string> files = t0dataFileList.Put(i);
                    if (files.empty()) {
                    }else{
                        _dataPathes.second = files[0].substr(0,(files[0].size()-24));
                    }
                }
            }
            if (_dataPathes.second==""){
                std::cout << _MessageTag+"SetDataPath : No data of runNo= "+runCode << std::endl;
                return;
            }
        }// if (t0dataFileList.Empty())

        for (UInt4 i=0;i<dataFileList.Size();i++){
            std::string key = dataFileList.PutKey(i);
            if (t0dataFileList.Check( key )==0){
                std::vector<std::string> files = dataFileList.Put( key );

                const boost::filesystem::path dir(_dataPathes.second.c_str());
                if ((boost::filesystem::exists(dir)) && (boost::filesystem::is_directory(dir))){
                }else{
                    std::cout << _MessageTag+"SetDataPath : not found t0Path= "+_dataPathes.second << std::endl;
                    return;
                }

                sort( files.begin(), files.end() );
                UInt4 ret = _CaseDecoder->PutT0TreatTools()->readOrgEvent( files );
                if (ret>0){
                }else{
                    char t0_file_name[30];
                    std::snprintf( t0_file_name, sizeof(t0_file_name), "%s_%s_000.t0b", runCode.c_str(), key.c_str() );
                    std::string t0_file( t0_file_name );
                    std::string path_dir( _dataPathes.second );
                    _addPath( &path_dir, &t0_file );
                    ret = _CaseDecoder->PutT0TreatTools()->saveT0IndexEvent( path_dir );
                    if (ret>0){
                        std::string path_dir2 = FindTempFilePath();
                        if (path_dir2==""){
                            UtsusemiError(_MessageTag+"SetPathToData : Not Set Environment Variable such as UTSUSEMI_USR_DIR ");
                            return;
                        }
                        _addPath( &path_dir2, &t0_file );
                        ret = _CaseDecoder->PutT0TreatTools()->saveT0IndexEvent( path_dir2 );
                        if (ret==0) path_dir = path_dir2;
                    }
                    if (ret==0){
                        std::vector<std::string> tmp_t0_file(1, path_dir );
                        t0dataFileList.Add( key, tmp_t0_file );
                    }
                }
                if (ret>0){
                    std::cout << _MessageTag+"SetDataPath : Fails to create .t0b files for key= "+key << std::endl;
                }
            }
        }

        for (UInt4 i=0;i<dataFileList.Size();i++){
            std::string key = dataFileList.PutKey(i);
            if (_dataFileList.Check( key )==0)
                _dataFileList.Add( key, dataFileList.Put( key ) );
            else{
                std::vector<std::string> files0 = _dataFileList.Put( key );
                std::vector<std::string> files1 = dataFileList.Put( key );
                for (UInt4 j=0; j<files1.size(); j++)
                    files0.push_back( files1[j] );
                _dataFileList.Remove( key );
                _dataFileList.Add( key, files0 );
            }
        }
        for (UInt4 i=0;i<t0dataFileList.Size();i++){
            std::string key = t0dataFileList.PutKey(i);
            if (_t0dataFileList.Check( key )==0)
                _t0dataFileList.Add( key, t0dataFileList.Put( key ) );
            else{
                std::vector<std::string> files0 = _t0dataFileList.Put( key );
                std::vector<std::string> files1 = t0dataFileList.Put( key );
                for (UInt4 j=0; j<files1.size(); j++)
                    files0.push_back( files1[j] );
                _t0dataFileList.Remove( key );
                _t0dataFileList.Add( key, files0 );
            }
        }
    }
    //_dataFileList.Dump();
    //_t0dataFileList.Dump();

    _isReady=true;
    return;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
std::vector<std::string> UtsusemiEventDataConverterTemplate<T1,T2>::
PutDataFiles( UInt4 daqId, UInt4 modNo, bool isEdb ){
    std::vector<std::string> ret;
    char filenamerootc[30];
    std::snprintf( filenamerootc, sizeof(filenamerootc), "%02d_%03d", daqId, modNo );
    std::string fileNameRoot( filenamerootc );

    if (_dataFileList.Check( fileNameRoot )==0){
        return ret;
    }
    if (_t0dataFileList.Check( fileNameRoot )==0){
        return ret;
    }

    if (isEdb){
        return _dataFileList.Put( fileNameRoot );
    }else{
        return _t0dataFileList.Put( fileNameRoot );
    }

}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
std::vector<UInt8> UtsusemiEventDataConverterTemplate<T1,T2>::
PutFilesSize( std::vector<std::string> files ){
    std::vector<UInt8> ret( files.size(), 0 );
    for (UInt4 i=0; i<files.size(); i++){
        const boost::filesystem::path file_path( files[i].c_str() );
        const boost::uintmax_t size = boost::filesystem::file_size(file_path);
        ret[i] = size;
    }
    return ret;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
ReadEventData( UInt4 daqId, UInt4 modNo ){
    _isReady=false;
    if (_dataFileList.Empty()){
        UtsusemiError( _MessageTag+"ReadEventData >> dataFilelist is empty" );
        return;
    }

    char filenamerootc[30];
    //std::snprintf( filenamerootc, sizeof(filenamerootc), "%3s%06d_%02d_%03d", _instCode.c_str(), _runNumber, daqId, modNo );
    std::snprintf( filenamerootc, sizeof(filenamerootc), "%02d_%03d", daqId, modNo );
    std::string fileNameRoot( filenamerootc );

    if (_dataFileList.Check( fileNameRoot )==0){
        UtsusemiError(_MessageTag+"ReadEventData >> dataFileList has no such module:"+fileNameRoot);
        return;
    }
    if (_t0dataFileList.Check( fileNameRoot )==0){
        UtsusemiError( _MessageTag+"ReadEventData >> t0dataFileList has no such module:"+fileNameRoot);
        return;
    }

    std::vector<std::string> edb_files = _dataFileList.Put( fileNameRoot );
    std::vector<std::string> t0b_files = _t0dataFileList.Put( fileNameRoot );
    sort( edb_files.begin(), edb_files.end() );
    sort( t0b_files.begin(), t0b_files.end() );
    bool isEmptyFile = false;
    for (UInt4 i=0;i<edb_files.size();i++){
        // Check file size
        std::ifstream edbf(edb_files[i], std::ifstream::ate);
        size_t fsize = static_cast<size_t>(edbf.tellg());
        if (fsize == 0){
            isEmptyFile = true;
            UtsusemiError(_MessageTag+"ReadEventData : "+edb_files[i] + " is Empty.");
        }else{
            UtsusemiMessage(_MessageTag+"ReadEventData : "+edb_files[i]);
        }
        edbf.seekg(0, std::ifstream::beg);
    }
    for (UInt4 i=0;i<t0b_files.size();i++) UtsusemiMessage( _MessageTag+"ReadEventData : "+t0b_files[i]);

    Int4 ret = _CaseDecoder->ReadT0IndexEventFile( t0b_files, _numOfAdditionalClocks );
    if (ret<0){
        UtsusemiError( _MessageTag+"ReadEventData >> fails to read T0Index" );
        return;
    }
    _CaseDecoder->CheckCaseTableWithT0Index();

    std::vector<UInt8> T0Table = _CaseDecoder->PutT0Index();
    std::vector<Double> ClockTable = _CaseDecoder->PutT0ClockDiff();
    std::vector< std::vector<UInt4>* >* CaseTable = _CaseDecoder->PutCaseTable();

    if (T0Table.empty()){
        UtsusemiError( _MessageTag+"ReadEventData >> T0EventData may be empty.");
        return;
    }

    Int4 num_of_preClocks = (Int4)(ClockTable.size()-T0Table.size());
    if (num_of_preClocks<0){
        std::string msg = "Exception:"+_MessageTag+"Invalid size between T0Table and ClockTable";
        UtsusemiError( msg );
        throw msg;
    }

    bool isUseCases = false;

    if (CaseTable==NULL){
    } else if ( T0Table.size()<=(CaseTable->size()+1) ){ //[inamura 170313]
        isUseCases = true;
    } else{
        std::string msg = _MessageTag+" T0 sizes are different between Neutron Event and CaseTable [ ";
        msg += _stools->UInt4ToString((UInt4)(T0Table.size())) + ", " + _stools->UInt4ToString((UInt4)(CaseTable->size())) + " ]";
        UtsusemiWarning( msg );
    }

    // EventData Files size
    std::vector<UInt8> edb_files_size = PutFilesSize( edb_files );

    // Open EventData Files
    std::vector<FILE*> fp_list( edb_files.size() );
    for (UInt4 i=0;i<edb_files.size();i++){
        if ( (fp_list[i]=fopen( edb_files[i].c_str(), "rb" ))==NULL ){
            UtsusemiError( _MessageTag+"ReadEventData >> fails to open event data file :"+edb_files[i]);
            for (UInt4 j=0;j<i;j++) fclose( fp_list[j] );
            return;
        }
    }

    UInt4 ind=0; // Index of EventData Files

    // The block of event-data before first T0-data should be removed.
    UInt8 ReadingNumOfEvents = T0Table[0];
    while( true ){
        if ( edb_files_size[ind]<( ReadingNumOfEvents*_eventSize ) ){
            ReadingNumOfEvents -= (UInt4)(edb_files_size[ind]/_eventSize);
            ind++;
        }else{
            if (fseek( fp_list[ind], (long)(ReadingNumOfEvents)*_eventSize, SEEK_SET )==0) break;
            else ind=(UInt4)(fp_list.size());
        }

        if (ind>(fp_list.size()-1)){
            UtsusemiError( _MessageTag+"ReadEventData >>  Cannot read enough event data from files");
            return;
        }
    }

    UInt8 current_posi = ReadingNumOfEvents*_eventSize; // current position in a file

    size_t ii;
    //UInt4 ReadingStep = 1500;
    // To keep the buffer size of ReadingEvent around 10-100MB
    Double alpha = (Double)(T0Table.back()-T0Table[0])/(Double)(T0Table.size())/10000.0;
    if (UtsusemiEnvGetIgnoreEmptyFile()) alpha = 1.0;
    if ((alpha == 0.0) && (!isEmptyFile)) alpha = 1.0;
    Double beta = 1500.0/alpha;
    if (beta<1.0) beta = 1.0;
    UInt4 ReadingStep = (UInt4)beta;
    //UtsusemiMessage(_MessageTag+"ReadingStep of events is "+_stools->UInt4ToString(ReadingStep)+" .");

    UInt4 ReadingTimes = ((UInt4)(T0Table.size())-1) / ReadingStep;
    UInt4 StepRemainder = (T0Table.size()-1) % ReadingStep;

    if( StepRemainder==0 ){
        StepRemainder = ReadingStep;
        ReadingTimes = ReadingTimes -1;
    }

    std::vector<UInt8> NewT0( ReadingStep+1, 0 );
    std::vector<Double> NewIC( ReadingStep+1+num_of_preClocks, 0.0 );
    std::vector< std::vector<UInt4>* > NewCase( ReadingStep+1, NULL);
    if (!isUseCases) NewCase.clear();

    std::vector<UInt4> ReadingPointer( ReadingTimes+2 );
    for (UInt4 k=0; k<(ReadingTimes+1); k++) ReadingPointer[k] = k*ReadingStep;
    ReadingPointer[ ReadingTimes+1 ] = ReadingTimes*ReadingStep + StepRemainder;

    bool isFinal = false;
    for (UInt4 k=0; k<(ReadingPointer.size()-1); k++){
        ReadingNumOfEvents = T0Table[ReadingPointer[k+1]] - T0Table[ReadingPointer[k]];
        UChar *Dat = new UChar [ ReadingNumOfEvents * _eventSize ];
        UInt4 start_ind = ind;
        std::vector<UInt8> read_events;
        UInt8 next_posi = (current_posi+(ReadingNumOfEvents*(_eventSize)));
        if (next_posi <= edb_files_size[ind]){
            read_events.push_back( ReadingNumOfEvents );
        }else{
            bool isSafe = true;
            while( next_posi > edb_files_size[ind] ){
                if (ind==(fp_list.size()-1)){
                    UtsusemiWarning( _MessageTag+"ReadEventData >> WARNING : next_posi is larger than the file size : something wrong.");
                    UtsusemiWarning( _MessageTag+"ReadEventData >> WARNING : k="+_stools->UInt4ToString(k)+", T0Table.size()="+_stools->UInt4ToString( (UInt4)(T0Table.size())) );
                    std::string msg = _MessageTag+"ReadEventData >> WARNING : ReadingPointer[k]=";
                    msg += _stools->UInt4ToString(ReadingPointer[k]);
                    msg += ", ReadingPointer[k+1]="+_stools->UInt4ToString(ReadingPointer[k+1]);
                    UtsusemiWarning( msg );
                    read_events.push_back( (edb_files_size[ind]-current_posi)/(_eventSize) ); //[inamura 161116]
                    isSafe = false;
                    break;
                }else{
                    next_posi = next_posi - edb_files_size[ind];
                    read_events.push_back( (edb_files_size[ind]-current_posi)/(_eventSize) );
                    // continue to a next file
                    std::string msg = _MessageTag+"ReadEventData >> Finish reading of "+edb_files[ind];
                    msg +=" ("+_stools->UInt4ToString(ind+1)+"/"+_stools->UInt4ToString( (UInt4)(edb_files.size()) )+")";
                    UtsusemiMessage( msg );
                    ind++;
                    current_posi =0;
                }
            }
            if (isSafe)
                read_events.push_back( next_posi/(_eventSize) );
        }

        UInt4 counter = 0;
        for (UInt4 i=0; i<(UInt4)(read_events.size()); i++){
            UChar *Dat_tmp = new UChar [ read_events[i]*(_eventSize) ];
            ii = fread( Dat_tmp, _eventSize, read_events[i], fp_list[ start_ind+i ] );
            for (UInt4 l=0;l<(ii*(_eventSize));l++) Dat[counter+l]=Dat_tmp[l];
            if (ii==read_events[i]){
                counter += (UInt4)ii*(_eventSize);
                if (i==0)
                    current_posi += ii*(_eventSize);
                else
                    current_posi = ii*(_eventSize);
                for (UInt4 l=counter; l<(ReadingNumOfEvents*_eventSize);l++) Dat[l]=0x00; //[inamura 161121]
            }else{
                std::string msg = _MessageTag+"ReadEventData >> WARNING : (Read left part) read_events[i]!=ii:";
                msg += (_stools->UInt4ToString((UInt4)read_events[i]) + "," + _stools->UInt4ToString((UInt4)ii));
                UtsusemiWarning( msg );
                msg  = _MessageTag+"ReadEventData >> WARNING : start_ind="+_stools->UInt4ToString(start_ind);
                msg = "i="+_stools->UInt4ToString(i)+",file="+edb_files[i+start_ind];
                UtsusemiWarning( msg );
                for (UInt4 l=(counter+(UInt4)ii);l<(ReadingNumOfEvents*_eventSize);l++) Dat[l]=0x00;
                isFinal = true;
            }
            delete [] Dat_tmp;
            if (isFinal) break;
        }

        if (k==(ReadingPointer.size()-2)){
            NewT0.clear();
            NewIC.clear();
            NewT0.resize( StepRemainder+1,0 );
            NewIC.resize( StepRemainder+num_of_preClocks+1,0.0 );
            if (isUseCases){
                NewCase.clear();
                NewCase.resize( StepRemainder+1,NULL );
            }
        }

        for( UInt4 i=0;i<(UInt4)num_of_preClocks;i++) NewIC[i] = ClockTable[ReadingPointer[k]+i];
        for( UInt4 i=ReadingPointer[k]; i<ReadingPointer[k+1]; i++ ){ //[inamura 170313]
            NewT0[i-ReadingPointer[k]]                     = T0Table[i]-T0Table[ ReadingPointer[k] ] ;
            NewIC[i-ReadingPointer[k]+num_of_preClocks]    = ClockTable[i+num_of_preClocks];
            if (isUseCases) NewCase[i-ReadingPointer[k]] = CaseTable->at(i);
        }
        NewT0[ReadingPointer[k+1]-ReadingPointer[k]] = T0Table[ReadingPointer[k+1]]-T0Table[ReadingPointer[k]];//[inamura 170313]

        PreIncrement( daqId, modNo, Dat, NewT0, NewIC, &NewCase );

        delete [] Dat;
        if (isFinal) break;
    }

    if (edb_files.size()>1){
        std::string msg = _MessageTag+"ReadEventData >> Finish reading of "+edb_files[ind];
        msg +=" ("+_stools->UInt4ToString( (UInt4)(edb_files.size()) )+"/"+_stools->UInt4ToString( (UInt4)(edb_files.size()) )+")";
        UtsusemiMessage( msg );
    }

    std::vector<FILE*>::iterator it = fp_list.begin();
    while(it!=fp_list.end()){
        fclose( *it );
        it++;
    }

    _isReady=true;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
UInt4 UtsusemiEventDataConverterTemplate<T1,T2>::
PutHistId( UInt4 PixelId, UInt4 CaseId ){
    return _numOfInnerPixels*(CaseId-1) + _EventDecoder->ConvertPixelIdToInnerId( PixelId );
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
std::vector<Double> UtsusemiEventDataConverterTemplate<T1,T2>::
PutHist( UInt4 PixelId, UInt4 CaseId ){
    if (CaseId<1) {
        std::vector<Double> ret;
        return ret;
    }
    //[inamura 160809]-->
    //return _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogram();
    //std::cout << "UtsusemiEventDataConverterTemplate::PutHist PixelId = "<<PutHistId(PixelId,CaseId)<<std::endl;
    std::vector<Double>* bg_range = _EventDecoder->PutTimeDependBackGroundInfo( PixelId );
    if ((bg_range==NULL)&&(!_isLoadedTimeDependBackGroundList)){
        return _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogram();
    }
    if ((bg_range!=NULL)&&(bg_range->at(1)==bg_range->at(2))){
        return _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogram();
    }

    std::vector<Double> hist_org = _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogram();
    std::vector<Double> tof_vec = _gslHist->at( PutHistId(PixelId,CaseId) )->PutBin();
    std::vector<Double> ret;
    //std::cout << "UtsusemiEventDataConverterTemplate::PutHist TimeDependBackGround "<<PutHistId(PixelId,CaseId)<<std::endl;
    UInt4 ThNum = 1;
#ifdef MULTH
    ThNum = omp_get_thread_num();
#endif

    if (_isLoadedTimeDependBackGroundList) {
        if ( TimeDependBackGroundCorrectionByList(true, &tof_vec, &hist_org, PixelId, ThNum, &ret, CaseId ) ){
            return ret;
        }else{
            return hist_org;
        }
    }

    _timeDependBackGroundList->at(ThNum)->at(PixelId) = TimeDependBackGroundCorrection( true, &tof_vec, &hist_org, bg_range, &ret );

    return ret;
    //<--[inamura 160809]
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
std::vector<Double> UtsusemiEventDataConverterTemplate<T1,T2>::
PutErr( UInt4 PixelId, UInt4 CaseId ){
    //return _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogramErr();
    std::vector<Double> hist_bin = _gslHist->at( PutHistId(PixelId,CaseId) )->PutBin();
    std::vector<Double> hist_err = _gslHist->at( PutHistId(PixelId,CaseId) )->PutHistogramErr();

    _EventDecoder->SetMaskOnError( PixelId, hist_bin, hist_err );

    /*
    if (_tofMaskRegion.empty()){
    }else{
        for (UInt4 i=0; i<hist_err.size(); i++){
            Double bin1 = hist_bin[i];
            Double bin2 = hist_bin[i+1];
            bool isMask = false;
            for (UInt4 j=0; j<_tofMaskRegion.size(); j++){
                if ( ( ( bin1>=(_tofMaskRegion[j].first) )&&( bin2<=(_tofMaskRegion[j].second) ) )
                     ||( ( bin1<=(_tofMaskRegion[j].first) )&&( (_tofMaskRegion[j].first)<=bin2 ) )
                     ||( ( bin1<=(_tofMaskRegion[j].second) )&&( (_tofMaskRegion[j].second)<=bin2 ) ) ){
                    isMask = true;
                    break;
                }
            }
            if (isMask) {
                if (hist_err[i]==0.0) hist_err[i] = 1e-30;
                hist_err[i] = -1.0*hist_err[i];
            }
        }
    }
    */
    //[inamura 160809]-->
    //return hist_err;
    std::vector<Double>* bg_range = _EventDecoder->PutTimeDependBackGroundInfo( PixelId );
    if ((bg_range==NULL)&&(!_isLoadedTimeDependBackGroundList)) return hist_err;
    if ((bg_range!=NULL)&&(bg_range->at(1)==bg_range->at(2))) return hist_err;

    std::vector<Double> tof_vec = _gslHist->at( PutHistId(PixelId,CaseId) )->PutBin();
    std::vector<Double> ret;
    UInt4 ThNum = 1;
#ifdef MULTH
    ThNum = omp_get_thread_num();
#endif

    if (_isLoadedTimeDependBackGroundList) {
        if ( TimeDependBackGroundCorrectionByList(false, &tof_vec, &hist_err, PixelId, ThNum, &ret, CaseId ) ){
            return ret;
        }else{
            return hist_err;
        }
    }
    TimeDependBackGroundCorrection( false, &tof_vec, &hist_err, bg_range, &ret );
    return ret;
    //<--[inamura 160809]

}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
InitTimeDependBackGroundList(){
    ClearTimeDependBackGroundList();
    std::vector<UInt4> outerPixelIdList = _EventDecoder->PutPixelIdList(true);
    _timeDependBackGroundList = new std::vector< std::vector<Double>* >( _NumOfMulTh, NULL );
    for (UInt4 i=0; i<_NumOfMulTh; i++)
        _timeDependBackGroundList->at(i) = new std::vector<Double>( outerPixelIdList.size(), 0.0 );
}
//[inamura 160809]-->
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
Double UtsusemiEventDataConverterTemplate<T1,T2>::
    TimeDependBackGroundCorrection( bool isIntensity, std::vector<Double>* tof_vec, std::vector<Double>* hist_vec, std::vector<Double>* bg_info, std::vector<Double>* ret ){
    UInt4 ptn = (UInt4)(bg_info->at(0)+0.1);
    Double tof0 = bg_info->at(1);
    Double tof1 = bg_info->at(2);

    Double sum_tof=0.0;
    Double sum_int=0.0;
    for (UInt4 i=0; i<(hist_vec->size()); i++){
        Double tof = tof_vec->at(i);
        if ((tof>=tof0)&&(tof<tof1)){
            sum_tof += ( (tof_vec->at(i+1))-tof );
            if (isIntensity)
                sum_int += ( hist_vec->at(i) );
            else
                sum_int += ( hist_vec->at(i) )*( hist_vec->at(i) );
        }
    }
    Double bg_per_unit = sum_int/sum_tof;
    std::vector<Double> bg_vec( hist_vec->size(), 0.0 );
    for (UInt4 i=0; i<(hist_vec->size()); i++)
        bg_vec[i] = bg_per_unit * ( (tof_vec->at(i+1))-(tof_vec->at(i)) );


    std::vector<Double> bg_vec2;
    //std::cout << "tof0, tof1="<<tof0<<","<<tof1<<std::endl;
    //std::cout << "tof_vec->front(), tof_vec->back()="<<tof_vec->front()<<","<< tof_vec->back()<<std::endl;
    if (ptn==1){ // tof0<tof1<tof_vec[0]<... : Pattern = 1
        ret->resize( hist_vec->size()-2 );
        bg_vec2.resize( hist_vec->size()-2 );
        copy( hist_vec->begin()+2, hist_vec->end(), ret->begin() );
        copy( bg_vec.begin()+2, bg_vec.end(), bg_vec2.begin() );
    }else if (ptn==2){// tof_vec[last]<tof0<tof1 : pattern = 2
        ret->resize( hist_vec->size()-2 );
        bg_vec2.resize( hist_vec->size()-2 );
        copy( hist_vec->begin(), hist_vec->end()-2, ret->begin() );
        copy( bg_vec.begin(), bg_vec.end()-2, bg_vec2.begin() );
    }else if (ptn==3){// tof0<tof_vec.front()<=tof1 : pattern = 3
        ret->resize( hist_vec->size()-1 );
        bg_vec2.resize( hist_vec->size()-1 );
        copy( hist_vec->begin()+1, hist_vec->end(), ret->begin() );
        copy( bg_vec.begin()+1, bg_vec.end(), bg_vec2.begin() );
    }else if (ptn==4){// tof0<=tof_vec[last]<tof1 : pattern = 4
        ret->resize( hist_vec->size()-1 );
        bg_vec2.resize( hist_vec->size()-1 );
        copy( hist_vec->begin(), hist_vec->end()-1, ret->begin() );
        copy( bg_vec.begin(), bg_vec.end()-1, bg_vec2.begin() );
    }else if (ptn==5){// tof_vec[first]<tof0<tof1<tof_vec[last] : pattern = 5
        ret->resize( hist_vec->size() );
        bg_vec2.resize( bg_vec.size() );
        copy( hist_vec->begin(), hist_vec->end(), ret->begin() );
        copy( bg_vec.begin(), bg_vec.end(), bg_vec2.begin() );
    }else{
        ret->resize( hist_vec->size() );
        bg_vec2.resize( bg_vec.size() );
        copy( hist_vec->begin(), hist_vec->end(), ret->begin() );
        copy( bg_vec.begin(), bg_vec.end(), bg_vec2.begin() );
        UtsusemiError( _MessageTag+"TimeDependBackGroundCorrection > Substruction is failed. " );
    }

    if (isIntensity)
        for (UInt4 i=0; i<(ret->size()); i++)
            ret->at(i) = (ret->at(i))-bg_vec2[i];
    else{
        for (UInt4 i=0; i<(ret->size()); i++){
            double err = (ret->at(i))*(ret->at(i)) - bg_vec2[i];
            if (err<0.0)
                ret->at(i) = sqrt( -1.0*err );
            else
                ret->at(i) = sqrt( err  ); // new E = sqrt(I-Ibk)
        }
    }

    return bg_per_unit;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
bool UtsusemiEventDataConverterTemplate<T1,T2>::
TimeDependBackGroundCorrectionByList( bool isIntensity, std::vector<Double>* tof_vec, std::vector<Double>* hist_vec, UInt4 pixelId, UInt4 multh, std::vector<Double>* ret, UInt4 caseId ){
    if (_timeDependBackGroundList->at(0)->size()<=pixelId){
        UtsusemiError(_MessageTag+"TimeDependBackGroundCorrectionByList >> TimeDependBackGroundList is invalid." );
        return false;
    }
    Double bg = _timeDependBackGroundList->at(multh)->at(pixelId);

    Int4 num_of_t0 = 0;
    if (_numOfT0List.size()==1) num_of_t0 = _numOfT0List[0];
    else num_of_t0 = _numOfT0List[ caseId ];
    bg = bg/_timeDependBackGroundNormalizeFactor*(Double)num_of_t0;

    ret->resize( hist_vec->size(), 0.0);
    if (isIntensity)
        for (UInt4 i=0; i<(ret->size()); i++)
            ret->at(i) = (hist_vec->at(i)) - (bg * ( (tof_vec->at(i+1))-(tof_vec->at(i)) ));
    else{
        for (UInt4 i=0; i<(ret->size()); i++){
            double err = (hist_vec->at(i))*(hist_vec->at(i)) - (bg * ( (tof_vec->at(i+1))-(tof_vec->at(i)) ));
            if (err<0.0)
                ret->at(i) = sqrt( -1.0*err );
            else
                ret->at(i) = sqrt( err  ); // new E = sqrt(I-Ibk)
        }
    }
    return true;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
bool UtsusemiEventDataConverterTemplate<T1,T2>::
SaveTimeDependBackGroundListToFile( std::string filePath, UInt4 caseId ){
    Int4 num_of_t0 = 0;
    if (_numOfT0List.size()==1) num_of_t0 = _numOfT0List[0];
    else num_of_t0 = _numOfT0List[ caseId ];

    std::string ext_code = filePath.substr( filePath.size()-4, 4 );
    UtsusemiMessage( _MessageTag+"SaveTimeDependBackGroundListToFile >> saving background to "+filePath );
    if (ext_code==".xml"){
        UtsusemiMessage( _MessageTag+"SaveTimeDependBackGroundListToFile >> Making background info " );
        BoostXmlParser BX;
        BX.SetQuiet( !(UtsusemiEnvGetDebugMode()) );
        BX.CreateNewTree();
        BX.AddElement("/timeDependBackGroundList/normFactor,unit=kickers",_stools->Int4ToString(num_of_t0) );
        for (UInt4 pix=0; pix<_timeDependBackGroundList->at(0)->size(); pix++){
            Double bk_sum = 0.0;
            for (UInt4 i=0; i<_NumOfMulTh; i++)
                bk_sum += _timeDependBackGroundList->at(i)->at(pix);
            std::string bkg_s = _stools->DoubleToString( bk_sum );
            std::string pix_s = _stools->UInt4ToString(pix);
            BX.AddElement( "/timeDependBackGroundList/backGoundIntensity,pixelId="+pix_s, bkg_s );
        }

        if (!BX.Save(filePath)){
            UtsusemiError( _MessageTag+"SaveTimeDependBackGroundListToFile >> could not save file as "+filePath );
            return false;
        }
    }else if (ext_code==".txt"){
        std::ofstream outf( filePath.c_str() );
        if (!outf){
            UtsusemiError(_MessageTag+"SaveTimeDependBackGroundListToFile >> could not save file as "+filePath);
            return false;
        }

        Double tof1 = 0.0;
        Double tof2 = 0.0;
        for (UInt4 pix=0; pix<_timeDependBackGroundList->at(0)->size(); pix++){
            std::vector<Double>* bg_range = _EventDecoder->PutTimeDependBackGroundInfo( pix );
            if (bg_range!=NULL){
                tof1 = bg_range->at(1);
                tof2 = bg_range->at(2);
                break;
            }
        }

        outf << "# RunNo = ";
        for (UInt4 i=0; i<_runNumbers.size(); i++) outf << _runNumbers[i] << ",";
        outf << std::endl;
        outf << "# normFactor ="<<num_of_t0<<",unit=kickers" << std::endl;
        outf << "# TOF range ="<<tof1<<"-"<<tof2<<std::endl;
        outf << "# pixelId, background intensity [/micro-sec]"<< std::endl;
        for (UInt4 pix=0; pix<_timeDependBackGroundList->at(0)->size(); pix++){
            Double bk_sum = 0.0;
            for (UInt4 i=0; i<_NumOfMulTh; i++)
                bk_sum += _timeDependBackGroundList->at(i)->at(pix);
            outf << pix << ", ";
            outf << std::scientific << std::setprecision(9) <<bk_sum << std::endl;
        }
        outf.close();
    }else{
        UtsusemiError(_MessageTag+"SaveTimeDependBackGroundListToFile >> could not save file as "+filePath);
        return false;
    }
    UtsusemiMessage( _MessageTag+"SaveTimeDependBackGroundListToFile >> succeeded. " );
    return true;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
bool UtsusemiEventDataConverterTemplate<T1,T2>::
ReadTimeDependBackGroundListFromFile( std::string filePath ){
    UtsusemiMessage( _MessageTag+"LoadTimeDependBackGroundListFromFile >> reading background from "+filePath );
    InitTimeDependBackGroundList();
    std::string ext_code = filePath.substr( filePath.size()-4, 4 );
    if (ext_code==".xml"){
        BoostXmlParser BX;
        BX.SetQuiet( !(UtsusemiEnvGetDebugMode()) );
        if (!(BX.Load(filePath))){
            UtsusemiError( _MessageTag+"LoadTimeDependBackGroundListFromFile >> not found "+filePath );
            return false;
        }
        _timeDependBackGroundNormalizeFactor = _stools->StringToDouble( BX.PutContent( "/timeDependBackGroundList/normFactor,unit=kickers","" ) );
        std::vector<std::string> pix_s_list = BX.PutAttValList( "/timeDependBackGroundList/backGoundIntensity","pixelId" );
        for (UInt4 i=0; i<pix_s_list.size(); i++){
            UInt4 pixelId = _stools->StringToUInt4( pix_s_list[i] );
            if (_timeDependBackGroundList->at(0)->size()<=pixelId) _timeDependBackGroundList->at(0)->resize( pixelId+1 );
            std::string path = "/timeDependBackGroundList/backGoundIntensity,pixelId="+pix_s_list[i];
            _timeDependBackGroundList->at(0)->at( pixelId ) = _stools->StringToDouble( BX.PutContent(path) );
        }
    }else if (ext_code==".txt"){
        std::ifstream inpf(filePath.c_str());
        if (!inpf){
            UtsusemiError( _MessageTag+"LoadTimeDependBackGroundListFromFile >> not found "+filePath );
            return false;
        }
        std::string tmp;
        getline(inpf, tmp);
        while(!inpf.eof()){
            if (tmp.find("#")==0){
                std::string::size_type ind = tmp.find("normFactor");
                if (ind!=std::string::npos){
                    std::string::size_type ind2 = tmp.find(",");
                    if (ind2==std::string::npos) ind2 = tmp.size()-1;
                    std::string tmp2 = tmp.substr(ind+10,ind2-ind-10);
                    //std::cout << "# [inamura 190416] normFactor tmp2 = "+tmp2<<std::endl;
                    std::string::size_type ind3 = tmp2.find("=");
                    if (ind3==std::string::npos) ind3 = 0;
                    std::string tmp3 = tmp2.substr(ind3+1,tmp2.size()-1);
                    //std::cout << "# [inamura 190416] normFactor tmp3 = "+tmp3<<std::endl;
                    _timeDependBackGroundNormalizeFactor = _stools->StringToDouble(tmp3);
                    std::cout << "# [inamura 190416] normFactor = "<<_timeDependBackGroundNormalizeFactor<<std::endl;
                }
            }else{
                std::string::size_type ind1 = tmp.find(",");
                std::string::size_type ind2 = tmp.size()-1;
                UInt4 pix = _stools->StringToUInt4( tmp.substr(0,ind1) );
                Double val = _stools->StringToDouble( tmp.substr(ind1+1,ind2-ind1) );
                if (pix<_timeDependBackGroundList->at(0)->size())
                    _timeDependBackGroundList->at(0)->at( pix ) = val;
            }
            getline(inpf, tmp);
        }
        inpf.close();
    }else{
        UtsusemiError( _MessageTag+"LoadTimeDependBackGroundListFromFile >> not found "+filePath );
        return false;
    }
    _isLoadedTimeDependBackGroundList=true;
    UtsusemiMessage( _MessageTag+"LoadTimeDependBackGroundListFromFile >> succeeded. " );
    return true;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
ClearTimeDependBackGroundList(){
    if (_timeDependBackGroundList!=NULL){
        for (UInt4 i=0; i<_timeDependBackGroundList->size(); i++)
            if (_timeDependBackGroundList->at(i)!=NULL) delete _timeDependBackGroundList->at(i);
        delete _timeDependBackGroundList;
    }
    _timeDependBackGroundList=NULL;
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
ResetHistogram(){
    if (_gslHist!=NULL)
        for (UInt4 i=0;i<_gslHist->size();i++) _gslHist->at(i)->Reset();
    _isUnReadDetId.clear();
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
void UtsusemiEventDataConverterTemplate<T1,T2>::
SetElementContainer( UInt4 outerPixelId, ElementContainer *ec, UInt4 caseId ){
    if (caseId<1){
        UtsusemiWarning(_MessageTag +"SetElementContainer >> CaseId must be more than 1." );
        return;
    }
    UInt4 innerId = PutHistId( outerPixelId, caseId );
    Int4 tof_bin_type = _EventDecoder->PutTofBinType( outerPixelId );
    std::pair< std::string,std::string > xlabel( UTSUSEMI_KEY_UNKNOWN,UTSUSEMI_KEY_UNKNOWN );
    std::pair< std::string,std::string > ylabel( UTSUSEMI_KEY_INTENSITY,UTSUSEMI_KEY_COUNTS_UNIT );
    std::pair< std::string,std::string > elabel( UTSUSEMI_KEY_ERROR,UTSUSEMI_KEY_COUNTS_UNIT );

    //if (!(_EventDecoder->_LabelsOfEC[tof_bin_type].empty())){
        //xlabel = _EventDecoder->_LabelsOfEC[tof_bin_type][0];
        //ylabel = _EventDecoder->_LabelsOfEC[tof_bin_type][1];
        //elabel = _EventDecoder->_LabelsOfEC[tof_bin_type][2];
        //}
    xlabel = _EventDecoder->PutXLabel( tof_bin_type );
    ylabel = _EventDecoder->PutYLabel( tof_bin_type );
    elabel = _EventDecoder->PutELabel( tof_bin_type );

    if (tof_bin_type<0){
        UtsusemiError( _MessageTag+"There is no information of tof_bin_type.[tof_bin_type<0]" );
    }else if (_EventDecoder->isValidConvType( tof_bin_type )){
        if (_runNumber>0){
            if (_EventDecoder->isReverseAxis( tof_bin_type )){
                std::vector<Double> xxv = _EventDecoder->PutXaxis();
                std::vector<Double> yyv = PutHist( outerPixelId, caseId );
                std::vector<Double> eev = PutErr( outerPixelId, caseId );
                reverse( xxv.begin(),xxv.end() );
                reverse( yyv.begin(),yyv.end() );
                reverse( eev.begin(),eev.end() );
                ec->Add(xlabel.first,xxv,xlabel.second);
                ec->Add(ylabel.first,yyv,ylabel.second);
                ec->Add(elabel.first,eev,elabel.second );
                ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
            }else{
                ec->Add(xlabel.first,_EventDecoder->PutXaxis(),xlabel.second);
                ec->Add(ylabel.first,PutHist( outerPixelId, caseId ),ylabel.second);
                ec->Add(elabel.first,PutErr( outerPixelId, caseId ),elabel.second );
                ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
            }
        }else{
            ec->Add(xlabel.first,_EventDecoder->PutXaxis(),xlabel.second);
            std::vector<Double> dummy( (ec->Put(xlabel.first).size()-1),1 );
            ec->Add(ylabel.first,dummy,ylabel.second);
            ec->Add(elabel.first,dummy,elabel.second );
            ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
        }
    }else{
        UtsusemiError( _MessageTag+"There is no information of tof_bin_type.[isInvalidConvType]" );
    }
    /**
    }else if (tof_bin_type<5){
        ec->Add(xlabel.first,_gslHist->at(innerId)->PutBin(),xlabel.second);
        if (_runNumber>0){
            ec->Add(ylabel.first,PutHist( outerPixelId, caseId ),ylabel.second);
            ec->Add(elabel.first,PutErr( outerPixelId, caseId ),elabel.second );
        }else{
            std::vector<Double> dummy( (ec->Put(xlabel.first).size()-1),1 );
            ec->Add(ylabel.first,dummy,ylabel.second);
            ec->Add(elabel.first,dummy,elabel.second );
        }
        ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
    }else if ((tof_bin_type==12)||(tof_bin_type==13)||(tof_bin_type==20)||(tof_bin_type==23)||(tof_bin_type==24)||(tof_bin_type==25)){
        ec->Add(xlabel.first,_EventDecoder->PutXaxis(),xlabel.second);
        if (_runNumber>0){
            ec->Add(ylabel.first,PutHist( outerPixelId, caseId ),ylabel.second);
            ec->Add(elabel.first,PutErr( outerPixelId, caseId ),elabel.second );
        }else{
            std::vector<Double> dummy( (ec->Put(xlabel.first).size()-1),1 );
            ec->Add(ylabel.first,dummy,ylabel.second);
            ec->Add(elabel.first,dummy,elabel.second );
        }
        ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
    }else if ((tof_bin_type==21)||(tof_bin_type==22)||(tof_bin_type==27)){
        std::vector<Double> xxv = _EventDecoder->PutXaxis();
        std::vector<Double> yyv = PutHist( outerPixelId, caseId );
        std::vector<Double> eev = PutErr( outerPixelId, caseId );
        reverse( xxv.begin(),xxv.end() );
        reverse( yyv.begin(),yyv.end() );
        reverse( eev.begin(),eev.end() );
        ec->Add(xlabel.first,xxv,xlabel.second);
        ec->Add(ylabel.first,yyv,ylabel.second);
        ec->Add(elabel.first,eev,elabel.second );
        ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
    */
        /*
        Double xsize = xxv.size();
        Double ysize = yyv.size();
        Double esize = eev.size();
        std::vector<Double> xv, yv, ev;
        xv.resize( xsize,0.0 );
        yv.resize( ysize,0.0 );
        ev.resize( esize,0.0 );
        xv[0] = xxv[ xsize-1 ];
        for (UInt4 i=0;i<ysize;i++){
            xv[i+1] = xxv[ xsize-1-(i+1) ];
            yv[i]   = yyv[ ysize-1-i ];
            ev[i]   = eev[ esize-1-i ];
        }
        ec->Add(xlabel.first,xv,xlabel.second);
        ec->Add(ylabel.first,yv,ylabel.second);
        ec->Add(elabel.first,ev,elabel.second );
        ec->SetKeys(xlabel.first,ylabel.first,elabel.first);
        */
    //}else{
//        std::cout << _MessageTag << "There is no information about tof_bin_type = "<< tof_bin_type << std::endl;
    //  }
}
//////////////////////////////////////////////////////////
template <typename T1, typename T2>
bool UtsusemiEventDataConverterTemplate<T1,T2>::
AddRunInfoToHeader( HeaderBase* _hh, UInt4 caseId ){
    std::string RUNNUMBER = "";
    for (UInt4 i=0; i<_runNumbers.size(); i++){
        if (RUNNUMBER!="") RUNNUMBER += "+";
        RUNNUMBER += _stools->Int4ToString( _runNumbers[i] );
    }
    _hh->Add( UTSUSEMI_KEY_HEAD_RUNNUMBER, RUNNUMBER );
    _hh->Add( UTSUSEMI_KEY_HEAD_MONITORCOUNT, 0.0 );
    _hh->Add( UTSUSEMI_KEY_HEAD_INSTRUMENT, _instCode );
    _hh->Add( UTSUSEMI_KEY_HEAD_SAMPLETYPE, UTSUSEMI_KEY_HEAD_SAMPLETYPE_UNKNOWN );
    if (_CaseDecoder->PutT0TreatTools()->_RangeSingleTimeSlice.empty())
      _hh->Add( UTSUSEMI_KEY_HEAD_MEASPERIOD, PutMeasTimeList() );
    else
      _hh->Add( UTSUSEMI_KEY_HEAD_MEASPERIOD, _CaseDecoder->PutMeasPeriodFromT0() );
    UInt4 num_of_case = PutNumOfCases();
    std::vector<UInt4> t0list = PutNumOfT0ListInCases();
    _numOfT0List.clear();
    _numOfT0List.resize(t0list.size());
    copy( t0list.begin(), t0list.end(), _numOfT0List.begin() );
    Int4 num_of_t0 = 0;
    if (_numOfT0List.size()==1) num_of_t0 = _numOfT0List[0];
    else num_of_t0 = _numOfT0List[ caseId ];
    _hh->Add( UTSUSEMI_KEY_HEAD_KICKERCOUNT, num_of_t0 );
    _hh->Add( UTSUSEMI_KEY_HEAD_CASEID, (Int4)caseId );

    _hh->Add( UTSUSEMI_KEY_HEAD_L1,  _EventDecoder->PutL1() );
    _hh->Add( UTSUSEMI_KEY_HEAD_TYPICALL2,  _EventDecoder->PutTypicalL2() );
    _hh->Add( UTSUSEMI_KEY_HEAD_TYPICALDS,  _EventDecoder->PutTypicalDS() );
    _hh->Add( UTSUSEMI_KEY_HEAD_TYPICALPIXELSIZE,  _EventDecoder->PutTypicalPixelSize() );

    for (UInt4 i=0; i<_timeDependBackGroundList->at(0)->size(); i++){
        Double tmp = 0.0;
        for (UInt4 j=0; j<_NumOfMulTh; j++)
            tmp += _timeDependBackGroundList->at(j)->at(i);
        for (UInt4 j=0; j<_NumOfMulTh; j++)
            _timeDependBackGroundList->at(j)->at(i) = tmp;
    }

    return true;
}
#endif
