#include "T0TreatToolsBase.hh"
//////////////////////////////////////////////////////////
T0TreatToolsBase::
T0TreatToolsBase(UInt4 bytes_of_org_event){
    SetBytesOfOrgEvent( bytes_of_org_event ); //[inamura 130227]
    clearMeasPeriod();
    _RangeSingleTimeSlice.clear();
    hasReadEvents = false;
    is_ReliableClock = true;
    NumOfClocksBeforeFirstT0 = 0;
    _MessageTag = "T0TreatToolsBase::";
    ignoredT0PIDCheck = MlfEnvGetT0PidCheckIgnored();
    if (!MlfEnvGetIsQuiet()){
        if (ignoredT0PIDCheck)
            std::cout << "T0TreatToolsBase >>> T0-PID Check is ignored (MLF_ENV_T0PIDCHECK_IGNORED=y)" << std::endl;
        else
            std::cout << "T0TreatToolsBase >>> T0-PID Check is enabled (MLF_ENV_T0PIDCHECK_IGNORED=n)" << std::endl;
    }
}
//////////////////////////////////////////////////////////
T0TreatToolsBase::
~T0TreatToolsBase(){

}
//////////////////////////////////////////////////////////[inamura 130227]
void T0TreatToolsBase::
SetBytesOfOrgEvent( UInt4 bytes_of_org_event ){
    if ((bytes_of_org_event==8)||(bytes_of_org_event==4)||(bytes_of_org_event==16)) BytesOfOrgEvent = bytes_of_org_event;
    //std::cout << "SetBytesOfOrgEvent : BytesOfOrgEvent = " << BytesOfOrgEvent << std::endl;
}
//////////////////////////////////////////////////////////[inamura 130501]
void T0TreatToolsBase::
setNumOfClocksBeforeFirstT0( UInt4 num_of_clocks ){
    NumOfClocksBeforeFirstT0 = num_of_clocks;
}

//////////////////////////////////////////////////////////
void T0TreatToolsBase::
encodePidClockEvent(UChar eventPid[], UChar eventClock[], UInt8 pid, Double clock ){
    // make T0 pulseID event
    //std::cout << "T0TreatTools : PID in encoding = " << pid << std::endl;
    eventPid[0]=0x4b;
    eventPid[1]=0x00;
    eventPid[2]=0x00;
    eventPid[3]=(char)( (pid>>32)&0xff );
    eventPid[4]=(char)( (pid>>24)&0xff );
    eventPid[5]=(char)( (pid>>16)&0xff );
    eventPid[6]=(char)( (pid>>8)&0xff );
    eventPid[7]=(char)( pid&0xff );

    // make Instrument Clock event
    eventClock[0]=0x4c;
    UInt4 sec = (UInt4)( floor(clock) );
    //unsigned long sub = (unsigned long)( floor( (clock - sec)*32768. ) );
    UInt4 sub = (UInt4)( floor( (clock - floor(clock))*32768. ) );

    Double subsecd = (Double)sub/32768.;
    UInt4 subm = (UInt4)( floor( (clock - floor(clock) - subsecd )*40000000. + 0.5 ) );
    eventClock[1]=(char)( ((sec)>>22)&0xff );
    eventClock[2]=(char)( ((sec)>>14)&0xff );
    eventClock[3]=(char)( ((sec)>>6)&0xff );
    eventClock[4]=(char)( (((sec)&0x3f)<<2) + (((sub)&0x7fff)>>13) );
    eventClock[5]=(char)( ((sub)&0x1fff)>>5 );
    eventClock[6]=(char)( (((sub)&0x1f)<<3 ) + (((subm)&0x700)>>8) );
    eventClock[7]=(char)( (subm)&0xff );

}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodePidClockEvent(UChar eventPid[], UChar eventClock[], UInt8 *pid, Double *clock ){
    decodePidEvent( eventPid, pid );
    decodeT0ClockEvent( eventClock, clock);
}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodePidEvent(UChar eventPid[], UInt8 *pid ){
    /* decode PulseId (40bit) */
    *pid=((UInt8)eventPid[3]<<32)
        +((UInt4)eventPid[4]<<24)
        +((UInt4)eventPid[5]<<16)
        +((UInt4)eventPid[6]<<8)
        +(UInt4)eventPid[7];
}
//////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodeT0ClockEvent(UChar eventClock[], Double *clock){
    UInt4 sec;
    Double subsec;
    Double submicrosec;

    /* decode Second from 2008/1/1 (30bit) */
    sec=((UInt4)eventClock[1]<<22)
        +((UInt4)eventClock[2]<<14)
        +((UInt4)eventClock[3]<<6)
        +((UInt4)eventClock[4]>>2);

    /* decode sub-Second (15bit) */
    subsec=(Double)(
        ((UInt4)(eventClock[4]&3)<<13)
        +((UInt4)eventClock[5]<<5)
        +((UInt4)eventClock[6]>>3)
        )/32768.;
    /* decode sub-microSecond (11bit) */
    submicrosec=(Double)(
        ((UInt4)(eventClock[6]&7)<<8)
        +(UInt4)eventClock[7]
        )/40000000.;
    *clock=(Double)sec + subsec + submicrosec;
}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
encodeT0InfoEvent(UChar event[], UInt8 num, Double clock) {
    UInt4 k = (UInt4)floor(clock);
    UInt4 l = (UInt4)((clock-floor(clock))*1000.);
    event[0]=0x4a;
    event[1]=(Char)( (k&0x7f80)>>7 );
    event[2]=(Char)( ( (k&0x7f)<<1 )+( (l&0x200)>>9 ) );
    event[3]=(Char)( ( (l&0x1fe)>>1 ) );
    event[4]=(Char)( ((l&0x01)<<7) + ( (num&0x7f000000)>>24) );
    event[5]=(Char)( ( num&0xff0000)>>16 );
    event[6]=(Char)( ( num&0xff00)>>8 );
    event[7]=(Char)( num&0xff );
}
/////////////////////////////////////////////////////////
void T0TreatToolsBase::
encodeT0InfoEvent(UChar event[], UInt8 num ) {
    event[0]=0x4f;
    event[1]=(Char)( 0 );
    event[2]=(Char)( ( num&0xff0000000000)>>40 );
    event[3]=(Char)( ( num&0xff00000000)>>32 );
    event[4]=(Char)( ( num&0xff000000)>>24 );
    event[5]=(Char)( ( num&0xff0000)>>16 );
    event[6]=(Char)( ( num&0xff00)>>8 );
    event[7]=(Char)( num&0xff );
}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodeT0InfoEvent(UChar event[], UInt8 *num, Double *clock) {
    UInt4 temp1,temp2;
    temp1 = (UInt4)(event[1]<<7) + (UInt4)(event[2]>>1);
    temp2 = (UInt4)( (event[2]&0x1)<<9 ) + (UInt4)(event[3]<<1) + (UInt4)(event[4]>>7);
    *clock = (Double)temp1 + ((Double)temp2/1000.);

    temp1 = (UInt4)((event[4]&0x7f)<<24) + (UInt4)(event[5]<<16);
    temp2 = (UInt4)(event[6]<<8) + (UInt4)(event[7]);
    *num = temp1 + temp2;
}
/////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodeT0InfoEvent(UChar event[], UInt8 *num ) {
    *num = (((UInt8)event[2])<<40) + (((UInt8)event[3])<<32) + ((UInt8)(event[4])<<24)
        + (UInt8)(event[5]<<16) + (UInt8)(event[6]<<8) + (UInt8)(event[7]);
}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
encodeClockIncEvent(UChar event[], Double clock ) {
    UInt8 clk = (UInt8)(floor( clock*1000000000.0 ));
    event[0]=0x4e;
    event[1]=(Char)(0x00);
    event[2]=(Char)( clk >>40 );
    event[3]=(Char)( (clk & 0xff00000000LL)>>32 );
    event[4]=(Char)( (clk & 0xff000000)>>24 );
    event[5]=(Char)( (clk & 0xff0000)>>16 );
    event[6]=(Char)( (clk & 0xff00)>>8 );
    event[7]=(Char)( (clk & 0xff) );

}

/////////////////////////////////////////////////////////
void T0TreatToolsBase::
decodeClockIncEvent(UChar event[], Double *clock) {
    double cnt = 40000000.0;
    if (event[0]==0x4e) cnt = 1000000000.0;
    *clock = (Double)( ( (UInt8)(event[2])<<40 )
                       + ( (UInt8)(event[3])<<32 )
                       + ( (UInt8)(event[4])<<24 )
                       + ( (UInt8)(event[5])<<16 )
                       + ( (UInt8)(event[6])<<8 )
                       + ( (UInt8)(event[7] ) )
        )/cnt;
}

//////////////////////////////////////////////////////////
std::vector<Double> T0TreatToolsBase::
convertInstClockToDateTime( Double inst_clock ){
    time_t MLF_clock_origin;
    time_t clock_UTC;

    struct tm t;
    t.tm_sec = 0;
    t.tm_min = 0;
    t.tm_hour = 0;
    t.tm_mday = 1;
    t.tm_mon = 1-1;
    t.tm_year = 2008-1900;
    t.tm_wday = 0;
    t.tm_yday = 0;
    t.tm_isdst = 0;

    MLF_clock_origin = mktime(&t);

    UInt4 inst_clock_d = (UInt4)( floor( inst_clock ) );
    Double inst_clock_f = inst_clock - (Double)inst_clock_d;
    clock_UTC = (inst_clock_d + (9*60*60)) + MLF_clock_origin; // (JST->UTC) + MLF_clock_origin


    struct tm* s1;
    s1 = localtime(&clock_UTC);

    std::vector<Double> ret;
    ret.clear();
    ret.resize(7,0.0);
    ret[0] = (Double)(s1->tm_year+1900);
    ret[1] = (Double)(s1->tm_mon+1);
    ret[2] = (Double)(s1->tm_mday);
    ret[3] = (Double)(s1->tm_hour);
    ret[4] = (Double)(s1->tm_min);
    ret[5] = (Double)(s1->tm_sec);
    ret[6] = inst_clock_f;

    return ret;
}
//////////////////////////////////////////////////////////
Double T0TreatToolsBase::
convertDateTimeToInstClock( std::vector<Double> date_time )
{
    if (date_time.size()!=7){
        return -1.0;
    }
    struct tm t0;
    t0.tm_sec = 0;
    t0.tm_min = 0;
    t0.tm_hour = 0;
    t0.tm_mday = 1;
    t0.tm_mon = 1-1;
    t0.tm_year = 2008-1900;
    t0.tm_wday = 0;
    t0.tm_yday = 0;
    t0.tm_isdst = 0;
    time_t MLF_clock_origin = mktime(&t0);

    struct tm t;
    UInt4 tm_sec = (UInt4)(floor(date_time[5]));
    UInt4 tm_min = (UInt4)(floor(date_time[4]));
    UInt4 tm_hour = (UInt4)(floor(date_time[3]));
    if ((tm_sec>=60)||(tm_min>=60)||(tm_hour>=24)) return -1.0;
    t.tm_sec = tm_sec;
    t.tm_min = tm_min;
    t.tm_hour = tm_hour;

    UInt4 tm_mon = (UInt4)(floor(date_time[1]))-1;

    UInt4 tm_mday = (UInt4)(floor(date_time[2]));
    switch(tm_mon){
    case 0: // Jun
        if (tm_mday>31) return -1.0;
        break;
    case 1: // Feb
        if (tm_mday>29) return -1.0;
        break;
    case 2: // Mar
        if (tm_mday>31) return -1.0;
        break;
    case 3: // Apr
        if (tm_mday>30) return -1.0;
        break;
    case 4: // May
        if (tm_mday>31) return -1.0;
        break;
    case 5: // Jun
        if (tm_mday>30) return -1.0;
        break;
    case 6: // Jul
        if (tm_mday>31) return -1.0;
        break;
    case 7: // Aug
        if (tm_mday>31) return -1.0;
        break;
    case 8: // Sep
        if (tm_mday>30) return -1.0;
        break;
    case 9: // Oct
        if (tm_mday>31) return -1.0;
        break;
    case 10: // Nov
        if (tm_mday>30) return -1.0;
        break;
    case 11: // Dec
        if (tm_mday>31) return -1.0;
        break;
    default:
        return -1.0;
    }

    t.tm_mon = tm_mon;
    t.tm_mday = tm_mday;
    Int4 tm_year = (UInt4)(floor(date_time[0]))-1900;
    if (tm_year<0) return -1.0;
    t.tm_year = tm_year;
    t.tm_wday = 0;
    t.tm_yday = 0;
    t.tm_isdst = 0;
    time_t given_clock = mktime(&t);

    if (given_clock==(time_t)(-1)) return -1.0;
    if ((date_time[6]<0.0)||(date_time[6]>1.0)) return -1.0;

    return (Double)( given_clock -(9*60*60) - MLF_clock_origin ) + date_time[6];
}

//////////////////////////////////////////////////////////
UInt4 T0TreatToolsBase::
readOrgEvent(std::string filename) {
    std::vector<std::string> filenames(1,filename);
    return readOrgEvent( filenames );
}

//////////////////////////////////////////////////////////
UInt4 T0TreatToolsBase::
readOrgEvent(std::vector<std::string> filenames) {
    hasReadEvents = false;

    sort(filenames.begin(),filenames.end());
    std::vector<FILE*> fp_list( filenames.size() );
    for (UInt4 ii=0;ii<filenames.size();ii++){
        if(NULL==(fp_list[ii]=fopen(filenames[ii].c_str(),"rb"))){
            std::cout << _MessageTag+"readOrgEvent : Can't open " << filenames[ii] << "." << std::endl;
            return 1;
        }else{
            std::cout << _MessageTag+"readOrgEvent : try to read " << filenames[ii] << "." << std::endl;
        }
    }

    //UChar buf[BytesOfOrgEvent];
    UChar *buf = new UChar[BytesOfOrgEvent];
    size_t i;
    UInt8 num_events=0;
    UInt8 pulseId=0;
    Double clock=0;
    bool isNeverClockEvent = true; // for event data without clock-event i.e. Readout events

    pulseId_n.clear();
    t0Time_n.clear();
    t0Sec_n.clear();
    t0Index_n.clear();

    UInt4 ind = 0;

    _MeasPeriodClock.clear();
    _MeasPeriodClock.resize( fp_list.size() );
    for (UInt4 j=0; j<_MeasPeriodClock.size(); j++){
        _MeasPeriodClock[j].first = 0.0;
        _MeasPeriodClock[j].second = 0.0;
    }
    // std::cout << "T0TreatToolsBase::readOrgEvent >> BytesOfOrgEvent = " << BytesOfOrgEvent << std::endl;
    while(true){
        i=fread(buf, BytesOfOrgEvent, 1, fp_list[ind]);
        if (i!=1){
            if (ind==(fp_list.size()-1)){
                break;
            }else{
                _MeasPeriodClock[ind].second = t0Time_n.back();
                ind++;
                i=fread(buf, BytesOfOrgEvent, 1, fp_list[ind]);
                if (i!=1) break;
            }
        }
        num_events+=1;

        // If a event is T0 event
        if (checkHeaderT0(buf)){
            pulseId = decodePulseIdEvent( buf );
            //if (pulseId==0){  //[inamura 140520: for bugfix on AppendRawData]
            if (pulseId_n.empty()){
            //}else if ((pulseId_n[0]!=0)&&(pulseId==0)){
            }else if (pulseId<pulseId_n.back()){
                std::cout << " Previous Pulse Id = "<<pulseId_n.back()<<std::endl;
                std::cout << " Current Pulse Id = "<<pulseId<< " is invalid."<<std::endl;
                if (ignoredT0PIDCheck){
                }else{
                    std::cout << " T0 Info is cleared." << std::endl;
                    pulseId_n.clear();
                    t0Time_n.clear();
                    t0Sec_n.clear();
                    t0Index_n.clear();
                }
            }else if (pulseId != (pulseId_n.back() + 1)){
                //std::cout << " Previous Pulse Id = " << pulseId_n.back() << std::endl;
                //std::cout << " Current Pulse Id = " << pulseId << " is invalid." << std::endl;
            }
            pulseId_n.push_back(pulseId);
            t0Index_n.push_back(num_events-1);

            // If no Clock Event in previous frame, add dummy frame clock.
            if (pulseId_n.size()>(t0Time_n.size()+1)){
                //std::cout << "@@@ No Clock Event in a frame." << std::endl;
                clock += 0.040;
                t0Time_n.push_back( clock );
                t0Sec_n.push_back( clock-MeasPeriodClock[0] );
            }
        }

        // If a event is Clock Event
        if (checkHeaderClock(buf)){
            clock = decodeInstClockEvent( buf );
            if (pulseId_n.size()!=(t0Time_n.size()+1)){
                std::cout << "T0TreatToolsBase::readOrgEvent >> Warning!!! : Found Wrong Clock Event, Ignored" << std::endl;
            }else{
                t0Time_n.push_back(clock);
                if (MeasPeriodClock[0]==0.0) MeasPeriodClock[0]=clock;
                if ((clock!=0.0)&&(clock<MeasPeriodClock[0])) {
                    MeasPeriodClock[0]=clock;
                }
                if (_MeasPeriodClock[ind].first==0.0) _MeasPeriodClock[ind].first=clock;
                if ((clock!=0.0)&&(clock<_MeasPeriodClock[ind].first)) {
                    _MeasPeriodClock[ind].first=clock;
                }
                t0Sec_n.push_back(clock-MeasPeriodClock[0]);
                isNeverClockEvent = false;
            }
        }
    }

    if (t0Index_n.empty()){
        std::cout << _MessageTag+"readOrgEvent >> Can not read event data correctly." << std::endl;
        return 1;
    }

    // Add last boundary
    pulseId_n.push_back(pulseId+1);
    t0Index_n.push_back(num_events);
    clock = t0Time_n[t0Time_n.size()-1];
    UInt4 diff_pId_t0T = 0;
    if (pulseId_n.size()>t0Time_n.size())
        diff_pId_t0T = (UInt4)(pulseId_n.size()-t0Time_n.size());
    for (UInt4 i=0;i<diff_pId_t0T;i++){
        t0Time_n.push_back(clock+0.040);
        t0Sec_n.push_back(clock+0.040-MeasPeriodClock[0]);
    }

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

    if (MeasPeriodClock[1]==0.0) MeasPeriodClock[1]=clock;
    if ((clock!=0.0)&&(clock>MeasPeriodClock[1])) MeasPeriodClock[1]=clock;
    _MeasPeriodClock[ind].second = t0Time_n.back();

    double sum_t0=0.;
    if (isNeverClockEvent){
        sum_t0=0;
    }else{
        for (UInt4 j=0;j<(t0Time_n.size()-1);j++){
            sum_t0+=t0Time_n[j];
        }
    }
    if (sum_t0!=0.){
        pulseId_m.clear();
        t0Index_m.clear();
        t0Time_m.clear();
        t0Sec_m.clear();
        pulseId_m.resize( pulseId_n.size() );
        t0Index_m.resize( t0Index_n.size() );
        t0Time_m.resize( t0Time_n.size() );
        t0Sec_m.resize( t0Sec_n.size() );

        copy( pulseId_n.begin(), pulseId_n.end(), pulseId_m.begin() );
        copy( t0Index_n.begin(), t0Index_n.end(), t0Index_m.begin() );
        copy( t0Time_n.begin(), t0Time_n.end(), t0Time_m.begin() );
        copy( t0Sec_n.begin(), t0Sec_n.end(), t0Sec_m.begin() );

    }else{
        if (t0Time_m.size()!=0){
            int m_pointer = 0;
            UInt8 c_pid;
            for (UInt4 j=0;j<t0Time_n.size();j++){
                c_pid = pulseId_n[j];
                for (UInt4 k=m_pointer;k<t0Time_m.size();k++){
                    if (c_pid==pulseId_m[k]){
                        t0Time_n[j]=t0Time_m[k];
                        t0Sec_n[j]=t0Sec_m[k];
                        m_pointer=k;
                        break;
                    }
                }
            }
        }
    }

    t0Time_diff.clear();
    t0Time_diff.push_back(0.0);
    for (UInt4 j=0;j<(pulseId_n.size()-1);j++){
        t0Time_diff.push_back( t0Time_n[j+1]-t0Time_n[j] );
    }
    std::cout << _MessageTag+"readOrgEvent >> T0 Index size=" << t0Index_n.size() << std::endl;

    if(buf) delete [] buf;

    hasReadEvents = true;
    return 0;
}

//////////////////////////////////////////////////////////
UInt4 T0TreatToolsBase::
saveT0IndexEvent(std::string filename){
    if (!hasReadEvents){
        std::cout << _MessageTag+"saveT0IndexEvent >> No T0 Index data." << std::endl;
        return 1;
    }

    FILE *fout;
    if(NULL==(fout= fopen(filename.c_str(),"wb"))){
        std::cout << _MessageTag+"saveT0IndexEvent >> Can't open " << filename << "." << std::endl;
        return 1;
    }

    //UChar event0[BytesOfT0Event],event1[BytesOfT0Event];
    UChar *event0 = new UChar[BytesOfT0Event];
    UChar *event1 = new UChar[BytesOfT0Event];
    UInt8 num_head=0;
    UInt8 pid=0;
    UInt8 pid_pre=pulseId_n[0];
    Double clock=0;
    Double clock_start=0.;
    Double clock_diff=0.;

    bool isJustAfterT0=false;
    for (UInt4 i=0;i<pulseId_n.size();i++){
        pid = pulseId_n[i];
        clock = t0Time_n[i];
        clock_diff=clock-clock_start;

        if ((pid!=(pid_pre+1))||(clock_diff>70.*60.*60.)){
            encodePidClockEvent(event0,event1,pid,clock);
            std::fwrite(event0,1,BytesOfT0Event,fout);
            std::fwrite(event1,1,BytesOfT0Event,fout);

            clock_start=clock;
            clock_diff=0;
            isJustAfterT0=true;
        }

        num_head=t0Index_n[i];
        //encodeT0InfoEvent(event0,num_head,clock_diff);
        encodeT0InfoEvent(event0,num_head);
        std::fwrite(event0,1,BytesOfT0Event,fout);
        if (is_ReliableClock){
            if (isJustAfterT0){
                encodeClockIncEvent(event1,0.0);
                isJustAfterT0=false;
            }else{
                encodeClockIncEvent(event1,(t0Time_diff[i]));
            }
            std::fwrite(event1,1,BytesOfT0Event,fout);
        }
        pid_pre=pid;
    }
    fclose(fout);
    std::cout << _MessageTag+"saveT0IndexEvent >> T0Index are saved " << filename << std::endl;
    if(event0) delete [] event0;
    if(event1) delete [] event1;
    return 0;
}

//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
readT0IndexEventold(std::string filename){
    std::vector<std::string> filenames(1,filename);
    return readT0IndexEvent( filenames );
}
//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
readT0IndexEventold(std::vector<std::string> filenames){

    std::vector<FILE*> fp_list( filenames.size() );
    for (UInt4 ii=0;ii<filenames.size();ii++){
        if(NULL==(fp_list[ii]=fopen(filenames[ii].c_str(),"rb"))){
            std::cout << "T0TreatTools : Can't open " << filenames[ii] << "." << std::endl;
            return 1;
        }
    }

    is_ReliableClock = true;
    UInt4 flg=0;
    UInt8 pid_add=0;
    UInt8 pid_start=0;
    Double clock_start=0.0;
    Double clock_diff=0.0;
    Double clock_inc = 0.0;
    Double clock_cur = 0.0;

    pulseId_n.clear();
    t0Time_n.clear();
    t0Index_n.clear();
    t0Time_diff.clear();

    size_t i;
    UInt8 num_events;
    //UChar buf0[BytesOfT0Event],buf1[BytesOfT0Event];
    UChar *buf0 = new UChar[BytesOfT0Event];
    UChar *buf1 = new UChar[BytesOfT0Event];

    UInt4 ind=0;

    for(;;){
        if(flg==0){
            i=fread(buf0,BytesOfOrgEvent,1,fp_list[ind]);
            if (i!=1){
                if (ind==(fp_list.size()-1)){
                    flg=3;
                }else{
                    ind++;
                    i=fread(buf0,BytesOfOrgEvent,1,fp_list[ind]);
                    if (i!=1) flg=3;
                }
            }
        }

        if (flg==3){
            break;
        }

        if (buf0[0]==0x4b){
            i=fread(buf1,BytesOfOrgEvent,1,fp_list[ind]);
            if(1!=i){
                if (ind==(fp_list.size()-1)){
                    flg=3;
                }else{
                    ind++;
                    i=fread(buf1,BytesOfOrgEvent,1,fp_list[ind]);
                    if (1!=i) flg=3;
                }
            }
            if (flg!=3){
                if(0x4c==buf1[0]){
                    decodePidClockEvent(buf0,buf1,&pid_start,&clock_start);
                    //std::cout << "Pid,Clock" << pid_start <<","<< clock_start << std::endl;
                    pid_add=0;
                    flg=0;
                    clock_cur = clock_start;
                }else{
                    memcpy(buf0,buf1,8);
                    flg=1;
                }
                if (flg==1){
                    if (buf0[0]==0x4b){
                    }else{
                        flg=0;
                    }
                }
            }

        }

        if (flg==3){
            break;
        }

        if (buf0[0]==0x4a){
            i=fread(buf1,BytesOfOrgEvent,1,fp_list[ind]);
            if(1!=i){
                if (ind==(fp_list.size()-1)){
                    flg=3;
                }else{
                    ind++;
                    i=fread(buf1,BytesOfOrgEvent,1,fp_list[ind]);
                    if (1!=i) flg=3;
                }
                if (flg==3){
                    decodeT0InfoEvent(buf0,&num_events,&clock_diff);
                    t0Index_n.push_back(num_events);
                    pulseId_n.push_back(pid_start+pid_add);
                    t0Time_n.push_back(clock_start+clock_diff);
                    if (is_ReliableClock){
                        t0Time_diff.push_back( clock_diff - clock_start );
                    }
                    pid_add+=1;
                }
            }
            if (flg!=3){
                decodeT0InfoEvent(buf0,&num_events,&clock_diff);
                t0Index_n.push_back(num_events);
                pulseId_n.push_back(pid_start+pid_add);
                pid_add+=1;

                if ((0x4d==buf1[0])||(0x4e==buf1[0])){
                    decodeClockIncEvent(buf1,&clock_inc);
                    clock_cur += clock_inc;
                    if ((clock_inc==0.0)&&(!(t0Time_n.empty()))) clock_inc = clock_cur - t0Time_n[ t0Time_n.size()-1 ];
                    t0Time_diff.push_back( clock_inc );
                    t0Time_n.push_back(clock_cur);
                    if (MeasPeriodClock[0]==0.0) MeasPeriodClock[0]=clock_cur;
                    if ((clock_cur!=0.0)&&(clock_cur<MeasPeriodClock[0])) MeasPeriodClock[0]=clock_cur;

                    flg=0;
                }else{
                    t0Time_n.push_back(clock_start+clock_diff);
                    memcpy(buf0,buf1,8);
                    flg=1;
                    is_ReliableClock = false;
                }
                if (flg==1){
                    if (buf0[0]==0x4a){
                    }else{
                        flg=0;
                    }
                }
            }
        }
    }
    std::vector<FILE*>::iterator it=fp_list.begin();
    while( it!=fp_list.end() ){
        fclose( *it );
        it++;
    }

    if (!(is_ReliableClock)){
        t0Time_diff.clear();
        t0Time_diff.push_back(0.0);
        for (UInt4 j=0;j<(pulseId_n.size()-1);j++){
            t0Time_diff.push_back( t0Time_n[j+1]-t0Time_n[j] );
        }
    }

    if(buf0) delete [] buf0;
    if(buf1) delete [] buf1;

    return 0;

}
//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
readT0IndexEvent(std::string filename){
    std::vector<std::string> filenames(1,filename);
    return readT0IndexEvent( filenames );
}
//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
readT0IndexEvent(std::vector<std::string> filenames){

    sort(filenames.begin(),filenames.end());
    std::vector<FILE*> fp_list( filenames.size() );
    for (UInt4 ii=0;ii<filenames.size();ii++){
        if(NULL==(fp_list[ii]=fopen(filenames[ii].c_str(),"rb"))){
            std::cout << _MessageTag+"readT0IndexEvent >> Can't open " << filenames[ii] << "." << std::endl;
            return 1;
        }
    }

    is_ReliableClock = true;
    UInt8 pid_add=0;
    UInt8 pid_start=0;
    Double clock_start=0.0;
    Double clock_cur = 0.0;

    pulseId_n.clear();
    t0Time_n.clear();
    t0Index_n.clear();
    t0Sec_n.clear();
    t0Time_diff.clear();

    _MeasPeriodClock.clear();
    _MeasPeriodClock.resize( fp_list.size() );
    for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
        _MeasPeriodClock[i].first = 0.0;
        _MeasPeriodClock[i].second = 0.0;
    }

    size_t i=0;
    //UChar buf0[BytesOfT0Event];
    UChar *buf0 = new UChar[BytesOfT0Event];

    UInt4 ind=0;
    UInt8 num_events=0;
    UInt8 pre_num_events=0;

    Double sec_cur = 0.;
    Double sec_cur_shift = 0.;

    bool isRead = true;
    bool isJustAfterChangeFile = false;

    while(true){
        if (isRead){
            i=fread(buf0, BytesOfT0Event, 1, fp_list[ind]);
            if (i!=1){
                if (ind==(fp_list.size()-1)){
                    break;
                }else{
                    _MeasPeriodClock[ind].second = t0Time_n.back();

                    ind++;
                    i=fread(buf0,BytesOfT0Event,1,fp_list[ind]);
                    if (i!=1) break;
                    pre_num_events += num_events;

                    sec_cur_shift += sec_cur;
                    sec_cur = 0;
                    isJustAfterChangeFile = true;
                }
            }
        }

        if (buf0[0]==0x4b){
            isRead = true;
            decodePidEvent( buf0, &pid_start );
            pid_add=0;
            i=fread(buf0, BytesOfT0Event, 1, fp_list[ind]);
            if (i!=1){
                if (ind==(fp_list.size()-1)){
                    break;
                }else{
                    _MeasPeriodClock[ind].second = t0Time_n.back();

                    ind++;
                    i=fread(buf0,BytesOfT0Event,1,fp_list[ind]);
                    if (i!=1) break;
                    pre_num_events += num_events;

                    sec_cur_shift += sec_cur;
                    sec_cur = 0;
                    isJustAfterChangeFile = true;
                }
            }
            if (buf0[0]==0x4c){
                decodeT0ClockEvent( buf0, &clock_start );
                clock_cur = clock_start;
            }else{
                clock_cur += 0.040;
                isRead = false;
            }
        }
        if ((buf0[0]==0x4a)||(buf0[0]==0x4f)){
            isRead = true;
            Double clock_diff;
            if (buf0[0]==0x4f)
                decodeT0InfoEvent(buf0,&num_events);
            else
                decodeT0InfoEvent(buf0,&num_events,&clock_diff);

            t0Index_n.push_back(pre_num_events+num_events);
            pulseId_n.push_back(pid_start+pid_add);
            pid_add+=1;

            i=fread(buf0, BytesOfT0Event, 1, fp_list[ind]);
            if (i!=1){
                if (ind==(fp_list.size()-1)){
                    break;
                }else{
                    _MeasPeriodClock[ind].second = t0Time_n.back();
                    ind++;
                    i=fread(buf0,BytesOfT0Event,1,fp_list[ind]);
                    if (i!=1) break;
                    pre_num_events += num_events;

                    sec_cur_shift += sec_cur;
                    sec_cur = 0;
                    isJustAfterChangeFile = true;
                }
            }

            if ((0x4d==buf0[0])||(0x4e==buf0[0])){
                Double clock_inc;
                decodeClockIncEvent(buf0,&clock_inc);
                clock_cur += clock_inc;
                sec_cur += clock_inc;
                if ((clock_inc==0.0)&&(!(t0Time_n.empty()))) {
                    clock_inc = clock_cur - t0Time_n[ t0Time_n.size()-1 ];
                    if (isJustAfterChangeFile) {
                    }else{
                        sec_cur += clock_inc;
                        isJustAfterChangeFile = false;
                    }
                }
                t0Time_diff.push_back( clock_inc );
                t0Time_n.push_back(clock_cur);

                t0Sec_n.push_back( sec_cur + sec_cur_shift );
                if (MeasPeriodClock[0]==0.0) MeasPeriodClock[0]=clock_cur;
                if ((clock_cur!=0.0)&&(clock_cur<MeasPeriodClock[0])) MeasPeriodClock[0]=clock_cur;
                if (_MeasPeriodClock[ind].first==0.0) _MeasPeriodClock[ind].first=clock_cur;
                if ((clock_cur!=0.0)&&(clock_cur<_MeasPeriodClock[ind].first)) _MeasPeriodClock[ind].first=clock_cur;
            }else{
                t0Time_n.push_back(clock_start+clock_diff);
                isRead = false;
                is_ReliableClock = false;
            }
        }
    }
    if (t0Time_n.empty()) {
        std::cout << "T0TreatToolsBase::readT0IndexEvent >> T0IndexEventFile may be empty." << std::endl;
        return 1;
    }
    _MeasPeriodClock[ind].second = t0Time_n.back();

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

    if (!(is_ReliableClock)){
        t0Time_diff.clear();
        t0Time_diff.push_back(0.0);
        for (UInt4 j=0;j<(pulseId_n.size()-1);j++){
            t0Time_diff.push_back( t0Time_n[j+1]-t0Time_n[j] );
        }
    }

    if(buf0) delete [] buf0;

    return 0;

}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putVectorT0Index(){

    if (t0Index_n.size()!=0){
        return t0Index_n;
    }else{
        std::vector<UInt8> ret;
        ret.push_back(0);
        return ret;
    }
}

//////////////////////////////////////////////////////////

void T0TreatToolsBase::
makeVectorBySec( Double start_sec, Double end_sec, bool getT0Index ){

    if (getT0Index){
        t0Index_tmp.clear();
    }else{
        pulseId_tmp.clear();
    }

    if (t0Index_n.size()==0){
        if (getT0Index){
            t0Index_tmp.push_back(0);
        }else{
            pulseId_tmp.push_back(0);
        }
        return;
    }

    std::vector<Double> *p_t0Time = NULL;
    std::vector<Double> *p_t0Sec = NULL;
    std::vector<Double> *p_t0Time_diff = NULL;
    if (t0Sec_ext.empty()){
        p_t0Time = &t0Time_n;
        p_t0Sec = &t0Sec_n;
        p_t0Time_diff = &t0Time_diff;
    }else{
        p_t0Time = &t0Time_ext;
        p_t0Sec = &t0Sec_ext;
        p_t0Time_diff = &t0Time_diff_ext;
    }

    if (start_sec<0.0) start_sec = 0.0;
    if (end_sec<0.0) end_sec = (*p_t0Sec)[ (*p_t0Sec).size()-1 ] + 0.004;

    if (start_sec>end_sec){
        double temp = end_sec;
        end_sec = start_sec;
        start_sec = temp;
    }

    int flag = 0;

    t0Time_tmp.clear();
    t0Time_diff_tmp.clear();
    MeasPeriodClock[0] = 0.0;
    MeasPeriodClock[1] = 0.0; //[inamura 160409]
    for (UInt4 i=0; i<t0Index_n.size(); i++){
        if ( (flag==0)&&((*p_t0Sec)[i]>=start_sec) ){
            if ((MeasPeriodClock[0]==0.0)||((*p_t0Time)[i]<MeasPeriodClock[0])) {
                MeasPeriodClock[0]=(*p_t0Time)[i];
            }
            flag = 1;
        }
        if ( (flag==1)&&((*p_t0Sec)[i]>end_sec) ){
            break;
        }
        if (flag==1){
            if (getT0Index){
                t0Index_tmp.push_back(t0Index_n[i]);
            }else{
                pulseId_tmp.push_back(pulseId_n[i]);
            }

            if ((MeasPeriodClock[1]==0.0)||((*p_t0Time)[i]>MeasPeriodClock[1])) {
                MeasPeriodClock[1]=(*p_t0Time)[i];
            }
            // if NumOfClocksBeforeFirstT0 is defined, head frames must be ignored (diff = -1.0)
            if ((t0Time_diff_tmp.empty())&&(NumOfClocksBeforeFirstT0>0)){
                if (i<NumOfClocksBeforeFirstT0){
                    for (UInt4 j=0; j<NumOfClocksBeforeFirstT0; j++) t0Time_diff_tmp.push_back( -1.0 );
                }else{
                    for (UInt4 j=0; j<NumOfClocksBeforeFirstT0; j++) t0Time_diff_tmp.push_back( (*p_t0Time_diff)[i-NumOfClocksBeforeFirstT0+j] );
                }
            }
            t0Time_tmp.push_back((*p_t0Time)[i]);
            t0Time_diff_tmp.push_back((*p_t0Time_diff)[i]);
        }
    }

    if (getT0Index){
        if (t0Index_tmp.empty()){
            t0Index_tmp.push_back(0);
        }
    }else{
        if (pulseId_tmp.empty()){
            pulseId_tmp.push_back(0);
        }
    }
}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putVectorT0IndexBySec(Double start_sec, Double end_sec){
    makeVectorBySec( start_sec, end_sec, true );
    return t0Index_tmp;
}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putVectorPulseId(){

    if (pulseId_n.size()!=0){
        return pulseId_n;
    }else{
        std::vector<UInt8> ret;
        ret.push_back(0);
        return ret;
    }
}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putVectorPulseIdBySec(Double start_sec, Double end_sec){
    makeVectorBySec( start_sec, end_sec, false );
    return pulseId_tmp;
}

//////////////////////////////////////////////////////////

std::vector<Double> T0TreatToolsBase::
putVectorT0Clock(){

    if (t0Time_n.size()!=0){
        return t0Time_n;
    }else{
        std::vector<double> ret;
        ret.push_back(0);
        return ret;
    }
}
//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
putIndexByPid(UInt8 start_pid, UInt8 end_pid, UInt4 *start_ret_id, UInt4 *end_ret_id ){
    UInt4 ret=1;
    *start_ret_id = 0;
    *end_ret_id = 0;

    if (t0Index_n.size()!=0){
        if (start_pid>end_pid){
            UInt8 temp = start_pid;
            start_pid = end_pid;
            end_pid = temp;
        }
        UInt4 flg = 0;
        Int4 start_id, end_id;
        start_id=-1;
        end_id=-1;
        for (UInt4 i=0;i<t0Index_n.size();i++){
            if ((flg==0)&&(pulseId_n[i]>=start_pid)) {
                flg=1;
                start_id=i;
                std::cout<<"PID,start_id = "<< pulseId_n[i] << "," << start_id << std::endl;
            }
            if ((flg==1)&&(pulseId_n[i]>=end_pid)) {
                end_id=i;
                std::cout<<"PID,end_id = "<<pulseId_n[i]<<","<<end_id<< std::endl;
                break;
            }
        }
        if (start_id!=-1) {
            *start_ret_id = UInt4( abs(start_id) ) ;
            if (end_id!=-1) {
                *end_ret_id = UInt4( abs(end_id) );
                ret=0;
            }
        }
    }

    return ret;
}

//////////////////////////////////////////////////////////

UInt4 T0TreatToolsBase::
putIndexByClock(Double start_clock, Double end_clock, UInt4 *start_ret_id, UInt4 *end_ret_id ){
    UInt4 ret=1;
    *start_ret_id = 0;
    *end_ret_id = 0;

    if (t0Index_n.size()!=0){
        if (start_clock>end_clock){
            Double temp = start_clock;
            start_clock = end_clock;
            end_clock = temp;
        }
        std::vector<Double> *p_t0Time = NULL;
        if (t0Time_ext.empty()){
            p_t0Time = &t0Time_n;
        }else{
            p_t0Time = &t0Time_ext;
        }
        UInt4 flg = 0;
        Int4 start_id, end_id;
        start_id=-1;
        end_id=-1;
        for (UInt4 i=0;i<(*p_t0Time).size();i++){
            if ((flg==0)&&((*p_t0Time)[i]>=start_clock)) {
                flg=1;
                start_id=i;
                std::cout<<"Clock,start_id = "<< (*p_t0Time)[i] << "," << start_id << std::endl;
            }
            if ((flg==1)&&((*p_t0Time)[i]>=end_clock)) {
                end_id=i;
                std::cout<<"Clock,end_id = "<<(*p_t0Time)[i]<<","<<end_id<< std::endl;
                break;
            }
        }
        if (start_id!=-1) {
            *start_ret_id = UInt4( abs(start_id) );
            if ((*start_ret_id)>=t0Index_n.size()) *start_ret_id = (UInt4)(t0Index_n.size())-1;
            if (end_id!=-1) {
                *end_ret_id = UInt4( abs(end_id) );
                if ((*end_ret_id)>=t0Index_n.size()) *end_ret_id = (UInt4)(t0Index_n.size())-1;
                ret=0;
            }
        }
    }

    return ret;
}
//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putT0IndexByPid(UInt8 start_pid, UInt8 end_pid ){
    std::vector<UInt8> ret;
    UInt4 start_ret_id, end_ret_id;
    UInt4 result = putIndexByPid( start_pid, end_pid, &start_ret_id, &end_ret_id );
    if (result!=0){
        ret.push_back(0);
        ret.push_back(0);
    }else{
        ret.push_back( t0Index_n[ start_ret_id ] );
        ret.push_back( t0Index_n[ end_ret_id ] );
    }

    return ret;
}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putT0IndexByClock(Double start_clock, Double end_clock){
    std::vector<UInt8> ret;
    UInt4 start_ret_id, end_ret_id;
    UInt4 result = putIndexByClock( start_clock, end_clock, &start_ret_id, &end_ret_id );
    if (result!=0){
        ret.push_back(0);
        ret.push_back(0);
    }else{
        ret.push_back( t0Index_n[ start_ret_id ] );
        ret.push_back( t0Index_n[ end_ret_id ] );
    }

    return ret;
}

//////////////////////////////////////////////////////////

std::vector<Double> T0TreatToolsBase::
putT0ClockRegion(){
    std::vector<Double> ret;

    if (t0Index_n.size()!=0){
        ret.push_back(t0Time_n[0]);
        ret.push_back(t0Time_n[(t0Time_n.size()-1)]);
        return ret;

    }else{

        ret.push_back(0);
        return ret;
    }
}

//////////////////////////////////////////////////////////

std::vector<UInt8> T0TreatToolsBase::
putPidRegion(){
    std::vector<UInt8> ret;

    if (pulseId_n.size()!=0){
        ret.push_back(pulseId_n[0]);
        ret.push_back(pulseId_n[(pulseId_n.size()-1)]);
        return ret;

    }else{

        ret.push_back(0);
        return ret;
    }
}

//////////////////////////////////////////////////////////

std::vector<Double> T0TreatToolsBase::
putT0ClockDiffAll(){
    std::vector<Double> ret;
    ret.clear();
    if (t0Time_diff.empty()){
        //throw "Exception: There is no clock data to be imported.";
        std::cout << _MessageTag+"putT0ClockDiffAll >> There is no clock data." << std::endl;
        ret.push_back(0);
        return ret;
    }
    ret.resize( (NumOfClocksBeforeFirstT0+t0Time_diff.size()), -1.0 );
    for (UInt4 i=0;i<t0Time_diff.size();i++){
        ret[NumOfClocksBeforeFirstT0+i] = t0Time_diff[i]*1000.0*1000.0; // conversion from sec to micro-sec
    }
    return ret;
}

//////////////////////////////////////////////////////////

std::vector<Double> T0TreatToolsBase::
putT0ClockDiff(){
    std::vector<Double> ret;
    ret.clear();
    if (t0Time_diff_tmp.empty()){
        //throw "Exception: There is no clock data to be imported.";
        std::cout << _MessageTag+"putT0ClockDiff >> There is no clock data." << std::endl;
        ret.push_back(0);
        return ret;
    }
    for (UInt4 i=0;i<t0Time_diff_tmp.size();i++){
        ret.push_back(t0Time_diff_tmp[i]*1000.0*1000.0); // conversion from sec to micro-sec
    }
    return ret;
}

//////////////////////////////////////////////////////////
void T0TreatToolsBase::
clearMeasPeriod(){
    MeasPeriodClock.clear();
    MeasPeriodClock.push_back(0.0);
    MeasPeriodClock.push_back(0.0);
}
//////////////////////////////////////////////////////////
std::vector<Double> T0TreatToolsBase::
putMeasPeriodFromT0(){
    std::vector<Double> ret;
    //[inamura 160409]-->
    /*
    for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
        std::vector<Double> tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
        for (UInt4 j=0; j< tmp1.size(); j++) ret.push_back( tmp1[j] );
        std::vector<Double> tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
        for (UInt4 j=0; j< tmp2.size(); j++) ret.push_back( tmp2[j] );
    }
    */
    std::vector<Double> tmp1;
    std::vector<Double> tmp2;
    if (_RangeSingleTimeSlice.empty()){
        for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
            tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
            tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
            for (UInt4 j=0; j< tmp1.size(); j++) ret.push_back( tmp1[j] );
            for (UInt4 j=0; j< tmp2.size(); j++) ret.push_back( tmp2[j] );
        }
    }else{
        if (_RangeSingleTimeSlice[0]==0){ // by sec
            Double slice_s = _RangeSingleTimeSlice[1];
            Double slice_e = _RangeSingleTimeSlice[2];
            if (slice_s<0.0) slice_s = 0.0;
            if (slice_e<0.0){
                slice_e = 0.0;
                for (UInt4 i=0; i<_MeasPeriodClock.size(); i++)
                    slice_e += (_MeasPeriodClock[i].second - _MeasPeriodClock[i].first);
            }
            Double start_sec = 0.0;
            bool isSearchSt = true;
            bool isFinish = false;
            for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
                tmp1.clear();
                tmp2.clear();
                Double end_sec = start_sec + (_MeasPeriodClock[i].second - _MeasPeriodClock[i].first);
                if (isSearchSt){
                    if ((start_sec<=slice_s)&&(slice_s<end_sec)){
                        isSearchSt = false;
                        if (slice_e<=end_sec){
                            tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first + (slice_s-start_sec));
                            tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].first + (slice_e-start_sec));
                            isFinish = true;
                        }else{
                            tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first + (slice_s-start_sec));
                            tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
                        }
                    }
                }else{
                    if (slice_e<=end_sec){
                        isFinish = true;
                        tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
                        tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].first + (slice_e-start_sec) );
                    }else{
                        tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
                        tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
                    }
                }
                for (UInt4 j=0; j< tmp1.size(); j++) ret.push_back( tmp1[j] );
                for (UInt4 j=0; j< tmp2.size(); j++) ret.push_back( tmp2[j] );
                if (isFinish) break;
                start_sec = end_sec;
            }
        }else{ // by clock calculated from date-time
            Double clock_s = _RangeSingleTimeSlice[1];
            Double clock_e = _RangeSingleTimeSlice[2];
            if (clock_s<0.0) clock_s = _MeasPeriodClock[0].first;
            if (clock_e<0.0) clock_e = _MeasPeriodClock.back().second;
            bool isSearchSt = true;
            bool isFinish = false;
            for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
                tmp1.clear();
                tmp2.clear();
                if (isSearchSt){
                    if (( _MeasPeriodClock[i].first<=clock_s)&&( clock_s<_MeasPeriodClock[i].second)){
                        isSearchSt = false;

                        if (clock_e<=_MeasPeriodClock[i].second){
                            tmp1 = convertInstClockToDateTime( clock_s );
                            tmp2 = convertInstClockToDateTime( clock_e );
                            isFinish = true;
                        }else{
                            tmp1 = convertInstClockToDateTime( clock_s );
                            tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
                        }
                    }
                }else{
                    if (clock_e<=_MeasPeriodClock[i].second){
                        isFinish = true;
                        tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
                        tmp2 = convertInstClockToDateTime( clock_e );
                    }else{
                        tmp1 = convertInstClockToDateTime( _MeasPeriodClock[i].first );
                        tmp2 = convertInstClockToDateTime( _MeasPeriodClock[i].second );
                    }
                }
                for (UInt4 j=0; j< tmp1.size(); j++) ret.push_back( tmp1[j] );
                for (UInt4 j=0; j< tmp2.size(); j++) ret.push_back( tmp2[j] );
                if (isFinish) break;
            }
        }
    }
    //for (UInt4 j=0; j< tmp1.size(); j++) ret.push_back( tmp1[j] );
    //for (UInt4 j=0; j< tmp2.size(); j++) ret.push_back( tmp2[j] );
    //<--[inamura 160409]
    return ret;
    /*
    std::vector<Double> clock_region = putT0ClockRegion();
    std::vector<Double> ret;
    ret.clear();
    if (clock_region.size()==2){
        for (UInt4 i=0; i<2; i++){
            std::vector<Double> tmp = convertInstClockToDateTime( clock_region[i] );
            for (UInt4 j=0; j<tmp.size(); j++){
                ret.push_back( tmp[j] );
            }
        }
    }else{
        ret.push_back(-1.0);
    }

    return ret;
    */
}

//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
putSlicedT0IndexEvent( UInt8 start_posi, std::string path_to_file, UInt8 *count_to_last ){

    //UChar   buf0[BytesOfT0Event],buf1[BytesOfT0Event];
    UChar *buf0 = new UChar[BytesOfT0Event];
    UChar *buf1 = new UChar[BytesOfT0Event];

    FILE *fp;

    std::vector<UInt8> ret;

    if(NULL==(fp=fopen(path_to_file.c_str(),"rb"))){
        //std::printf("Can't open %s.\n",filename.c_str());
        std::cout << _MessageTag+"putSlicedT0IndexEvent >> Can't open " << path_to_file << "." << std::endl;
        return ret;
    }

    if (0!=fseek( fp, (long)(start_posi*BytesOfT0Event), SEEK_SET )){
        std::cout << _MessageTag+"putSlicedT0IndexEvent >> false to fseek " << std::endl;
        return ret;
    }

    UInt4 cnt=0;
    UInt4 flg=0;
    UInt8 num_events=0;
    Double dumm=0.0;
    bool isUsedLimit = false;
    UInt4 lastT0cnt = 0;

    if (*count_to_last!=0) isUsedLimit = true;

    for(;;){
        if (isUsedLimit){
            if (cnt==(*count_to_last)) flg=3;
        }
        //std::cout << "cnt,flg=" << cnt <<","<< flg << std::endl;
        if(flg==0){
            if (fread(buf0,BytesOfT0Event,1,fp)==1){
                cnt++;
            }else{
                flg=3;
            }
        }
        if (flg==3){
            break;
        }

        if (buf0[0]==0x4b){
            if (fread(buf1,BytesOfT0Event,1,fp)==1){
                cnt++;
                if (0x4c==buf1[0]){
                    flg=0;
                }else{
                    memcpy(buf0,buf1,8);
                    flg=1;
                }
            }else{
                flg=3;
            }
        }
        if ((buf0[0]==0x4a)||(buf0[0]==0x4f)){
            if (buf0[0]==0x4f)
                decodeT0InfoEvent(buf0,&num_events);
            else
                decodeT0InfoEvent(buf0,&num_events,&dumm);
            ret.push_back(num_events);
            lastT0cnt = cnt-1;
            if (fread(buf1,BytesOfT0Event,1,fp)==1){
                cnt++;
                if ((0x4d!=buf1[0])&&(0x4e!=buf1[0])){
                    memcpy(buf0,buf1,8);
                    flg=1;
                }
            }else{
                flg=3;
            }
        }
    }
    fclose(fp);
    if(buf0) delete [] buf0;
    if(buf1) delete [] buf1;
    *count_to_last = lastT0cnt;
    return ret;

}
//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
putSlicedT0IndexEventPy( UInt8 start_posi, std::string path_to_file){
    UInt8 cnt = 0;
    std::vector<UInt8> ret=putSlicedT0IndexEvent( start_posi, path_to_file, &cnt );
    std::cout << _MessageTag+"putSlicedT0IndexEventPy >> vect size=" << ret.size() << ", returned cnt=" << cnt << std::endl;
    return ret;
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
putSlicedT0EventInfo( UInt8 start_posi, std::vector<std::string> filenames, std::vector<UInt8>& retCountToLast, std::vector<UInt8>& retT0Index, std::vector<UInt8>& retPulseId, std::vector<Double>& retDiffClock, UInt8 lastPulseId ){

    UInt4 ind=0;
    for (UInt4 i=0; i<filenames.size(); i++){
        const boost::filesystem::path file_path( filenames[i].c_str() );
        const boost::uintmax_t size = boost::filesystem::file_size(file_path);
        if ( (start_posi*BytesOfT0Event)> (UInt4)size ){
            start_posi -= (UInt4)size/BytesOfT0Event;
            ind++;
        }else{
            break;
        }
    }

    std::vector<FILE*> fp_list( filenames.size() );
    for (UInt4 ii=0;ii<filenames.size();ii++){
        if(NULL==(fp_list[ii]=fopen(filenames[ii].c_str(),"rb"))){
            std::cout << _MessageTag+"putSlicedT0EventInfo >> Can't open " << filenames[ii] << "." << std::endl;
            return false;
        }
    }
    /*
    if (0!=fseek( fp_list[ind], start_posi*BytesOfT0Event, SEEK_SET )){
        std::cout << "T0TreatTools : false to fseek " << std::endl;
        return false;
    }
    */
    //UChar buf[BytesOfT0Event];
    UChar *buf= new UChar[BytesOfT0Event];
    bool isRead = true;
    is_ReliableClock = true;
    UInt4 cnt = 0;
    //UInt4 lastT0cnt = 0;
    UInt8 pid_add=0;
    UInt8 pid_start=lastPulseId;

    if ((pid_start==0)&&(!(retPulseId.empty()))) pid_start = retPulseId[retPulseId.size()-1];

    // Seek Event to Set Clock
    MeasClockSliced.first = CurrentClockSliced.first + CurrentClockSliced.second;
    MeasClockSliced.second = 0.0;
    if (CurrentClockSliced.first != 0.0){
        if (0!=fseek( fp_list[ind], (long)start_posi*(long)BytesOfT0Event, SEEK_SET )){
            std::cout << _MessageTag+"putSlicedT0EventInfo >> false to fseek " << std::endl;
            return false;
        }
    }else{ // This seek is first slice.
        UInt4 p_i = 0;
        Double clock_inc;
        CurrentClockSliced.second = 0.0;
        while( p_i<start_posi ){
            if (fread( buf, BytesOfT0Event, 1, fp_list[ind] )==1){
                p_i++;
                if (buf[0]==0x4c) {
                    decodeT0ClockEvent( buf, &(CurrentClockSliced.first));
                    CurrentClockSliced.second = 0;
                }
                if ((0x4d==buf[0])||(0x4e==buf[0])){
                    decodeClockIncEvent(buf,&clock_inc);
                    CurrentClockSliced.second += clock_inc;
                }
            }else{
                if (ind<fp_list.size()){
                    ind++;
                }else{
                    std::cout << _MessageTag+"putSlicedT0EventInfo >> false to fseek " << std::endl;
                    for (UInt4 j=0;j<fp_list.size();j++) fclose( fp_list[j] );
                    return false;
                }
            }
        }
        MeasClockSliced.first = CurrentClockSliced.first + CurrentClockSliced.second;
    }

    while(true){
        //if ((*count_to_last!=0)&&(cnt==(*count_to_last))) break;

        if (isRead){
            if (fread(buf, BytesOfT0Event, 1, fp_list[ind])==1) cnt++;
            else{
                if (ind==(fp_list.size()-1)) break;
                else{
                    ind++;
                    if (fread(buf,BytesOfT0Event,1,fp_list[ind])==1) cnt++;
                    else break;
                }
            }
        }

        if (buf[0]==0x4b){
            isRead = true;
            decodePidEvent( buf, &pid_start );
            pid_add=0;
            if (fread(buf, BytesOfT0Event, 1, fp_list[ind])==1) cnt++;
            else{
                if (ind==(fp_list.size()-1)) break;
                else{
                    ind++;
                    if (fread(buf,BytesOfT0Event,1,fp_list[ind])==1) cnt++;
                    else break;
                }
            }
            if (buf[0]==0x4b) isRead = false;
            if (buf[0]==0x4c){
                decodeT0ClockEvent( buf, &(CurrentClockSliced.first));
                CurrentClockSliced.second = 0.0;
            }
        }
        if ((buf[0]==0x4a)||(buf[0]==0x4f)){
            isRead = true;
            UInt8 num_events;
            Double clock_diff;
            if (buf[0]==0x4f)
                decodeT0InfoEvent(buf,&num_events);
            else
                decodeT0InfoEvent(buf,&num_events,&clock_diff);

            retT0Index.push_back(num_events);
            retPulseId.push_back(pid_start+pid_add);
            pid_add+=1;
            //lastT0cnt = cnt-1;
            retCountToLast.push_back( cnt-1 );

            if (fread(buf, BytesOfT0Event, 1, fp_list[ind])==1) cnt++;
            else {
                if (ind==(fp_list.size()-1)) break;
                else{
                    ind++;
                    if (fread(buf,BytesOfT0Event,1,fp_list[ind])==1) cnt++;
                    else break;
                }
            }
            if ((0x4d==buf[0])||(0x4e==buf[0])){
                Double clock_inc;
                decodeClockIncEvent(buf,&clock_inc);
                retDiffClock.push_back( clock_inc );
                CurrentClockSliced.second += clock_inc;
                isRead = true;
            }else{
                retDiffClock.push_back(clock_diff);
                isRead = false;
                is_ReliableClock = false;
            }

        }
    }
    std::vector<FILE*>::iterator it=fp_list.begin();
    while( it!=fp_list.end() ){
        fclose( *it );
        it++;
    }
    if(buf) delete [] buf;
    MeasClockSliced.second = CurrentClockSliced.first + CurrentClockSliced.second;
    //*count_to_last = lastT0cnt;
    return true;
}
//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
putSlicedT0EventInfoPy1( UInt8 start_posi, std::vector<std::string> filenames ){
    std::vector<UInt8> cnt;
    std::vector<UInt8> ret;
    std::vector<UInt8> dum1;
    std::vector<Double> dum2;
    putSlicedT0EventInfo( start_posi, filenames, cnt, ret, dum1, dum2 );
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
putSlicedT0EventInfoPy2( UInt8 start_posi, std::vector<std::string> filenames, UInt8 start_pid ){
    std::vector<UInt8> cnt;
    std::vector<UInt8> dum1;
    std::vector<UInt8> ret;
    std::vector<Double> dum2;
    putSlicedT0EventInfo( start_posi, filenames, cnt, dum1, ret, dum2, start_pid );
    return ret;
}
//////////////////////////////////////////////////////////
void T0TreatToolsBase::dumpMeasPeriodClock(){
    std::cout << "----------------------------" << std::endl;
    for (UInt4 i=0; i<_MeasPeriodClock.size(); i++){
        std::cout << "----------------------------" << std::endl;
        std::cout << "i=" << i << std::endl;
        std::cout << "   start clock = " << _MeasPeriodClock[i].first << std::endl;
        std::cout << "    end  clock = " << _MeasPeriodClock[i].second << std::endl;
    }
}
//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
PutT0Index()
{
    std::vector<UInt8> invalid_ret;
    if (_RangeSingleTimeSlice.empty()){
        return putVectorT0Index();
    }else{
        if (_RangeSingleTimeSlice[0]==0){
            return putVectorT0IndexBySec( _RangeSingleTimeSlice[1], _RangeSingleTimeSlice[2] );
        }else{
            std::vector<Double> measClockRegion = putT0ClockRegion(); // [JST]
            if (measClockRegion.size()!=2){
                invalid_ret.push_back(-1);
                return invalid_ret;
            }
            Double startSec=_RangeSingleTimeSlice[1] -  measClockRegion[0];
            Double endSec  =_RangeSingleTimeSlice[2] -  measClockRegion[0];

            return putVectorT0IndexBySec( startSec,endSec );
        }
    }
}
//////////////////////////////////////////////////////////
std::vector<UInt8> T0TreatToolsBase::
PutPulseId()
{
    std::vector<UInt8> invalid_ret;
    if (_RangeSingleTimeSlice.empty()){
        return putVectorPulseId();
    }else{
        if (_RangeSingleTimeSlice[0]==0){
            return putVectorPulseIdBySec( _RangeSingleTimeSlice[1], _RangeSingleTimeSlice[2] );
        }else{
            std::vector<Double> measClockRegion = putT0ClockRegion(); // [JST]
            if (measClockRegion.size()!=2){
                invalid_ret.push_back(-1);
                return invalid_ret;
            }
            Double startSec=_RangeSingleTimeSlice[1] -  measClockRegion[0];
            Double endSec  =_RangeSingleTimeSlice[2] -  measClockRegion[0];

            return putVectorPulseIdBySec( startSec,endSec );
        }
    }
}
//////////////////////////////////////////////////////////
std::vector<Double> T0TreatToolsBase::
putT0SecVector(){
    if (t0Sec_ext.empty()) return t0Sec_n;
    else return t0Sec_ext;
}
//////////////////////////////////////////////////////////
std::vector<Double> T0TreatToolsBase::
PutT0ClockDiff()
{
    if (_RangeSingleTimeSlice.empty()){
        return putT0ClockDiffAll();
    }else if (( _RangeSingleTimeSlice[1]<0.0)&&(_RangeSingleTimeSlice[2]<0.0)){
        return putT0ClockDiffAll();
    }else{
        return putT0ClockDiff();
    }
}
//////////////////////////////////////////////////////////
std::vector<Double> T0TreatToolsBase::
PutT0Clock()
{
    if (_RangeSingleTimeSlice.empty()){
        if (t0Time_ext.empty()) return t0Time_n;
        else return t0Time_ext;
    }else if (( _RangeSingleTimeSlice[1]<0.0)&&(_RangeSingleTimeSlice[2]<0.0)){
        if (t0Time_ext.empty()) return t0Time_n;
        else return t0Time_ext;
    }else{
        if (t0Time_tmp.empty()){
            //throw "Exception: There is no clock data to be imported.";
            std::cout << _MessageTag+"PutT0Clock >> There is no clock data." << std::endl;
            std::vector<Double> ret(1,0.0);
            return ret;
        }
        return t0Time_tmp;
    }
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
SetRangeOfSingleTimeSlicing( double startSec, double endSec )
{
    _RangeSingleTimeSlice.clear();
    _RangeSingleTimeSlice.push_back(0);
    _RangeSingleTimeSlice.push_back( startSec );
    _RangeSingleTimeSlice.push_back( endSec );
    return true;
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
SetRangeOfSingleTimeSlicing( std::string startDate, std::string endDate )
{
    StringTools stools;
    Double startClock = -1.0;
    Double endClock = -1.0;
    std::vector<std::string> startDate_v = stools.SplitString( startDate, "," );
    std::vector<std::string> endDate_v = stools.SplitString( endDate, "," );
    if ((startDate_v.size()==1)&&((stools.StringToDouble( startDate_v[0] ))<0.0)){
    }else{
        if (startDate_v.size()!=7) return false;
        std::vector<Double> startDate_dv(7,0.0);
        for (UInt4 i=0; i<7; i++) startDate_dv[i]=stools.StringToDouble( startDate_v[i] );
        startClock = convertDateTimeToInstClock( startDate_dv ); //[JST]
        if (startClock<0.0) return false;
    }
    if ((endDate_v.size()==1)&&((stools.StringToDouble( endDate_v[0] ))<0.0)){
    }else{
        if (endDate_v.size()!=7) return false;
        std::vector<Double> endDate_dv(7,0.0);
        for (UInt4 i=0; i<7; i++) endDate_dv[i]=stools.StringToDouble( endDate_v[i] );
        endClock = convertDateTimeToInstClock( endDate_dv ); //[JST]
        if (endClock<0.0) return false;
    }
    /*
    std::vector<std::string> startDate_v = stools.SplitString( startDate, "," );
    std::vector<std::string> endDate_v = stools.SplitString( endDate, "," );
    if ((startDate_v.size()!=7)||(endDate_v.size()!=7)){
        return false;
    }
    std::vector<Double> startDate_dv,endDate_dv;
    for (UInt4 i=0;i<7;i++){
        startDate_dv.push_back( stools.StringToDouble( startDate_v[i] ) );
        endDate_dv.push_back( stools.StringToDouble( endDate_v[i] ) );
    }
    Double startClock = convertDateTimeToInstClock( startDate_dv ); //[JST]
    Double endClock = convertDateTimeToInstClock( endDate_dv );     //[JST]
    */
    _RangeSingleTimeSlice.clear();
    _RangeSingleTimeSlice.push_back(1);
    _RangeSingleTimeSlice.push_back( startClock );
    _RangeSingleTimeSlice.push_back( endClock );

    return true;
}

//////////////////////////////////////////////////////////
void T0TreatToolsBase::
SetExternalClockInfo( std::vector<Double> _t0Time, bool _isReliable ){
    t0Time_ext.clear();
    t0Sec_ext.clear();
    t0Time_diff_ext.clear();

    UInt4 _size = (UInt4)(_t0Time.size());
    t0Time_ext.resize( _size, 0.0 );
    t0Sec_ext.resize( _size, 0.0 );
    t0Time_diff_ext.resize( _size, 0.0 );

    copy( _t0Time.begin(), _t0Time.end(), t0Time_ext.begin() );
    for (UInt4 i=0; i<_size; i++)
        t0Sec_ext[i] = _t0Time[i] - _t0Time[0];
    for (UInt4 i=0; i<(_size-1); i++)
        t0Time_diff_ext[i+1] = _t0Time[i+1] - _t0Time[i];

    is_ReliableClock = _isReliable;

    return;

}
//////////////////////////////////////////////////////////
void T0TreatToolsBase::
ClearExternalClockInfo(){
    t0Time_ext.clear();
    t0Sec_ext.clear();
    t0Time_diff_ext.clear();
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
PutSlicedOrgEventBySec( std::vector<std::string> orgfiles, double start_sec, double end_sec, std::string filepath, std::vector<double> extTime ){
    // SIK001234_00_000_000.edb
    UInt4 ret=0;
    bool isEdbFile=true;
    std::vector<std::string> edbfiles;
    std::vector<std::string> t0bfiles;
    for (UInt4 i=0; i<orgfiles.size(); i++){
        if (orgfiles[i].find(".edb")==(orgfiles[i].size()-4))
            edbfiles.push_back( orgfiles[i] );
        else if (orgfiles[0].find(".t0b")==(orgfiles[0].size()-4))
            t0bfiles.push_back( orgfiles[i] );
    }

    if (edbfiles.empty()){
        return false;
    }

    if (t0bfiles.empty())
        ret = readOrgEvent( edbfiles );
    else
        ret = readT0IndexEvent( t0bfiles );

    for (UInt4 i=0; i<orgfiles.size(); i++){
        std::cout << "EDB file=" << edbfiles[i] << std::endl;
    }

    std::vector<FILE*> fp_list( edbfiles.size() );
    for (UInt4 ii=0;ii<edbfiles.size();ii++){
        if(NULL==(fp_list[ii]=fopen(edbfiles[ii].c_str(),"rb"))){
            std::cout << _MessageTag+"readT0IndexEvent >> Can't open " << edbfiles[ii] << "." << std::endl;
            return false;
        }
    }

    std::cout << "----- Step 1" << std::endl;
    if (!(extTime.empty()))
        SetExternalClockInfo( extTime );

    std::vector<UInt8> tmp = putVectorT0IndexBySec(start_sec, end_sec);

    std::cout << "----- Step 2" << std::endl;
    FILE* fo = fopen( filepath.c_str(), "wb" );
    if (fo==NULL){
        return false;
    }

    UInt4 file_index = 0;

    for (UInt4 i=0;i<(tmp.size()-1);i++){
        UInt4 read_bytes = (UInt4)(tmp[i+1]-tmp[i]);
        UChar *buf0 = new UChar[BytesOfT0Event*read_bytes];
        UInt4 i0=(UInt4)(fread(buf0,BytesOfT0Event,read_bytes,fp_list[file_index]));
        if (i0!=read_bytes){
            if (file_index==(fp_list.size()-1)) break;
            else{
                file_index++;
                UChar *buf1 = new UChar[BytesOfT0Event*(read_bytes-i0)];
                UInt4 i1=(UInt4)(fread(buf1,BytesOfT0Event, (read_bytes-i0), fp_list[file_index]));
                if (i1!=(read_bytes-i)) break;
                for (UInt4 j=0;j<(read_bytes-i0);j++)
                    buf0[i+j] = buf1[j];
                delete [] buf1;
            }
        }

        std::fwrite(buf0,1,BytesOfT0Event*read_bytes,fo);

        delete [] buf0;
    }

    fclose(fo);
    std::vector<FILE*>::iterator it=fp_list.begin();
    while( it!=fp_list.end() ){
        fclose( *it );
        it++;
    }
    return true;
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
PutSlicedOrgEventByKicker( std::vector<std::string> orgfiles, UInt4 start_kick, UInt4 end_kick, std::string outfile ){
    if (start_kick>end_kick){
        std::cerr << "T0TreatToolsBase::PutSlicedOrgEventByKicker >> Invalid kicker arguments" << std::endl;
        return false;
    }

    UInt4 ret=0;
    bool isEdbFile=true;
    std::vector<std::string> edbfiles;
    std::vector<std::string> t0bfiles;
    for (UInt4 i=0; i<orgfiles.size(); i++){
        if (orgfiles[i].find(".edb")==(orgfiles[i].size()-4))
            edbfiles.push_back( orgfiles[i] );
        else if (orgfiles[0].find(".t0b")==(orgfiles[0].size()-4))
            t0bfiles.push_back( orgfiles[i] );
    }

    if (edbfiles.empty()){
        return false;
    }

    if (t0bfiles.empty())
        ret = readOrgEvent( edbfiles );
    else
        ret = readT0IndexEvent( t0bfiles );
    if (t0Index_n.size()<=(end_kick+2)){
        std::cerr << "T0TreatToolsBase::PutSlicedOrgEventByKicker >> given kicker is too large against data" << std::endl;
        return false;
    }

    for (UInt4 i=0; i<orgfiles.size(); i++){
        std::cout << "EDB file=" << edbfiles[i] << std::endl;
    }

    std::vector<FILE*> fp_list( edbfiles.size() );
    for (UInt4 ii=0;ii<edbfiles.size();ii++){
        if(NULL==(fp_list[ii]=fopen(edbfiles[ii].c_str(),"rb"))){
            std::cout << _MessageTag+"readT0IndexEvent >> Can't open " << edbfiles[ii] << "." << std::endl;
            return false;
        }
    }

    FILE* fo = fopen( outfile.c_str(), "wb" );
    if (fo==NULL){
        return false;
    }


    UInt4 file_index = 0;

    UInt4 read_bytes = (UInt4)(t0Index_n[ end_kick+2 ] - t0Index_n[ start_kick ]);
    std::vector<UInt8> tmp( end_kick+2 - start_kick );
    copy( t0Index_n.begin()+start_kick, t0Index_n.begin()+end_kick+2, tmp.begin() );

    UChar *buf_tmp = new UChar[BytesOfT0Event*tmp[0]];
    UInt8 read_bytes_tmp = tmp[0];
    while(true){
        UInt4 i_tmp = (UInt4)( fread(buf_tmp,BytesOfT0Event,read_bytes_tmp,fp_list[file_index]) );
        if (i_tmp==read_bytes_tmp) break;
        read_bytes_tmp -= i_tmp;
        file_index ++;
        if (file_index==fp_list.size()) return false;
    }

    for (UInt4 i=0;i<(tmp.size()-1);i++){
        UInt4 read_bytes = (UInt4)(tmp[i+1]-tmp[i]);
        UChar *buf0 = new UChar[BytesOfT0Event*read_bytes];
        UInt4 i0=(UInt4)( fread(buf0,BytesOfT0Event,read_bytes,fp_list[file_index]) );
        if (i0!=read_bytes){
            if (file_index==(fp_list.size()-1)) break;
            else{
                file_index++;
                UChar *buf1 = new UChar[BytesOfT0Event*(read_bytes-i0)];
                UInt4 i1=(UInt4)( fread(buf1,BytesOfT0Event, (read_bytes-i0), fp_list[file_index]) );
                if (i1!=(read_bytes-i)) break;
                for (UInt4 j=0;j<(read_bytes-i0);j++)
                    buf0[i+j] = buf1[j];
                delete [] buf1;
            }
        }

        std::fwrite(buf0,1,BytesOfT0Event*read_bytes,fo);

        delete [] buf0;
    }

    fclose(fo);
    std::vector<FILE*>::iterator it=fp_list.begin();
    while( it!=fp_list.end() ){
        fclose( *it );
        it++;
    }
    return true;
}
//////////////////////////////////////////////////////////
void T0TreatToolsBase::
DumpInfo(std::string filepath){
    std::vector<std::string> fv;
    if (filepath != "")
        fv.push_back(filepath);
    else{
        std::cout << _MessageTag + "DumpInfo(str):: Error >> given argument is empty." << std::endl;
        return;
    }
    DumpInfo(fv);
}
//////////////////////////////////////////////////////////
void T0TreatToolsBase::
DumpInfo(std::vector<std::string> filepaths){
    if (filepaths.empty()){
        std::cout <<_MessageTag + "DumpInfo(<vector>):: Error >> given file vector is empty." << std::endl;
        return;
    }else{
        UInt4 l = filepaths[0].size();
        std::string ext = filepaths[0].substr((l - 4), 4);
        if (ext == ".edb"){
            if (readOrgEvent(filepaths) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given file paths." << std::endl;
            }
        }else if (ext == ".t0b"){
            if (readT0IndexEvent(filepaths) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given file paths." << std::endl;
            }
        }
    }

    std::vector<double> mt = putMeasPeriodFromT0();
    if ((mt.size() % 14) != 0){
        return;
    }
    for (UInt4 i; i < mt.size(); i += 14){
        std::cout << "----------------------" << std::endl;
        std::cout << "Start : " << mt[i + 0] << "/" << mt[i + 1] << "/" << mt[i + 2] << " " << mt[i + 3] << ":" << mt[i + 4] << ":" << mt[i + 5] << "." << mt[i + 6];
        std::cout << std::endl;
        std::cout << "Stop  : " << mt[i + 7] << "/" << mt[i + 8] << "/" << mt[i + 9] << " " << mt[i + 10] << ":" << mt[i + 11] << ":" << mt[i + 12] << "." << mt[i + 13];
        std::cout << std::endl;
    }

    std::cout << "----------------------" << std::endl;
    std::cout << "Pulse ID Check" << std::endl;
    std::vector<UInt8> tiv = PutPulseId();
    if (tiv.empty()){
        return;
    }
    std::cout << "  Total number = " << tiv.size() << std::endl;
    std::cout << "  Range and the number = " << tiv[0] << " - " << tiv.back() << std::endl;
    UInt8 ti = tiv[0];
    bool isOk = true;
    for (UInt4 i=1; i<tiv.size(); i++){
        if (tiv[i] != (ti + 1)){
            std::cout << _MessageTag + "ERROR : Lack of T0 Index " << ti + 1 << std::endl;
            isOk = false;
        }
        ti = tiv[i];
    }
    if (isOk){
        std::cout << "  The sequence is OK" << std::endl;
    }

    return;
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
CheckSequencePulseId(std::string filepath){
    if (filepath != ""){
        std::vector<std::string> files;
        files.push_back(filepath);
        UInt4 l = files[0].size();
        std::string ext = files[0].substr((l - 4), 4);
        if (ext == ".edb"){
            if (readOrgEvent(files) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given edb file paths." << std::endl;
            }
        }else if (ext == ".t0b"){
            if (readT0IndexEvent(files) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given t0b file paths." << std::endl;
            }
        }
    }

    std::vector<UInt8> tiv = PutPulseId();
    if (tiv.empty()){
        std::cout << _MessageTag + "Error >> PulseId is empty." << std::endl;
        return false;
    }
    std::cout << "  Total number = " << tiv.size() << std::endl;
    std::cout << "  Range and the number = " << tiv[0] << " - " << tiv.back() << std::endl;
    UInt8 ti = tiv[0];
    bool isOk = true;
    for (UInt4 i=1; i<tiv.size(); i++){
        if (tiv[i] != (ti + 1)){
            std::cout << _MessageTag + "ERROR : Lack of T0 Index " << ti + 1 << std::endl;
            isOk = false;
            break;
        }
        ti = tiv[i];
    }
    return isOk;
}
//////////////////////////////////////////////////////////
bool T0TreatToolsBase::
CheckSequencePulseId2(std::string filepath, std::vector<UInt4>* ret_pid, std::vector<double>* ret_clock){
    if (filepath != ""){
        std::vector<std::string> files;
        files.push_back(filepath);
        UInt4 l = files[0].size();
        std::string ext = files[0].substr((l - 4), 4);
        if (ext == ".edb"){
            if (readOrgEvent(files) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given edb file paths." << std::endl;
            }
        }else if (ext == ".t0b"){
            if (readT0IndexEvent(files) == 0){
            }else{
                std::cout << _MessageTag + "Error >> Failed to read given t0b file paths." << std::endl;
            }
        }
    }

    std::vector<UInt8> tiv = PutPulseId();
    std::vector<Double> clv = PutT0Clock();
    if (tiv.empty()){
        std::cout << _MessageTag + "Error >> PulseId is empty." << std::endl;
        return false;
    }
    if (tiv.size() != clv.size()){
        std::cout << _MessageTag + "Error >> The numbers are different between PulseId and Clock." << std::endl;
        return false;
    }
    std::cout << "  Total number = " << tiv.size() << std::endl;
    std::cout << "  Range and the number = " << tiv[0] << " - " << tiv.back() << std::endl;
    UInt8 ti = tiv[0];
    bool isOk = true;
    ret_pid->clear();
    ret_clock->clear();
    for (UInt4 i=1; i<tiv.size(); i++){
        if (tiv[i] != (ti + 1)){
            std::cout << _MessageTag + "ERROR : Lack of T0 Index " << ti + 1 << std::endl;
            isOk = false;
	    ret_pid->push_back((UInt4)tiv[i]);
	    ret_clock->push_back(clv[i]);
        }
        ti = tiv[i];
    }
    return isOk;
}
