#ifndef UTSUSEMIEVENTDATACONVERTERNEUNET2QEVENT
#define UTSUSEMIEVENTDATACONVERTERNEUNET2QEVENT

#include "UtsusemiHeader.hh"
#include "UtsusemiEventDataConverterTemplate.hh"
#include "UtsusemiEventCasesDecoderTemplate.hh"
#include "UtsusemiNeunetEventDecoderBase.hh"
#include "UtsusemiFilterTrignet.hh"
#include "T0TreatToolsNeunet.hh"
#include "HeaderBase.hh"
#include "ElementContainer.hh"
#include "ElementContainerArray.hh"
#include "ElementContainerMatrix.hh"
#include "StringTools.hh"
#include "UtsusemiUnitConverter.hh"
#include "UtsusemiSqeCalc.hh"
#include "UtsusemiSqeCalcXtalParams.hh"
#include "UtsusemiSetMask.hh"

////////////////////////////////////
// UtsusemiEventDataConverterNeunet2Event
///////////////////////////////////

//! Load Event Data and convert to Histogram for Inelastic scattering
/*! 
 *   LoadParamFiles( "WiringInfo.xml", "DetectorInfo.xml", "CaseInfo.xml" )
 *   LoadTrignetEventFile( runNo, "/data", "" )
 *   SetHistAllocation()
 *   ecm = ElementContainerMatrix()
 *   SetElementContainerMatrix( ecm, runNo, "/data", "" )
 */

class UtsusemiEventDataConverterNeunet2QEvent:
    public UtsusemiEventDataConverterTemplate< UtsusemiNeunetEventDecoderBase,
                                               UtsusemiEventCasesDecoderTemplate<T0TreatToolsNeunet,UtsusemiFilterTrignet>
                                               >
{
private:
    void Initialize2QEvent();
    string _MessageTag;
    StringTools* stools;
    Int4 _SetElementContainerMatrix( ElementContainerMatrix* ecm, UInt4 caseId=1 );
        //!< Sets Histogram into ElementContainerMatrix
        /*!< This must be executed after LoadEventDataFiles
         *
         *     _SetElementContainerMatrix( ElementContainerMatrix* ecm, UInt4 caseId=1 )
         *   @param ecm          (ElementContainerMatrix*)
         *   @param caseId       (UInt4) case ID 
         *   @retval  0 : succeed
         *   @retval -3 : Wrong defined TOF binning info ( failed to load WiringInfo )
         */
    Double _Ei;
    Double _hw_min;
    Double _hw_max;
    Double _L1;
    string _outputPath;
    vector<Double> _PM;
    UtsusemiUnitConverter* _uuc;

    bool _withWeightOutput;
    bool _withT0EventMark;

    vector< vector< vector<Double>* >* > *_MaskList;

public:
    UtsusemiEventDataConverterNeunet2QEvent();
        //!< Constructor
        /*!<
         */
    ~UtsusemiEventDataConverterNeunet2QEvent();
        //!< Destructor
        /*!<
         */
    void SetEi( Double Ei, Double hw_min, Double hw_max, Double l1 );
    bool SetXtalParamFile( string _xtalParamPath, string rotateStep="" );
    bool SetOutputPath( string _outputPath );
    bool LoadParamFiles( string w_file, string d_file, string c_file="" );
    bool DumpEventToText( string evtfile, string txtfile );
    void SetWithWeightOutput( bool _flag ){ _withWeightOutput = _flag; }
    void SetWithT0EventMark( bool _flag ){ _withT0EventMark = _flag; }
    bool SetTextMaskInfo( string maskfile );
    bool ConvertEventDataFiles(UInt4 runNumber, string pathToData, string pathToT0data);
    void EventTransform( UInt4 daqId, UInt4 moduleNo, const UChar* data, UInt4 size,  vector<Double>* Offset, vector<UInt4>* Case, vector<Double>* retVals );
        //!< Convert normal events to Arima's Events
        /*!< 
         *
         *   @param daqId (UInt4) DAQ id
         *   @param moduleNo (UInt4) Module No
         *   @param data (UChar*) event data
         *   @param size (UInt4) size of event data
         *   @param Offset (vector<Double>) offset value
         *   @param Case (vector<UInt4>) case
         *   @param retVals (vector<Double>) converted Values
         *   @retval None
         */
    void PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, vector<UInt8> T0Table, vector<Double> ClockTable, vector< vector<UInt4>* > *CaseTable );
    void PreIncrement( UInt4 daqId, UInt4 moduleNo, const UChar* data, vector<UInt8> T0Table);
        //!< Pre-process to convert event data to histogam
        /*!< Pre-process to convert event data to histogam with multh-threading.
         *
         *   @param daqId (UInt4) DAQ id
         *   @param moduleNo (UInt4) module No
         *   @param data (UChar*) event data
         *   @param T0Table (vecrot<UInt4>) T0 index 
         *   @param ClockTable (vector<Double>) Differences between instrument clocks
         *   @param CaseTable (vector<vector<UInt4>>) Table of cases pattern
         *   @retval None
         */
    ElementContainerArray Slice2d( string evtFile, string XtalParam );
    ElementContainerArray Slice2d( vector<string> evtFiles, string XtalParam );
    void _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 );
};
#endif
