#include "UtsusemiEventDataConverterSimpleNeunet.hh"
//////////////////////////////////////////////////////////
UtsusemiEventDataConverterSimpleNeunet::
UtsusemiEventDataConverterSimpleNeunet(){
    _ED = PutEventDecoder();
    _ED->SetSimpleMode(true);
    _NumOfMod = 1;
    _NumOfPix = 100;
    _Aval = 1000;
    _Bval = 1.0;
    _Cval = 0.0;
    _LLD = 0;
    _HLD = 4096;
    _deltaX = 10.0;
    _offsetX = 0.0;
    _L1 = 0.0;
    SetNumOfPixel( _NumOfPix );
    _MessageTag = "UtsusemiEventDataConverterSimpleNeunet::";
    _stools = new StringTools();
    _enableConv = false;
}
//////////////////////////////////////////////////////////
UtsusemiEventDataConverterSimpleNeunet::
~UtsusemiEventDataConverterSimpleNeunet(){
    delete _stools;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetL1( Double L1 ){
    _L1 = L1;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetNumOfMod( UInt4 n ){
    _NumOfMod = n;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetNumOfPixel( UInt4 _numPix ){
    _ED->_wirInfo->Clear();
    _ED->_wirInfo->ClearReader();
    _NumOfPix = _numPix;
    UInt4 daqId = 0;
    UInt4 detId = 0;
    UInt4 headPixelId = 0;
    UInt4 numAxis = 1;
    for (UInt4 modNo=0; modNo<_NumOfMod; modNo++){
        for (UInt4 detN=0; detN<8; detN++){
            _ED->_wirInfo->SetPixelInfo( daqId, modNo, detId, headPixelId, _NumOfPix, "PSD", numAxis );
            detId++;
            headPixelId += _NumOfPix;
        }
    }
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterSimpleNeunet::
SetPsdParam( UInt4 detId, Double _A, Double _B, Double _C ){
    _ED->_wirInfo->SetPsdParams( detId, WiringInfoEditorNeunet::PSD_A, _A );
    _ED->_wirInfo->SetPsdParams( detId, WiringInfoEditorNeunet::PSD_B, _B );
    _ED->_wirInfo->SetPsdParams( detId, WiringInfoEditorNeunet::PSD_C, _C );
    if ( (double(_ED->_wirInfo->PsdParams.size())/8.0) > double(_NumOfMod) )
        _NumOfMod = UInt4(double(_ED->_wirInfo->PsdParams.size())/8.0);
    return true;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetPsdParam( Double _A, Double _B, Double _C ){
    _Aval = _A;
    _Bval = _B;
    _Cval = _C;
    for (UInt4 detId=0; detId<_NumOfMod*8; detId++)
        SetPsdParam( detId, _A, _B, _C );
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterSimpleNeunet::
SetPsdPosition( UInt4 detId, std::vector<Double> det_info ){
    UInt4 num_ax = 1;
    return _ED->_detInfo->SetPositionInfo( detId, num_ax, det_info );
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetPsdPH( Double _minPH, Double _maxPH ){
    _LLD = _minPH;
    _HLD = _maxPH;
    for (UInt4 detId=0; detId<_NumOfMod*8; detId++){
        _ED->_wirInfo->SetPsdParams( detId, WiringInfoEditorNeunet::PSD_LLD, _minPH );
        _ED->_wirInfo->SetPsdParams( detId, WiringInfoEditorNeunet::PSD_HLD, _maxPH );
    }
    if ( (double(_ED->_wirInfo->PsdParams.size())/8.0) > double(_NumOfMod) )
        _NumOfMod = UInt4(double(_ED->_wirInfo->PsdParams.size())/8.0);
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
SetPsdInfo( Double deltaX, Double offsetX ){
    _deltaX = deltaX;
    _offsetX = offsetX;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterSimpleNeunet::
SetHistParams( std::string _params ){
    UInt4 tof_pat_id = 0; //_ED->_wirInfo->TofBinInfoList[ pixelId ];
    UInt4 conv_type = 1;
    std::vector<Double> params;

    if ( (_ED->_detInfo->PosiInfo!=NULL) &&
         ((_ED->_detInfo->PosiInfo->position_list.size())>=(_NumOfMod*8)) )
        _enableConv=true;

    UtsusemiTofBinInfo* tmp = new UtsusemiTofBinInfo();
    tmp->patternId = tof_pat_id;
    tmp->offset = 0.0;
    tmp->conts =  "All";
    _ED->_wirInfo->TofBinInfo.push_back( tmp );
    _ED->_wirInfo->SetInfoAsReader();
    if (_enableConv){
        _ED->_detInfo->SetInfoAsReader();
        _ED->CalcPixelPosition();
        _ED->_wirDict->SetPixelPosition(_ED->_pixelPositionVect);
        _ED->_wirDict->SetL1( _L1 );
    }else{
        std::vector<std::string> div_p = _stools->SplitString(_params,",");
        if (div_p.empty()){
            UtsusemiError(_MessageTag+"SetHistParams >> Given params are invalid.");
            return false;
        }
        std::string tmp = div_p[0];
        transform( tmp.begin(), tmp.end(), tmp.begin(), ::toupper );
        if (tmp!="TOF"){
            UtsusemiError(_MessageTag+"SetHistParams >> You must set PsdPosition(s) at first for your histogram creation params ("+_params+")");
            return false;
        }
    }
    if (_ED->_wirInfo->SetConversionParameter( _params, tof_pat_id)){
        _ED->_wirInfo->MakePsdInfo( _NumOfPix, _deltaX, _offsetX );
        _ED->_wirInfo->SetInfoAsReader();
        _numOfInnerPixels = _ED->PutNumOfInnerPixels();
        _eventSize = _EventDecoder->_EventSize;
        SetHistAllocation();
    }
    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterSimpleNeunet::
ReadEventData( UInt4 modNo, std::string _file ){
    char modkeyc[7];
    std::snprintf( modkeyc, sizeof(modkeyc), "00_%03d",modNo ); // make 00_123 as key
    std::string modkey(modkeyc);
    std::string::size_type ind = _file.rfind(".edb");
    if (ind==std::string::npos){
        UtsusemiError( _MessageTag+"ReadEventData >> given file name has no extention edb. ("+_file+")" );
        return false;
    }
    std::ifstream ifs(_file.c_str());
    if (ifs.fail()){
        UtsusemiError( _MessageTag+"ReadEventData >> File not found. ("+_file+")" );
        ifs.close();
        return false;
    }
    ifs.close();

    std::vector<std::string> edb_files;
    std::vector<std::string> t0b_files;
    bool remakeT0b = false;
    if (_dataFileList.Check( modkey )!=0){
        edb_files = _dataFileList.Put( modkey );
        _t0dataFileList.Remove( modkey );
        remakeT0b = true;
    }
    edb_files.push_back( _file );

    std::string t0b_path = _file.substr( 0, ind )+".t0b";
    std::string found_path = FindTempFilePath( t0b_path );
    if ( (found_path=="")||(remakeT0b) ){
        Int4 ret = _CaseDecoder->PutT0TreatTools()->readOrgEvent( edb_files );
        if (ret>0){
            UtsusemiError( _MessageTag+"ReadEventData >> Fails to read edb file. ("+_file+")" );
            return false;
        }
        ret = _CaseDecoder->PutT0TreatTools()->saveT0IndexEvent( t0b_path );
        if (ret>0){
            UtsusemiError( _MessageTag+"ReadEventData >> Fails to make t0b file. ("+t0b_path+")" );
            return false;
        }
        t0b_files.push_back(t0b_path);
    }else
        t0b_files.push_back(found_path);

    _dataFileList.Add(modkey,edb_files);
    _t0dataFileList.Add(modkey,t0b_files);
    //_dataFileList.Dump();
    //_t0dataFileList.Dump();

    UtsusemiEventDataConverterTemplate::ReadEventData( 0, modNo );

    return true;
}
//////////////////////////////////////////////////////////
bool UtsusemiEventDataConverterSimpleNeunet::
SetElementContainerMatrix( ElementContainerMatrix* _ecm ){
    UInt4 caseId = 1;
    _runNumber = 1;
    _runNumbers.clear();
    _runNumbers.push_back(_runNumber);
    for (UInt4 detId=0; detId<_NumOfMod*8; detId++){
        ElementContainerArray eca;
        HeaderBase* hh_eca = eca.PutHeaderPointer();
        hh_eca->Add( std::string(UTSUSEMI_KEY_HEAD_MASKED), 0 );
        hh_eca->Add( std::string(UTSUSEMI_KEY_HEAD_DETID), Int4(detId) );
        for (UInt4 i=0; i<_NumOfPix; i++){
            UInt4 pixId = detId*_NumOfPix + i;
            ElementContainer ec;
            HeaderBase* hh = ec.PutHeaderPointer();
            hh->Add(std::string(UTSUSEMI_KEY_HEAD_DETID), Int4(detId) );
            hh->Add(std::string(UTSUSEMI_KEY_HEAD_MASKED), 0 );
            hh->Add(std::string(UTSUSEMI_KEY_HEAD_PIXELID), Int4(pixId) );
            if (_enableConv){
                std::vector<Double> ppv(3,0.0);
                ppv[0] = _ED->_pixelPositionVect[ pixId ]->at(0);
                ppv[1] = _ED->_pixelPositionVect[ pixId ]->at(1);
                ppv[2] = _ED->_pixelPositionVect[ pixId ]->at(2);
                hh->Add(std::string(UTSUSEMI_KEY_HEAD_PIXELPOSITION),ppv);
                hh->Add(std::string(UTSUSEMI_KEY_HEAD_PIXELSOLIDANGLE), _ED->_pixelSolidAngleVect[ pixId ] );
            }
            SetElementContainer( pixId, &ec, caseId );
            eca.Add(ec);
        }
        _ecm->Add(eca);
    }
    HeaderBase* hh_ecm = _ecm->PutHeaderPointer();
    AddRunInfoToHeader(hh_ecm,caseId);
    std::vector<std::string> process_h;
    process_h.push_back( "E2H" );
    hh_ecm->Add( UTSUSEMI_KEY_HEAD_DATAPROCESSED, process_h );
    if (_enableConv){
        UtsusemiReductionCommon UR( _ecm );
        UR.CalcPhi();
    }
    return true;
}
//////////////////////////////////////////////////////////
void UtsusemiEventDataConverterSimpleNeunet::
Test(ElementContainerMatrix* _ecm, UInt4 modNo, std::string _filePath ){
    SetNumOfPixel(100);
    UtsusemiMessage( _MessageTag+"Test >> SetPsdParam ");
    SetPsdParam( 100.0, 1.0, 0.0 );
    UtsusemiMessage( _MessageTag+"Test >> SetPsdParam fin.");
    UtsusemiMessage( _MessageTag+"Test >> SetPsdPH ");
    SetPsdPH( 0, 4094 );
    UtsusemiMessage( _MessageTag+"Test >> SetPsdPH fin. ");

    if (SetHistParams( "tof,0,40000,100" )){
        UtsusemiMessage( _MessageTag+"Test >> SetHistParam fin. ");
        if (ReadEventData( modNo, _filePath )){
            UtsusemiMessage( _MessageTag+"Test >> ReadEventData fin. ");
            if (SetElementContainerMatrix( _ecm )){
                UtsusemiMessage( _MessageTag+"Test >> SetElementContainerMatrix fin. ");
            }
        }
    }
}

