#include "UtsusemiEventDataConverterNeunet2QEvent.hh"
//////////////////////////////////////////////////////////
UtsusemiEventDataConverterNeunet2QEvent::
UtsusemiEventDataConverterNeunet2QEvent(){
    Initialize2QEvent();
}

//////////////////////////////////////////////////////////
UtsusemiEventDataConverterNeunet2QEvent::
~UtsusemiEventDataConverterNeunet2QEvent(){
    delete stools;
    delete _uuc;
}

//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterNeunet2QEvent::
Initialize2QEvent(){
    _Ei= 0.0;
    _hw_min = 0.0;
    _hw_max = 0.0;
    _L1 = 0.0;
    stools = new StringTools();
    _uuc = new UtsusemiUnitConverter();
    _PM.clear();
    _outputPath="";
    _withWeightOutput = true;
    _withT0EventMark = true;
    _MaskList = NULL;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterNeunet2QEvent::
SetEi( Double Ei, Double hw_min, Double hw_max, Double l1 ){
    _Ei = Ei;
    _hw_min = hw_min;
    _hw_max = hw_max;
    if (_hw_max>=_Ei) _hw_max = _Ei*0.99;
    _L1 = l1;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
SetOutputPath( string _Path ){
    _outputPath = _Path;
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
SetXtalParamFile( string _xtalParamPath, string rotateStep ){
    string err_msg = "";
    UtsusemiSqeCalcXtalParams* _xp = new UtsusemiSqeCalcXtalParams();
    if (_xp->LoadFile(_xtalParamPath)){
        //_xp->Dump();
        vector<string> tmp = stools->SplitString(rotateStep,",");
        for (UInt4 i=0; i<tmp.size(); i++){
	    vector<string> tmp2 = stools->SplitString(tmp[i],":");
	    if (tmp2.size()==2){
	        string axis = tmp2[0];
	        transform(axis.begin(), axis.end(), axis.begin(), ::toupper);
	        if ((axis=="X")||(axis=="Y")||(axis=="Z")){
	            _xp->AddRotationStep( axis, stools->StringToDouble(tmp2[1]) );
	        }
	    }
        }
	//_xp->Dump();
        vector<Double> LC = _xp->PutLatticeConsts();
        vector<Double> UV = _xp->PutUVector();
        vector<Double> VV = _xp->PutVVector();
        vector<Double> RS = _xp->PutRotateSteps();
        vector<Double> VA = _xp->PutViewAxes();
        UtsusemiSqeCalc* VCS = new UtsusemiSqeCalc();
        _PM = VCS->MakeProjectionMatrix( LC, UV, VV, RS, VA );
        delete VCS;
        if (_PM.size()!=16) err_msg = "UtsusemiEventDataConverterNeunet2QEvent::SetXtalParamFile : Failed to make conversion matrix";
    }else{
        err_msg = "UtsusemiEventDataConverterNeunet2QEvent::SetXtalParamFile : Failed to read file="+_xtalParamPath;
    }

    delete _xp;
    
    if (err_msg=="") return true;

    UtsusemiError( err_msg );
    return false;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
LoadParamFiles( string w_file, string d_file, string c_file ){
    if (SetEventParams( w_file, d_file )){
    }else{
        UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::SetXtalParamFile : Failed to read wfile or dfile." );
        return false;
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
SetTextMaskInfo( string maskfile ){
    if (_MaskList==NULL) _MaskList = new vector< vector< vector<Double>* >* >;
    UtsusemiSetMask MM;
    if (MM.ReadFile( maskfile ))
        return MM.PutListOfTxtMask( _MaskList );

    return false;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
DumpEventToText( string evtfile, string txtfile ){
    FILE *fp, *fo;
    if (NULL==(fp=fopen( evtfile.c_str(),"rb"))){
        UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::DumpEventToText >> Failed to open file :"+evtfile );
        return false;
    }
    if (NULL==(fo=fopen( txtfile.c_str(),"w"))){
        UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::DumpEventToText >> Failed to save file :"+evtfile );
        fclose(fp);
        return false;
    }
    
    float data[5];
    float q1,q2,q3,hw,ww;

    UInt4 c=0;
    if (_withWeightOutput){
        while((fread( data, sizeof(float),5,fp))==5){
            q1 = data[0];
            q2 = data[1];
            q3 = data[2];
            hw = data[3];
            ww = data[4];
            c++;
            fprintf( fo, "%g, %g, %g, %g, %g\n",q1,q2,q3,hw,ww );
        }
    }else{
        while((fread( data, sizeof(float),4,fp))==4){
            q1 = data[0];
            q2 = data[1];
            q3 = data[2];
            hw = data[3];
            ww = -1.0;
            c++;
            fprintf( fo, "%g, %g, %g, %g, %g\n",q1,q2,q3,hw,ww );
        }
    }
    fclose(fp);
    fclose(fo);
    cout << " counts= " <<c << endl;
    return true;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterNeunet2QEvent::
EventTransform( UInt4 daqId, UInt4 moduleNo, const UChar* data, UInt4 size,  vector<Double>* Offset, vector<UInt4>* Case, vector<Double>* retVals ){
    UInt4 index = 0;
    UInt4 pixelId = 0;
    Double tof = 0.0;
    UInt4 caseId = 0;
    UInt4 histId = 0;
    UInt4 ret = 0;
    Double dS = (25.4*19.05)/(2500.0*2500.0);
    UInt4 detId = 0;
    UInt4 pixNo = 0;
    for (UInt4 i=0; i<size; i++){
        index = i*_eventSize;
        
        ret = _EventDecoder->DecodeEventData( daqId, moduleNo, (data+index), &pixelId, &tof, Offset, 0 );
        if (_MaskList!=NULL)
            if (_EventDecoder->PutDetIdPixNoFromEvent( daqId, moduleNo, (data+index), &detId, &pixNo, 0))
                if ( detId<(_MaskList->size()) )
                    if ( _MaskList->at(detId)!=NULL )
                        if ( pixNo<(_MaskList->at(detId)->size() ) )
                            if ( _MaskList->at(detId)->at(pixNo)!=NULL ) continue;
        
        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){
                Double px = _EventDecoder->_pixelPositionVect[ pixelId ]->at(0);
                Double py = _EventDecoder->_pixelPositionVect[ pixelId ]->at(1);
                Double pz = _EventDecoder->_pixelPositionVect[ pixelId ]->at(2);
                Double L2 = sqrt( px*px + py*py + pz*pz );
                Double tof_at_sample = (_L1/1000.0)/(_uuc->EtoV(_Ei));
                Double tof_at_hw_min = tof_at_sample + (L2/1000.0)/(_uuc->EtoV(_Ei-_hw_min));
                Double tof_at_hw_max = tof_at_sample + (L2/1000.0)/(_uuc->EtoV(_Ei-_hw_max));
                if ((tof>tof_at_hw_min)&&(tof<=tof_at_hw_max)){
                    Double Ef = _uuc->VtoE( (L2/1000.0)/(tof-tof_at_sample) );
                    Double hw = _Ei-Ef;
                    Double ki = sqrt( _uuc->EtoK2( _Ei ) );
                    Double kf = sqrt( _uuc->EtoK2( Ef ) );
                    Double ki_over_kf = sqrt(_Ei/Ef); //ki/kf;
                    Double qx = -kf*(px/L2);
                    Double qy = -kf*(py/L2);
                    Double qz = ki-kf*(pz/L2);
                    
                    Double q1 = qz*_PM[0] + qx*_PM[1] + qy*_PM[2] + hw*_PM[3];
                    Double q2 = qz*_PM[4] + qx*_PM[5] + qy*_PM[6] + hw*_PM[7];
                    Double q3 = qz*_PM[8] + qx*_PM[9] + qy*_PM[10] + hw*_PM[11];
                    Double q4 = qz*_PM[12] + qx*_PM[13] + qy*_PM[14] + hw*_PM[15];
                    //Double weight = ki_over_kf/(_EventDecoder->_pixelSolidAngleVect[ pixelId ])*dS;
                    Double weight = ki_over_kf*dS/(_EventDecoder->_pixelSolidAngleVect[ pixelId ]);
                    
                    retVals->push_back( q1 );
                    retVals->push_back( q2 );
                    retVals->push_back( q3 );
                    retVals->push_back( q4 );
                    retVals->push_back( weight );
                    /*
                    if (i<5){
                        cout << "-----------------------------------" << endl;
                        cout << "Ts = " << tof_at_sample << endl;
                        cout << "Te = " << tof_at_hw_max << endl;
                    }

                    if (i<5){
                        cout << "-----------------------------------" << endl;
                        cout << "L1 = " << _L1 << " / L2 = " << L2 << endl;
                        cout << "Ts = " << tof_at_sample << endl;
                        cout << "tof= " << tof << endl;
                        cout << "hw = " << hw << endl;
                        cout << "ki = " << ki << " / kf = " << kf << endl;
                        cout << " q = " << qx << "," << qy << "," << qz << endl;
                    }
                    */
                }
            }else{
                //cout << "caseId=" << caseId << endl;
            }
            
            
        }else if (_EventDecoder->IsT0Event(ret)){
            if (_withT0EventMark){
                retVals->push_back( 0.0 );
                retVals->push_back( 0.0 );
                retVals->push_back( 0.0 );
                retVals->push_back( 0.0 );
                retVals->push_back( 0.0 );
            }
            //cout << "ret=" << ret << endl;
        }
    }
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterNeunet2QEvent::
PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, vector<UInt8> T0Table, vector<Double> ClockTable, vector<vector<UInt4>*> *CaseTable ){
    UInt8 size = T0Table[ T0Table.size()-1 ];
    UInt4 TableSize = T0Table.size();
    UInt4 num_of_preClocks = ClockTable.size()-TableSize;
    UChar *CopyData = new UChar [ size * _eventSize ];
    bool isUseCases = true;
    if (CaseTable->empty()) isUseCases=false;
    
    for( UInt4 i=0; i<size*_eventSize; i++ ){
        CopyData[i] = data[i];
    }

    Char fname_c[200];
    sprintf( fname_c, "%s/%s%06d_%02d_%03d.evt", _outputPath.c_str(),_instCode.c_str(),_runNumber,daqId,moduleNo );
    string fname_s(fname_c);
    FILE *fout;
    float out_data[5]={0.0,0.0,0.0,0.0,0.0};
    if (NULL==(fout=fopen( fname_s.c_str(),"ab"))){
        UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to open output file :"+fname_s );
        return;
    }
    
    vector<double> retVals;
    UChar *T0event4 = new UChar[16];
    UChar *T0event5 = new UChar[20];
    for (UInt4 i=0; i<16; i++) T0event4[i]=0xff;
    for (UInt4 i=0; i<20; i++) T0event5[i]=0xff;
    for( UInt4 i=0; i<TableSize-1; i++ ){
        retVals.clear();
        UInt4 Ini = T0Table[i];
        UInt8 DataSize = T0Table[i+1]-T0Table[i];
        vector<Double>* Clock = new vector<Double>(_numOfAdditionalClocks,0.0);
        if (i==0){
            if (num_of_preClocks>0) (*Clock)[1]=ClockTable[num_of_preClocks-1];
            (*Clock)[2]=ClockTable[0+num_of_preClocks]+(*Clock)[1];
        }else if (i==1){
            (*Clock)[1]=ClockTable[1+num_of_preClocks];
            (*Clock)[2]=ClockTable[0+num_of_preClocks]+(*Clock)[1];
        }else{
            (*Clock)[1]=ClockTable[i+num_of_preClocks];
            (*Clock)[2]=ClockTable[i+num_of_preClocks-1]+(*Clock)[1];
        }
        
        vector<UInt4>* Case = NULL;
        if (isUseCases) {
            Case = CaseTable->at(i); 
        }
        
        try{
            EventTransform( daqId, moduleNo, CopyData+(Ini*_eventSize), DataSize, Clock, Case, &retVals );

            if (_withWeightOutput){
                for (UInt4 j=0;j<retVals.size();j+=5){
                    out_data[0] = float(retVals[j+0]);
                    out_data[1] = float(retVals[j+1]);
                    out_data[2] = float(retVals[j+2]);
                    out_data[3] = float(retVals[j+3]);
                    out_data[4] = float(retVals[j+4]);
		    if ((out_data[0]==0)&&(out_data[1]==0)&&(out_data[2]==0)&&(out_data[3]==0)&&(out_data[4]==0)){
		        if ((int)fwrite( T0event5,20,1, fout )!=1){
			    UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write T0 events" );
			    break;
		        }
		    }else{
                        if ((int)fwrite( out_data, sizeof(float), 5, fout ) !=5){
                            UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write events" );
                            break;
                        }
		    }
                }
            }else{
                for (UInt4 j=0;j<retVals.size();j+=5){
                    out_data[0] = float(retVals[j+0]);
                    out_data[1] = float(retVals[j+1]);
                    out_data[2] = float(retVals[j+2]);
                    out_data[3] = float(retVals[j+3]);
		    if ((out_data[0]==0)&&(out_data[1]==0)&&(out_data[2]==0)&&(out_data[3]==0)){
		        if ((int)fwrite( T0event4,16,1, fout )!=1){
			    UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write T0 events" );
			    break;
		        }
		    }else{
		        if ((int)fwrite( out_data, sizeof(float), 4, fout ) !=4){
                            UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write Q events" );
                            break;
			}
                    }
                }
            }
        }
        catch(...){
            UtsusemiError( _MessageTag+"PreIncrement >> Increment Error;" );
        }
        delete Clock;
    }

    if(T0event4) delete [] T0event4;
    if(T0event5) delete [] T0event5;
    delete [] CopyData;
    fclose( fout );
}

//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterNeunet2QEvent::
PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, vector<UInt8> T0Table ){
    UInt4 TableSize = T0Table.size();
    UInt8 size = T0Table[ TableSize-1 ];
    UChar *CopyData = new UChar [ size * _eventSize ];
    
    for( UInt4 i=0; i<size*_eventSize; i++ ){
        CopyData[i] = data[i];
    }

    Char fname_c[200];
    sprintf( fname_c, "%s/%s%06d_%02d_%03d.evt", _outputPath.c_str(),_instCode.c_str(),_runNumber,daqId,moduleNo );
    string fname_s(fname_c);
    FILE *fout;
    float out_data[5];
    if (NULL==(fout=fopen( fname_s.c_str(),"ab"))){
        UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to open output file :"+fname_s );
        return;
    }
    
    vector<Double> retVals;
    for( UInt4 i=0; i<TableSize-1; i++ ){
        retVals.clear();
        UInt4 Ini = T0Table[i];
        UInt8 DataSize = T0Table[i+1]-T0Table[i];
        vector<Double>* Clock = new vector<Double>(_numOfAdditionalClocks,0.0);
        vector<UInt4>* Case = NULL;
        
        try{
            EventTransform( daqId, moduleNo, CopyData+(Ini*_eventSize), DataSize, Clock, Case, &retVals );
            if (_withWeightOutput){
                for (UInt4 j=0;j<retVals.size();j+=5){
                    out_data[0] = float(retVals[j+0]);
                    out_data[1] = float(retVals[j+1]);
                    out_data[2] = float(retVals[j+2]);
                    out_data[3] = float(retVals[j+3]);
                    out_data[4] = float(retVals[j+4]);
                    if ((int)fwrite( out_data, sizeof(out_data), 1, fout ) !=1){
                        UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write events" );
                        break;
                    }
                }
            }else{
                for (UInt4 j=0;j<retVals.size();j+=5){
                    out_data[0] = float(retVals[j+0]);
                    out_data[1] = float(retVals[j+1]);
                    out_data[2] = float(retVals[j+2]);
                    out_data[3] = float(retVals[j+3]);
                    if ((int)fwrite( out_data, sizeof(float), 4, fout ) !=4){
                        UtsusemiError("UtsusemiEventDataConverterNeunet2QEvent::PreIncrement >> Failed to write events" );
                        break;
                    }
                }
            }
        }
        catch(...){
            UtsusemiError( _MessageTag+"PreIncrement >> Increment Error;" );
        }
        delete Clock;
        
    }

  delete [] CopyData;
  fclose( fout );
  //cout << "fin PreIncrement" << endl;
}

//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterNeunet2QEvent::
ConvertEventDataFiles(UInt4 runNumber, string pathToData, string pathToT0data){
    vector< vector< vector< vector<Int4>* >* >* >* _PixelInfoStore = _EventDecoder->_wirInfo->PixelInfoStore;
    if (_PixelInfoStore==NULL){
        UtsusemiError( _MessageTag+"LoadEventDataFiles > There is no information about pixels from WiringInfo.xml" );
        return false;
    }
    SetDataPath( pathToData, pathToT0data, runNumber, false, _PixelInfoStore );
    if (_isReady){
        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){
                        UtsusemiMessage( _MessageTag+"LoadEventDataFiles >> Load event data file for daq,mod="+stools->UInt4ToString(daq) + ","  + stools->UInt4ToString(mod) );
                        ReadEventData( daq, mod );
                        if (!(_isReady)){
                            UtsusemiError(_MessageTag+"ReadEventDataFiles >>> fails to read Event data (daq="+stools->UInt4ToString(daq) + ","  + stools->UInt4ToString(mod) );
                            for (UInt4 i=0; i<(_PixelInfoStore->at(daq)->at(mod)->size()); i++){
                                if (_PixelInfoStore->at(daq)->at(mod)->at(i)!=NULL){
                                    Int4 det_id = _PixelInfoStore->at(daq)->at(mod)->at(i)->at(1);
                                    if ( det_id>=(_isUnReadDetId.size()) ) _isUnReadDetId.resize( (det_id+1), false );
                                    _isUnReadDetId[det_id]=true;
                                    UtsusemiMessage( _MessageTag+"ReadEventData >>> masked on detId="+stools->UInt4ToString(det_id) );
                                }
                            }
                        }
                    }
                }
            }
        }
        if (!(_isReady)){
            UtsusemiError( _MessageTag+"LoadEventDataFiles >>> fails to read some event data files ");
        }
    }else{
        UtsusemiError( _MessageTag+"LoadEventDataFiles >>> Not Found Data Folder." );
        return false;
    }
    return true;
}
//////////////////////////////////////////////////////////
ElementContainerArray  UtsusemiEventDataConverterNeunet2QEvent::
Slice2d( string evtFile, string XtalParam ){
    vector<string> evtFiles;
    evtFiles.push_back(evtFile);
    return Slice2d(evtFiles, XtalParam);
}
//////////////////////////////////////////////////////////
ElementContainerArray  UtsusemiEventDataConverterNeunet2QEvent::
Slice2d( vector<string> evtFiles, string XtalParam )
{
    vector<Double> ax1range;
    vector<Double> ax2range;
    vector<Double> ax3range;
    vector<Double> ax4range;
    vector<string> type;
    vector<Double> folding;
    ElementContainerArray eca;

    UtsusemiSqeCalcXtalParams* _xp = new UtsusemiSqeCalcXtalParams();
    if (_xp->LoadFile(XtalParam)){
        ax1range = _xp->PutAxRange(0);
        ax2range = _xp->PutAxRange(1);
        ax3range = _xp->PutAxRange(2);
        ax4range = _xp->PutAxRange(3);
        type = _xp->PutAxType();
        folding = _xp->PutFolding();
    }else{
        UtsusemiError( _MessageTag+"Slice2d >> " );
        delete _xp;
        return eca;
    }
    delete _xp;
    
    vector<Int4> v_type;
    v_type.resize(4,-1);
    
    vector< vector<Double> > ranges;
    ranges.push_back( ax1range );
    ranges.push_back( ax2range );
    ranges.push_back( ax3range );
    ranges.push_back( ax4range );
    
    for (UInt4 i=0;i<type.size();i++){
        if ((type[i]=="X")||(type[i]=="x")){
            v_type[0] = i;
        }
        if ((type[i]=="Y")||(type[i]=="y")){
            v_type[1] = i;
        }
        if ((type[i]=="T")||(type[i]=="t")){
            if (v_type[2]==-1){
                v_type[2] = i;
            }else{
                v_type[3] = i;
            }
        }
    }

    vector<Double> xrange = CalcRangeAsBinCenterZero( ranges[v_type[0]][0],ranges[v_type[0]][1],ranges[v_type[0]][2] );
    vector<Double> yrange = CalcRangeAsBinCenterZero( ranges[v_type[1]][0],ranges[v_type[1]][1],ranges[v_type[1]][2] );
    vector<Double> xbin;
    vector<Double> ybin;
    Double xbin_width = ranges[v_type[0]][2];
    Double ybin_width = ranges[v_type[1]][2];
    for (Double x=xrange[0];x<=xrange[1];x+=ranges[v_type[0]][2]) xbin.push_back( x );
    for (Double y=yrange[0];y<=yrange[1];y+=ranges[v_type[1]][2]) ybin.push_back( y );
    UInt4 n_X = (UInt4)( xrange[2] );
    UInt4 n_Y = (UInt4)( yrange[2] );

    float **dArray, **cArray;
    dArray = new float*[ n_X ];
    cArray = new float*[ n_X ];
    for (UInt4 i=0;i<n_X;i++){
        dArray[i] = new float[ n_Y ];
        cArray[i] = new float[ n_Y ];
    }
    
    for (UInt4 i=0;i<n_X;i++){
        for (UInt4 j=0;j<n_Y;j++){
            dArray[i][j]=cArray[i][j]=0.0;
        }
    }
    
    Double *T1range = new Double[2];
    vector<Double> t1range = CalcRangeAsBinCenterZero( ranges[v_type[2]][0],ranges[v_type[2]][1],ranges[v_type[2]][2] );
    T1range[0] = t1range[0];
    T1range[1] = t1range[1]-0.5*ranges[v_type[2]][2];
    Double *T2range = new Double[2];
    vector<Double> t2range = CalcRangeAsBinCenterZero( ranges[v_type[3]][0],ranges[v_type[3]][1],ranges[v_type[3]][2] );
    T2range[0] = t2range[0];
    T2range[1] = t2range[1]-0.5*ranges[v_type[3]][2];

    vector<FILE*> fpList( evtFiles.size() );
    for (UInt4 i=0; i<evtFiles.size(); i++){
        if (NULL==(fpList[i]=fopen( evtFiles[i].c_str(),"rb"))){
            UtsusemiError( "UtsusemiEventDataConverterNeunet2QEvent::DumpEventToText >> Failed to open file :"+evtFiles[i] );
            return eca;
        }
    }
    
    _MeasuredPoints( cArray, ax4range, n_X, n_Y, v_type, xrange, xbin_width, yrange, ybin_width, T1range, T2range, folding );
    
    float data[5];
    for (UInt4 i=0; i<evtFiles.size(); i++){
        cout << "Treating file="+evtFiles[i] << endl;
        FILE *fp = fpList[i];
        while((fread( data, sizeof(float),5,fp))==5){
            vector<Double> ax(4);
            ax[0] = data[0];
            ax[1] = data[1];
            ax[2] = data[2];
            ax[3] = data[3];
            Double weight = data[4];
            
            Double X = ax[ v_type[0] ];
            if (folding[ v_type[0] ]==0.0) X = fabs(X);
            if (folding[ v_type[0] ]>0.0) X = fabs(X) - (floor(fabs(X)/folding[v_type[0]])*folding[v_type[0]]);
            Double Y = ax[ v_type[1] ];
            if (folding[ v_type[1] ]==0.0) Y = fabs(Y);
            if (folding[ v_type[1] ]>0.0) Y = fabs(Y) - (floor(fabs(Y)/folding[v_type[1]])*folding[v_type[1]]);
            Double T1 = ax[ v_type[2] ];
            if (folding[ v_type[2] ]==0.0) T1 = fabs(T1);
            if (folding[ v_type[2] ]>0.0) T1 = fabs(T1) - (floor(fabs(T1)/folding[v_type[2]])*folding[v_type[2]]);
            Double T2 = ax[ v_type[3] ];
            if (folding[ v_type[3] ]==0.0) T2 = fabs(T2);
            if (folding[ v_type[3] ]>0.0) T2 = fabs(T2) - (floor(fabs(T2)/folding[v_type[3]])*folding[v_type[3]]);
            
            if ((T1range[0]<=T1)&&(T1<T1range[1])){
                if ((T2range[0]<=T2)&&(T2<T2range[1])){
                    if ((xrange[0]<=X)&&(X<xrange[1])){
                        if ((yrange[0]<=Y)&&(Y<yrange[1])){
                            UInt4 i_X = (UInt4)( (X-xrange[0])/xbin_width );
                            UInt4 i_Y = (UInt4)( (Y-yrange[0])/ybin_width );
                            
                            dArray[i_X][i_Y] += weight;
                        }
                    }
                }
            }
        }
    }
    
    for (UInt4 i=0; i<evtFiles.size(); i++) fclose(fpList[i]);
    
    //fclose(fp);
    //cout << "n_X,n_y=" << n_X << "," << n_Y << endl;
    //cout << "xbin.size()=" << xbin.size() << endl;
    //cout << "ybin.size()=" << ybin.size() << endl;
    
    for (UInt4 x=0;x<n_X;x++){
        vector<Double> xr;
        xr.push_back( xbin[x] );
        xr.push_back( xbin[x+1] );
        HeaderBase hh;
        hh.Add( "XRANGE", xr );
        
        ElementContainer ec(hh);
        ec.Add("Ybin",ybin );
        vector<Double> Int;
        vector<Double> Err;
        Int.resize( n_Y, 0.0 );
        Err.resize( n_Y, 0.0 );
        for (UInt4 y=0;y<n_Y;y++){
            Double ii = dArray[x][y];
            Double cc = cArray[x][y];
            if (cc!=0){
                Int[y] = ii/cc;
                Err[y] = sqrt(ii)/cc;
            }else{
                Int[y] = UTSUSEMIMASKVALUE64;
                Err[y] = 0.0;
            }
        }
        ec.Add( "Intensity", Int );
        ec.Add( "Error", Err );
        ec.SetKeys( "Ybin", "Intensity", "Error" );
        
        eca.Add(ec);
    }
    
    for (UInt4 i=0;i<n_X;i++){
        delete [] dArray[i];
        delete [] cArray[i];
    }
    delete [] dArray;
    delete [] cArray;
    
    return eca;
    
}



//////////////////////////////////////////////////////////
void  UtsusemiEventDataConverterNeunet2QEvent::
_MeasuredPoints( float** A, vector<Double> hwrange, UInt4 n_X, UInt4 n_Y, vector<Int4> v_type, vector<Double> xrange, Double xbin_width, vector<Double> yrange, Double ybin_width, Double *T1range, Double *T2range, vector<Double> folding ){
    vector<Double> hw_info = CalcRangeAsBinCenterZero( hwrange[0],hwrange[1],hwrange[2]);
    UInt4 num_of_hw = (UInt4)hw_info[2];
    vector<Double> hw(num_of_hw,0.0);
    for (UInt4 i=0; i<num_of_hw; i++)
        hw[i] = hw_info[0] + hwrange[2]/2.0 + (Double)i * hwrange[2];

    UInt4 num_of_pixels = _EventDecoder->_pixelPositionVect.size();

    for (UInt4 pixelId=0; pixelId<num_of_pixels; pixelId++){
        if (_EventDecoder->_pixelPositionVect[ pixelId ]!=NULL){
            Double px = _EventDecoder->_pixelPositionVect[ pixelId ]->at(0);
            Double py = _EventDecoder->_pixelPositionVect[ pixelId ]->at(1);
            Double pz = _EventDecoder->_pixelPositionVect[ pixelId ]->at(2);
            Double L2 = sqrt( px*px + py*py + pz*pz );

            Double ki = sqrt( _uuc->EtoK2( _Ei ) );

            for (UInt4 i=0; i<num_of_hw; i++){
                Double Ef = _Ei - hw[i];
                Double kf = sqrt( _uuc->EtoK2( Ef ) );
                Double qx = -kf*(px/L2);
                Double qy = -kf*(py/L2);
                Double qz = ki-kf*(pz/L2);
                Double q1 = qz*_PM[0] + qx*_PM[1] + qy*_PM[2] + hw[i]*_PM[3];
                Double q2 = qz*_PM[4] + qx*_PM[5] + qy*_PM[6] + hw[i]*_PM[7];
                Double q3 = qz*_PM[8] + qx*_PM[9] + qy*_PM[10] + hw[i]*_PM[11];
                Double q4 = qz*_PM[12] + qx*_PM[13] + qy*_PM[14] + hw[i]*_PM[15];
                
                vector<Double> ax(4);
                ax[0] = q1;
                ax[1] = q2;
                ax[2] = q3;
                ax[3] = q4;
                Double X = ax[ v_type[0] ];
                if (folding[ v_type[0] ]==0.0) X = fabs(X);
                if (folding[ v_type[0] ]>0.0) X = fabs(X) - (floor(fabs(X)/folding[v_type[0]])*folding[v_type[0]]);
                Double Y = ax[ v_type[1] ];
                if (folding[ v_type[1] ]==0.0) Y = fabs(Y);
                if (folding[ v_type[1] ]>0.0) Y = fabs(Y) - (floor(fabs(Y)/folding[v_type[1]])*folding[v_type[1]]);
                Double T1 = ax[ v_type[2] ];
                if (folding[ v_type[2] ]==0.0) T1 = fabs(T1);
                if (folding[ v_type[2] ]>0.0) T1 = fabs(T1) - (floor(fabs(T1)/folding[v_type[2]])*folding[v_type[2]]);
                Double T2 = ax[ v_type[3] ];
                if (folding[ v_type[3] ]==0.0) T2 = fabs(T2);
                if (folding[ v_type[3] ]>0.0) T2 = fabs(T2) - (floor(fabs(T2)/folding[v_type[3]])*folding[v_type[3]]);
                
                if ((T1range[0]<=T1)&&(T1<T1range[1])){
                    if ((T2range[0]<=T2)&&(T2<T2range[1])){
                        if ((xrange[0]<=X)&&(X<xrange[1])){
                            if ((yrange[0]<=Y)&&(Y<yrange[1])){
                                UInt4 i_X = (UInt4)( (X-xrange[0])/xbin_width );
                                UInt4 i_Y = (UInt4)( (Y-yrange[0])/ybin_width );
                                A[i_X][i_Y]+=1.0;
                            }
                        }
                    }
                }
            }
        }
    }
}
