<commit_before>//=============================================================================================================
/**
* @file     filterdata.cpp
* @author   Florian Schlembach <florian.schlembach@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
*           Jens Haueisen <jens.haueisen@tu-ilmenau.de>
* @version  1.0
* @date     February, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Florian Schlembach, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains all FilterData.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "filterdata.h"

#include "../mnemath.h"

#include "parksmcclellan.h"
#include "cosinefilter.h"

//*************************************************************************************************************
//=============================================================================================================
// STL INCLUDES
//=============================================================================================================

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// Eigen INCLUDES
//=============================================================================================================

#include <Eigen/SparseCore>
//#ifndef EIGEN_FFTW_DEFAULT
//#define EIGEN_FFTW_DEFAULT
//#endif
#include <unsupported/Eigen/FFT>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//*************************************************************************************************************

FilterData::FilterData()
: m_Type(UNKNOWN)
, m_iFilterOrder(80)
, m_iFFTlength(512)
, m_sName("Unknown")
, m_dParksWidth(0.1)
, m_designMethod(External)
, m_dCenterFreq(0.5)
, m_dBandwidth(0.1)
, m_sFreq(1000)
, m_dLowpassFreq(4)
, m_dHighpassFreq(40)
{

}

//*************************************************************************************************************

FilterData::FilterData(QString unique_name,
                       FilterType type,
                       int order,
                       double centerfreq,
                       double bandwidth,
                       double parkswidth,
                       double sFreq,
                       qint32 fftlength,
                       DesignMethod designMethod)
: m_Type(type)
, m_iFilterOrder(order)
, m_iFFTlength(fftlength)
, m_sName(unique_name)
, m_dParksWidth(parkswidth)
, m_designMethod(designMethod)
, m_dCenterFreq(centerfreq)
, m_dBandwidth(bandwidth)
, m_sFreq(sFreq)
{
    designFilter();
}

//*************************************************************************************************************

void FilterData::designFilter()
{
    switch(m_designMethod) {
        case Tschebyscheff: {
            ParksMcClellan filter(m_iFilterOrder,
                                  m_dCenterFreq,
                                  m_dBandwidth,
                                  m_dParksWidth,
                                  (ParksMcClellan::TPassType)m_Type);
            m_dCoeffA = filter.FirCoeff;

            //fft-transform m_dCoeffA in order to be able to perform frequency-domain filtering
            fftTransformCoeffs();

            break;
        }

        case Cosine: {
            CosineFilter filtercos;

            switch(m_Type) {
                case LPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;

                case HPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;

                case BPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;
            }

            //This filter is designed in the frequency domain, hence the time domain impulse response need to be shortend by the users dependent number of taps
            m_dCoeffA.resize(m_iFilterOrder);
            m_dCoeffA.head(m_iFilterOrder/2) = filtercos.m_dCoeffA.tail(m_iFilterOrder/2);
            m_dCoeffA.tail(m_iFilterOrder/2) = filtercos.m_dCoeffA.head(m_iFilterOrder/2);

            //Now generate the fft version of the shortened impulse response
            fftTransformCoeffs();

            break;
        }
    }

    switch(m_Type) {
        case LPF:
            m_dLowpassFreq = 0;
            m_dHighpassFreq = m_dCenterFreq*(m_sFreq/2);
        break;

        case HPF:
            m_dLowpassFreq = m_dCenterFreq*(m_sFreq/2);
            m_dHighpassFreq = 0;
        break;

        case BPF:
            m_dLowpassFreq = (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2);
            m_dHighpassFreq = (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2);
        break;
    }

}

//*************************************************************************************************************

void FilterData::fftTransformCoeffs()
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    //zero-pad m_dCoeffA to m_iFFTlength
    RowVectorXd t_coeffAzeroPad = RowVectorXd::Zero(m_iFFTlength);
    t_coeffAzeroPad.head(m_dCoeffA.cols()) = m_dCoeffA;

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform filter coeffs
    m_dFFTCoeffA = RowVectorXcd::Zero(m_iFFTlength);
    fft.fwd(m_dFFTCoeffA,t_coeffAzeroPad);
}

//*************************************************************************************************************

RowVectorXd FilterData::applyConvFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData){
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());
    RowVectorXd t_filteredTime = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;

        default:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;
    }

    //Do the convolution
    for(int i=m_dCoeffA.cols(); i<t_filteredTime.cols(); i++)
        t_filteredTime(i-m_dCoeffA.cols()) = t_dataZeroPad.segment(i-m_dCoeffA.cols(),m_dCoeffA.cols()) * m_dCoeffA.transpose();

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}

//*************************************************************************************************************

RowVectorXd FilterData::applyFFTFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData) {
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

//    std::cout<<"m_iFFTlength: "<<m_iFFTlength<<std::endl;
//    std::cout<<"2*m_dCoeffA.cols() + data.cols(): "<<2*m_dCoeffA.cols() + data.cols()<<std::endl;

    if(2*m_dCoeffA.cols() + data.cols()>m_iFFTlength) {
        qDebug()<<"Error in FilterData: Number of mirroring/zeropadding size plus data size is bigger then fft length!";
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(m_iFFTlength);

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.head(data.cols()) = data;
            break;

        default:
            t_dataZeroPad.head(data.cols()) = data;
            break;
    }

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform data sequence
    RowVectorXcd t_freqData;
    fft.fwd(t_freqData,t_dataZeroPad);

    //perform frequency-domain filtering
    RowVectorXcd t_filteredFreq = m_dFFTCoeffA.array()*t_freqData.array();

    //inverse-FFT
    RowVectorXd t_filteredTime;
    fft.inv(t_filteredTime,t_filteredFreq);

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}

//*************************************************************************************************************

QString FilterData::getStringForDesignMethod(const FilterData::DesignMethod &designMethod)
{
    QString designMethodString = "External";

    if(designMethod == FilterData::External)
        designMethodString = "External";

    if(designMethod == FilterData::Cosine)
        designMethodString = "Cosine";

    if(designMethod == FilterData::Tschebyscheff)
        designMethodString = "Tschebyscheff";

    return designMethodString;
}

//*************************************************************************************************************

QString FilterData::getStringForFilterType(const FilterData::FilterType &filterType)
{
    QString filterTypeString = "LPF";

    if(filterType == FilterData::LPF)
        filterTypeString = "LPF";

    if(filterType == FilterData::HPF)
        filterTypeString = "HPF";

    if(filterType == FilterData::BPF)
        filterTypeString = "BPF";

    if(filterType == FilterData::NOTCH)
        filterTypeString = "NOTCH";

    return filterTypeString;
}

//*************************************************************************************************************

FilterData::DesignMethod FilterData::getDesignMethodForString(const QString &designMethodString)
{
    FilterData::DesignMethod designMethod = FilterData::External;

    if(designMethodString == "External")
        designMethod = FilterData::External;

    if(designMethodString == "Tschebyscheff")
        designMethod = FilterData::Tschebyscheff;

    if(designMethodString == "Cosine")
        designMethod = FilterData::Cosine;

    return designMethod;
}

//*************************************************************************************************************

FilterData::FilterType FilterData::getFilterTypeForString(const QString &filterTypeString)
{
    FilterData::FilterType filterType = FilterData::UNKNOWN;

    if(filterTypeString == "LPF")
        filterType = FilterData::LPF;

    if(filterTypeString == "HPF")
        filterType = FilterData::HPF;

    if(filterTypeString == "BPF")
        filterType = FilterData::BPF;

    if(filterTypeString == "NOTCH")
        filterType = FilterData::NOTCH;

    return filterType;
}
<commit_msg>change mirror length to m_dCoeffA/2<commit_after>//=============================================================================================================
/**
* @file     filterdata.cpp
* @author   Florian Schlembach <florian.schlembach@tu-ilmenau.de>;
*           Christoph Dinh <chdinh@nmr.mgh.harvard.edu>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>;
*           Jens Haueisen <jens.haueisen@tu-ilmenau.de>
* @version  1.0
* @date     February, 2014
*
* @section  LICENSE
*
* Copyright (C) 2014, Florian Schlembach, Christoph Dinh and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Contains all FilterData.
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include "filterdata.h"

#include "../mnemath.h"

#include "parksmcclellan.h"
#include "cosinefilter.h"

//*************************************************************************************************************
//=============================================================================================================
// STL INCLUDES
//=============================================================================================================

#include <iostream>

//*************************************************************************************************************
//=============================================================================================================
// Qt INCLUDES
//=============================================================================================================

#include <QDebug>

//*************************************************************************************************************
//=============================================================================================================
// Eigen INCLUDES
//=============================================================================================================

#include <Eigen/SparseCore>
//#ifndef EIGEN_FFTW_DEFAULT
//#define EIGEN_FFTW_DEFAULT
//#endif
#include <unsupported/Eigen/FFT>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace UTILSLIB;

//*************************************************************************************************************

FilterData::FilterData()
: m_Type(UNKNOWN)
, m_iFilterOrder(80)
, m_iFFTlength(512)
, m_sName("Unknown")
, m_dParksWidth(0.1)
, m_designMethod(External)
, m_dCenterFreq(0.5)
, m_dBandwidth(0.1)
, m_sFreq(1000)
, m_dLowpassFreq(4)
, m_dHighpassFreq(40)
{

}

//*************************************************************************************************************

FilterData::FilterData(QString unique_name,
                       FilterType type,
                       int order,
                       double centerfreq,
                       double bandwidth,
                       double parkswidth,
                       double sFreq,
                       qint32 fftlength,
                       DesignMethod designMethod)
: m_Type(type)
, m_iFilterOrder(order)
, m_iFFTlength(fftlength)
, m_sName(unique_name)
, m_dParksWidth(parkswidth)
, m_designMethod(designMethod)
, m_dCenterFreq(centerfreq)
, m_dBandwidth(bandwidth)
, m_sFreq(sFreq)
{
    designFilter();
}

//*************************************************************************************************************

void FilterData::designFilter()
{
    switch(m_designMethod) {
        case Tschebyscheff: {
            ParksMcClellan filter(m_iFilterOrder,
                                  m_dCenterFreq,
                                  m_dBandwidth,
                                  m_dParksWidth,
                                  (ParksMcClellan::TPassType)m_Type);
            m_dCoeffA = filter.FirCoeff;

            //fft-transform m_dCoeffA in order to be able to perform frequency-domain filtering
            fftTransformCoeffs();

            break;
        }

        case Cosine: {
            CosineFilter filtercos;

            switch(m_Type) {
                case LPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;

                case HPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;

                case BPF:
                    filtercos = CosineFilter(m_iFFTlength,
                                             (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2),
                                             m_dParksWidth*(m_sFreq/2),
                                             m_sFreq,
                                             (CosineFilter::TPassType)m_Type);

                    break;
            }

            //This filter is designed in the frequency domain, hence the time domain impulse response need to be shortend by the users dependent number of taps
            m_dCoeffA.resize(m_iFilterOrder);
            m_dCoeffA.head(m_iFilterOrder/2) = filtercos.m_dCoeffA.tail(m_iFilterOrder/2);
            m_dCoeffA.tail(m_iFilterOrder/2) = filtercos.m_dCoeffA.head(m_iFilterOrder/2);

            //Now generate the fft version of the shortened impulse response
            fftTransformCoeffs();

            break;
        }
    }

    switch(m_Type) {
        case LPF:
            m_dLowpassFreq = 0;
            m_dHighpassFreq = m_dCenterFreq*(m_sFreq/2);
        break;

        case HPF:
            m_dLowpassFreq = m_dCenterFreq*(m_sFreq/2);
            m_dHighpassFreq = 0;
        break;

        case BPF:
            m_dLowpassFreq = (m_dCenterFreq + m_dBandwidth/2)*(m_sFreq/2);
            m_dHighpassFreq = (m_dCenterFreq - m_dBandwidth/2)*(m_sFreq/2);
        break;
    }

}

//*************************************************************************************************************

void FilterData::fftTransformCoeffs()
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    //zero-pad m_dCoeffA to m_iFFTlength
    RowVectorXd t_coeffAzeroPad = RowVectorXd::Zero(m_iFFTlength);
    t_coeffAzeroPad.head(m_dCoeffA.cols()) = m_dCoeffA;

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform filter coeffs
    m_dFFTCoeffA = RowVectorXcd::Zero(m_iFFTlength);
    fft.fwd(m_dFFTCoeffA,t_coeffAzeroPad);
}

//*************************************************************************************************************

RowVectorXd FilterData::applyConvFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    if(data.cols()<m_dCoeffA.cols() && compensateEdgeEffects==MirrorData){
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());
    RowVectorXd t_filteredTime = RowVectorXd::Zero(2*m_dCoeffA.cols() + data.cols());

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()) = data.head(m_dCoeffA.cols()).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()) = data.tail(m_dCoeffA.cols()).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;

        default:
            t_dataZeroPad.segment(m_dCoeffA.cols(), data.cols()) = data;
            break;
    }

    //Do the convolution
    for(int i=m_dCoeffA.cols(); i<t_filteredTime.cols(); i++)
        t_filteredTime(i-m_dCoeffA.cols()) = t_dataZeroPad.segment(i-m_dCoeffA.cols(),m_dCoeffA.cols()) * m_dCoeffA.transpose();

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}

//*************************************************************************************************************

RowVectorXd FilterData::applyFFTFilter(const RowVectorXd& data, bool keepOverhead, CompensateEdgeEffects compensateEdgeEffects) const
{
    #ifdef EIGEN_FFTW_DEFAULT
        fftw_make_planner_thread_safe();
    #endif

    if(data.cols()<m_dCoeffA.cols()/2 && compensateEdgeEffects==MirrorData) {
        qDebug()<<QString("Error in FilterData: Number of filter taps(%1) bigger then data size(%2). Not enough data to perform mirroring!").arg(m_dCoeffA.cols()).arg(data.cols());
        return data;
    }

    if(m_dCoeffA.cols() + data.cols()>m_iFFTlength) {
        qDebug()<<"Error in FilterData: Number of mirroring/zeropadding size plus data size is bigger then fft length!";
        return data;
    }

    //Do zero padding or mirroring depending on user input
    RowVectorXd t_dataZeroPad = RowVectorXd::Zero(m_iFFTlength);

    switch(compensateEdgeEffects) {
        case MirrorData:
            t_dataZeroPad.head(m_dCoeffA.cols()/2) = data.head(m_dCoeffA.cols()/2).reverse();   //front
            t_dataZeroPad.segment(m_dCoeffA.cols()/2, data.cols()) = data;                    //middle
            t_dataZeroPad.tail(m_dCoeffA.cols()/2) = data.tail(m_dCoeffA.cols()/2).reverse();   //back
            break;

        case ZeroPad:
            t_dataZeroPad.head(data.cols()) = data;
            break;

        default:
            t_dataZeroPad.head(data.cols()) = data;
            break;
    }

    //generate fft object
    Eigen::FFT<double> fft;
    fft.SetFlag(fft.HalfSpectrum);

    //fft-transform data sequence
    RowVectorXcd t_freqData;
    fft.fwd(t_freqData,t_dataZeroPad);

    //perform frequency-domain filtering
    RowVectorXcd t_filteredFreq = m_dFFTCoeffA.array()*t_freqData.array();

    //inverse-FFT
    RowVectorXd t_filteredTime;
    fft.inv(t_filteredTime,t_filteredFreq);

    //Return filtered data
    if(!keepOverhead)
        return t_filteredTime.segment(m_dCoeffA.cols()/2, data.cols());

    return t_filteredTime.head(data.cols()+m_dCoeffA.cols());
}

//*************************************************************************************************************

QString FilterData::getStringForDesignMethod(const FilterData::DesignMethod &designMethod)
{
    QString designMethodString = "External";

    if(designMethod == FilterData::External)
        designMethodString = "External";

    if(designMethod == FilterData::Cosine)
        designMethodString = "Cosine";

    if(designMethod == FilterData::Tschebyscheff)
        designMethodString = "Tschebyscheff";

    return designMethodString;
}

//*************************************************************************************************************

QString FilterData::getStringForFilterType(const FilterData::FilterType &filterType)
{
    QString filterTypeString = "LPF";

    if(filterType == FilterData::LPF)
        filterTypeString = "LPF";

    if(filterType == FilterData::HPF)
        filterTypeString = "HPF";

    if(filterType == FilterData::BPF)
        filterTypeString = "BPF";

    if(filterType == FilterData::NOTCH)
        filterTypeString = "NOTCH";

    return filterTypeString;
}

//*************************************************************************************************************

FilterData::DesignMethod FilterData::getDesignMethodForString(const QString &designMethodString)
{
    FilterData::DesignMethod designMethod = FilterData::External;

    if(designMethodString == "External")
        designMethod = FilterData::External;

    if(designMethodString == "Tschebyscheff")
        designMethod = FilterData::Tschebyscheff;

    if(designMethodString == "Cosine")
        designMethod = FilterData::Cosine;

    return designMethod;
}

//*************************************************************************************************************

FilterData::FilterType FilterData::getFilterTypeForString(const QString &filterTypeString)
{
    FilterData::FilterType filterType = FilterData::UNKNOWN;

    if(filterTypeString == "LPF")
        filterType = FilterData::LPF;

    if(filterTypeString == "HPF")
        filterType = FilterData::HPF;

    if(filterTypeString == "BPF")
        filterType = FilterData::BPF;

    if(filterTypeString == "NOTCH")
        filterType = FilterData::NOTCH;

    return filterType;
}
<|endoftext|>


<commit_before>/*
     This file is part of libhttpserver
     Copyright (C) 2011-2019 Sebastiano Merlino

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
     USA
*/

#if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION)
#error "Only <httpserver.hpp> or <httpserverpp> can be included directly."
#endif

#ifndef SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_
#define SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_

#include <stdlib.h>
#include <memory>
#include <string>

#include "httpserver/http_response.hpp"
#include "httpserver/http_utils.hpp"

#define DEFAULT_WS_TIMEOUT 180
#define DEFAULT_WS_PORT 9898

namespace httpserver {

class webserver;
class http_request;

typedef const std::shared_ptr<http_response>(*render_ptr)(const http_request&);
typedef bool(*validator_ptr)(const std::string&);
typedef void(*log_access_ptr)(const std::string&);
typedef void(*log_error_ptr)(const std::string&);

class create_webserver {
 public:
     create_webserver() = default;
     create_webserver(const create_webserver& b) = default;
     create_webserver(create_webserver&& b) noexcept = default;
     create_webserver& operator=(const create_webserver& b) = default;
     create_webserver& operator=(create_webserver&& b) = default;

     explicit create_webserver(uint16_t port):
         _port(port) { }

     create_webserver& port(uint16_t port) {
         _port = port;
         return *this;
     }

     create_webserver& start_method(const http::http_utils::start_method_T& start_method) {
         _start_method = start_method;
         return *this;
     }

     create_webserver& max_threads(int max_threads) {
         _max_threads = max_threads;
         return *this;
     }

     create_webserver& max_connections(int max_connections) {
         _max_connections = max_connections;
         return *this;
     }

     create_webserver& memory_limit(int memory_limit) {
         _memory_limit = memory_limit;
         return *this;
     }

     create_webserver& content_size_limit(size_t content_size_limit) {
         _content_size_limit = content_size_limit;
         return *this;
     }

     create_webserver& connection_timeout(int connection_timeout) {
         _connection_timeout = connection_timeout;
         return *this;
     }

     create_webserver& per_IP_connection_limit(int per_IP_connection_limit) {
         _per_IP_connection_limit = per_IP_connection_limit;
         return *this;
     }

     create_webserver& log_access(log_access_ptr log_access) {
         _log_access = log_access;
         return *this;
     }

     create_webserver& log_error(log_error_ptr log_error) {
         _log_error = log_error;
         return *this;
     }

     create_webserver& validator(validator_ptr validator) {
         _validator = validator;
         return *this;
     }

     create_webserver& unescaper(unescaper_ptr unescaper) {
         _unescaper = unescaper;
         return *this;
     }

     create_webserver& bind_address(const struct sockaddr* bind_address) {
         _bind_address = bind_address;
         return *this;
     }

     create_webserver& bind_socket(int bind_socket) {
         _bind_socket = bind_socket;
         return *this;
     }

     create_webserver& max_thread_stack_size(int max_thread_stack_size) {
         _max_thread_stack_size = max_thread_stack_size;
         return *this;
     }

     create_webserver& use_ssl() {
         _use_ssl = true;
         return *this;
     }

     create_webserver& no_ssl() {
         _use_ssl = false;
         return *this;
     }

     create_webserver& use_ipv6() {
         _use_ipv6 = true;
         return *this;
     }

     create_webserver& no_ipv6() {
         _use_ipv6 = false;
         return *this;
     }

     create_webserver& use_dual_stack() {
         _use_dual_stack = true;
         return *this;
     }

     create_webserver& no_dual_stack() {
         _use_dual_stack = false;
         return *this;
     }

     create_webserver& debug() {
         _debug = true;
         return *this;
     }

     create_webserver& no_debug() {
         _debug = false;
         return *this;
     }

     create_webserver& pedantic() {
         _pedantic = true;
         return *this;
     }

     create_webserver& no_pedantic() {
         _pedantic = false;
         return *this;
     }

     create_webserver& https_mem_key(const std::string& https_mem_key) {
         _https_mem_key = http::load_file(https_mem_key);
         return *this;
     }

     create_webserver& https_mem_cert(const std::string& https_mem_cert) {
         _https_mem_cert = http::load_file(https_mem_cert);
         return *this;
     }

     create_webserver& https_mem_trust(const std::string& https_mem_trust) {
         _https_mem_trust = http::load_file(https_mem_trust);
         return *this;
     }

     create_webserver& raw_https_mem_key(const std::string& https_mem_key) {
         _https_mem_key = https_mem_key;
         return *this;
     }

     create_webserver& raw_https_mem_cert(const std::string& https_mem_cert) {
         _https_mem_cert = https_mem_cert;
         return *this;
     }

     create_webserver& raw_https_mem_trust(const std::string& https_mem_trust) {
         _https_mem_trust = https_mem_trust;
         return *this;
     }

     create_webserver& https_priorities(const std::string& https_priorities) {
         _https_priorities = https_priorities;
         return *this;
     }

     create_webserver& cred_type(const http::http_utils::cred_type_T& cred_type) {
         _cred_type = cred_type;
         return *this;
     }

     create_webserver& digest_auth_random(const std::string& digest_auth_random) {
         _digest_auth_random = digest_auth_random;
         return *this;
     }

     create_webserver& nonce_nc_size(int nonce_nc_size) {
         _nonce_nc_size = nonce_nc_size;
         return *this;
     }

     create_webserver& default_policy(const http::http_utils::policy_T& default_policy) {
         _default_policy = default_policy;
         return *this;
     }

     create_webserver& basic_auth() {
         _basic_auth_enabled = true;
         return *this;
     }

     create_webserver& no_basic_auth() {
         _basic_auth_enabled = false;
         return *this;
     }

     create_webserver& digest_auth() {
         _digest_auth_enabled = true;
         return *this;
     }

     create_webserver& no_digest_auth() {
         _digest_auth_enabled = false;
         return *this;
     }

     create_webserver& deferred() {
         _deferred_enabled = true;
         return *this;
     }

     create_webserver& no_deferred() {
         _deferred_enabled = false;
         return *this;
     }

     create_webserver& regex_checking() {
         _regex_checking = true;
         return *this;
     }

     create_webserver& no_regex_checking() {
         _regex_checking = false;
         return *this;
     }

     create_webserver& ban_system() {
         _ban_system_enabled = true;
         return *this;
     }

     create_webserver& no_ban_system() {
         _ban_system_enabled = false;
         return *this;
     }

     create_webserver& post_process() {
         _post_process_enabled = true;
         return *this;
     }

     create_webserver& no_post_process() {
         _post_process_enabled = false;
         return *this;
     }

     create_webserver& no_put_processed_data_to_content() {
         _put_processed_data_to_content = false;
         return *this;
     }

     create_webserver& put_processed_data_to_content() {
         _put_processed_data_to_content = true;
         return *this;
     }

     create_webserver& file_upload_target(const file_upload_target_T& file_upload_target) {
         _file_upload_target = file_upload_target;
         return *this;
     }

     create_webserver& file_upload_dir(const std::string& file_upload_dir) {
         _file_upload_dir = file_upload_dir;
         return *this;
     }

     create_webserver& no_generate_random_filename_on_upload() {
         _generate_random_filename_on_upload = false;
         return *this;
     }

     create_webserver& generate_random_filename_on_upload() {
         _generate_random_filename_on_upload = true;
         return *this;
     }

     create_webserver& single_resource() {
         _single_resource = true;
         return *this;
     }

     create_webserver& no_single_resource() {
         _single_resource = false;
         return *this;
     }

     create_webserver& tcp_nodelay() {
         _tcp_nodelay = true;
         return *this;
     }

     create_webserver& not_found_resource(render_ptr not_found_resource) {
         _not_found_resource = not_found_resource;
         return *this;
     }

     create_webserver& method_not_allowed_resource(render_ptr method_not_allowed_resource) {
         _method_not_allowed_resource = method_not_allowed_resource;
         return *this;
     }

     create_webserver& internal_error_resource(render_ptr internal_error_resource) {
         _internal_error_resource = internal_error_resource;
         return *this;
     }

 private:
     uint16_t _port = DEFAULT_WS_PORT;
     http::http_utils::start_method_T _start_method = http::http_utils::INTERNAL_SELECT;
     int _max_threads = 0;
     int _max_connections = 0;
     int _memory_limit = 0;
     size_t _content_size_limit = static_cast<size_t>(-1);
     int _connection_timeout = DEFAULT_WS_TIMEOUT;
     int _per_IP_connection_limit = 0;
     log_access_ptr _log_access = nullptr;
     log_error_ptr _log_error = nullptr;
     validator_ptr _validator = nullptr;
     unescaper_ptr _unescaper = nullptr;
     const struct sockaddr* _bind_address = nullptr;
     int _bind_socket = 0;
     int _max_thread_stack_size = 0;
     bool _use_ssl = false;
     bool _use_ipv6 = false;
     bool _use_dual_stack = false;
     bool _debug = false;
     bool _pedantic = false;
     std::string _https_mem_key = "";
     std::string _https_mem_cert = "";
     std::string _https_mem_trust = "";
     std::string _https_priorities = "";
     http::http_utils::cred_type_T _cred_type = http::http_utils::NONE;
     std::string _digest_auth_random = "";
     int _nonce_nc_size = 0;
     http::http_utils::policy_T _default_policy = http::http_utils::ACCEPT;
     bool _basic_auth_enabled = true;
     bool _digest_auth_enabled = true;
     bool _regex_checking = true;
     bool _ban_system_enabled = true;
     bool _post_process_enabled = true;
     bool _put_processed_data_to_content = true;
     file_upload_target_T _file_upload_target = FILE_UPLOAD_MEMORY_ONLY;
     std::string _file_upload_dir = "/tmp";
     bool _generate_random_filename_on_upload = false;
     bool _deferred_enabled = false;
     bool _single_resource = false;
     bool _tcp_nodelay = false;
     render_ptr _not_found_resource = nullptr;
     render_ptr _method_not_allowed_resource = nullptr;
     render_ptr _internal_error_resource = nullptr;

     friend class webserver;
};

}  // namespace httpserver

#endif  // SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_
<commit_msg>switch callback function pointers to std::function types (#283)<commit_after>/*
     This file is part of libhttpserver
     Copyright (C) 2011-2019 Sebastiano Merlino

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or (at your option) any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301
     USA
*/

#if !defined (_HTTPSERVER_HPP_INSIDE_) && !defined (HTTPSERVER_COMPILATION)
#error "Only <httpserver.hpp> or <httpserverpp> can be included directly."
#endif

#ifndef SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_
#define SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_

#include <stdlib.h>
#include <memory>
#include <functional>
#include <string>

#include "httpserver/http_response.hpp"
#include "httpserver/http_utils.hpp"

#define DEFAULT_WS_TIMEOUT 180
#define DEFAULT_WS_PORT 9898

namespace httpserver {

class webserver;
class http_request;

typedef std::function<const std::shared_ptr<http_response>(const http_request&)> render_ptr;
typedef std::function<bool(const std::string&)> validator_ptr;
typedef std::function<void(const std::string&)> log_access_ptr;
typedef std::function<void(const std::string&)> log_error_ptr;

class create_webserver {
 public:
     create_webserver() = default;
     create_webserver(const create_webserver& b) = default;
     create_webserver(create_webserver&& b) noexcept = default;
     create_webserver& operator=(const create_webserver& b) = default;
     create_webserver& operator=(create_webserver&& b) = default;

     explicit create_webserver(uint16_t port):
         _port(port) { }

     create_webserver& port(uint16_t port) {
         _port = port;
         return *this;
     }

     create_webserver& start_method(const http::http_utils::start_method_T& start_method) {
         _start_method = start_method;
         return *this;
     }

     create_webserver& max_threads(int max_threads) {
         _max_threads = max_threads;
         return *this;
     }

     create_webserver& max_connections(int max_connections) {
         _max_connections = max_connections;
         return *this;
     }

     create_webserver& memory_limit(int memory_limit) {
         _memory_limit = memory_limit;
         return *this;
     }

     create_webserver& content_size_limit(size_t content_size_limit) {
         _content_size_limit = content_size_limit;
         return *this;
     }

     create_webserver& connection_timeout(int connection_timeout) {
         _connection_timeout = connection_timeout;
         return *this;
     }

     create_webserver& per_IP_connection_limit(int per_IP_connection_limit) {
         _per_IP_connection_limit = per_IP_connection_limit;
         return *this;
     }

     create_webserver& log_access(log_access_ptr log_access) {
         _log_access = log_access;
         return *this;
     }

     create_webserver& log_error(log_error_ptr log_error) {
         _log_error = log_error;
         return *this;
     }

     create_webserver& validator(validator_ptr validator) {
         _validator = validator;
         return *this;
     }

     create_webserver& unescaper(unescaper_ptr unescaper) {
         _unescaper = unescaper;
         return *this;
     }

     create_webserver& bind_address(const struct sockaddr* bind_address) {
         _bind_address = bind_address;
         return *this;
     }

     create_webserver& bind_socket(int bind_socket) {
         _bind_socket = bind_socket;
         return *this;
     }

     create_webserver& max_thread_stack_size(int max_thread_stack_size) {
         _max_thread_stack_size = max_thread_stack_size;
         return *this;
     }

     create_webserver& use_ssl() {
         _use_ssl = true;
         return *this;
     }

     create_webserver& no_ssl() {
         _use_ssl = false;
         return *this;
     }

     create_webserver& use_ipv6() {
         _use_ipv6 = true;
         return *this;
     }

     create_webserver& no_ipv6() {
         _use_ipv6 = false;
         return *this;
     }

     create_webserver& use_dual_stack() {
         _use_dual_stack = true;
         return *this;
     }

     create_webserver& no_dual_stack() {
         _use_dual_stack = false;
         return *this;
     }

     create_webserver& debug() {
         _debug = true;
         return *this;
     }

     create_webserver& no_debug() {
         _debug = false;
         return *this;
     }

     create_webserver& pedantic() {
         _pedantic = true;
         return *this;
     }

     create_webserver& no_pedantic() {
         _pedantic = false;
         return *this;
     }

     create_webserver& https_mem_key(const std::string& https_mem_key) {
         _https_mem_key = http::load_file(https_mem_key);
         return *this;
     }

     create_webserver& https_mem_cert(const std::string& https_mem_cert) {
         _https_mem_cert = http::load_file(https_mem_cert);
         return *this;
     }

     create_webserver& https_mem_trust(const std::string& https_mem_trust) {
         _https_mem_trust = http::load_file(https_mem_trust);
         return *this;
     }

     create_webserver& raw_https_mem_key(const std::string& https_mem_key) {
         _https_mem_key = https_mem_key;
         return *this;
     }

     create_webserver& raw_https_mem_cert(const std::string& https_mem_cert) {
         _https_mem_cert = https_mem_cert;
         return *this;
     }

     create_webserver& raw_https_mem_trust(const std::string& https_mem_trust) {
         _https_mem_trust = https_mem_trust;
         return *this;
     }

     create_webserver& https_priorities(const std::string& https_priorities) {
         _https_priorities = https_priorities;
         return *this;
     }

     create_webserver& cred_type(const http::http_utils::cred_type_T& cred_type) {
         _cred_type = cred_type;
         return *this;
     }

     create_webserver& digest_auth_random(const std::string& digest_auth_random) {
         _digest_auth_random = digest_auth_random;
         return *this;
     }

     create_webserver& nonce_nc_size(int nonce_nc_size) {
         _nonce_nc_size = nonce_nc_size;
         return *this;
     }

     create_webserver& default_policy(const http::http_utils::policy_T& default_policy) {
         _default_policy = default_policy;
         return *this;
     }

     create_webserver& basic_auth() {
         _basic_auth_enabled = true;
         return *this;
     }

     create_webserver& no_basic_auth() {
         _basic_auth_enabled = false;
         return *this;
     }

     create_webserver& digest_auth() {
         _digest_auth_enabled = true;
         return *this;
     }

     create_webserver& no_digest_auth() {
         _digest_auth_enabled = false;
         return *this;
     }

     create_webserver& deferred() {
         _deferred_enabled = true;
         return *this;
     }

     create_webserver& no_deferred() {
         _deferred_enabled = false;
         return *this;
     }

     create_webserver& regex_checking() {
         _regex_checking = true;
         return *this;
     }

     create_webserver& no_regex_checking() {
         _regex_checking = false;
         return *this;
     }

     create_webserver& ban_system() {
         _ban_system_enabled = true;
         return *this;
     }

     create_webserver& no_ban_system() {
         _ban_system_enabled = false;
         return *this;
     }

     create_webserver& post_process() {
         _post_process_enabled = true;
         return *this;
     }

     create_webserver& no_post_process() {
         _post_process_enabled = false;
         return *this;
     }

     create_webserver& no_put_processed_data_to_content() {
         _put_processed_data_to_content = false;
         return *this;
     }

     create_webserver& put_processed_data_to_content() {
         _put_processed_data_to_content = true;
         return *this;
     }

     create_webserver& file_upload_target(const file_upload_target_T& file_upload_target) {
         _file_upload_target = file_upload_target;
         return *this;
     }

     create_webserver& file_upload_dir(const std::string& file_upload_dir) {
         _file_upload_dir = file_upload_dir;
         return *this;
     }

     create_webserver& no_generate_random_filename_on_upload() {
         _generate_random_filename_on_upload = false;
         return *this;
     }

     create_webserver& generate_random_filename_on_upload() {
         _generate_random_filename_on_upload = true;
         return *this;
     }

     create_webserver& single_resource() {
         _single_resource = true;
         return *this;
     }

     create_webserver& no_single_resource() {
         _single_resource = false;
         return *this;
     }

     create_webserver& tcp_nodelay() {
         _tcp_nodelay = true;
         return *this;
     }

     create_webserver& not_found_resource(render_ptr not_found_resource) {
         _not_found_resource = not_found_resource;
         return *this;
     }

     create_webserver& method_not_allowed_resource(render_ptr method_not_allowed_resource) {
         _method_not_allowed_resource = method_not_allowed_resource;
         return *this;
     }

     create_webserver& internal_error_resource(render_ptr internal_error_resource) {
         _internal_error_resource = internal_error_resource;
         return *this;
     }

 private:
     uint16_t _port = DEFAULT_WS_PORT;
     http::http_utils::start_method_T _start_method = http::http_utils::INTERNAL_SELECT;
     int _max_threads = 0;
     int _max_connections = 0;
     int _memory_limit = 0;
     size_t _content_size_limit = static_cast<size_t>(-1);
     int _connection_timeout = DEFAULT_WS_TIMEOUT;
     int _per_IP_connection_limit = 0;
     log_access_ptr _log_access = nullptr;
     log_error_ptr _log_error = nullptr;
     validator_ptr _validator = nullptr;
     unescaper_ptr _unescaper = nullptr;
     const struct sockaddr* _bind_address = nullptr;
     int _bind_socket = 0;
     int _max_thread_stack_size = 0;
     bool _use_ssl = false;
     bool _use_ipv6 = false;
     bool _use_dual_stack = false;
     bool _debug = false;
     bool _pedantic = false;
     std::string _https_mem_key = "";
     std::string _https_mem_cert = "";
     std::string _https_mem_trust = "";
     std::string _https_priorities = "";
     http::http_utils::cred_type_T _cred_type = http::http_utils::NONE;
     std::string _digest_auth_random = "";
     int _nonce_nc_size = 0;
     http::http_utils::policy_T _default_policy = http::http_utils::ACCEPT;
     bool _basic_auth_enabled = true;
     bool _digest_auth_enabled = true;
     bool _regex_checking = true;
     bool _ban_system_enabled = true;
     bool _post_process_enabled = true;
     bool _put_processed_data_to_content = true;
     file_upload_target_T _file_upload_target = FILE_UPLOAD_MEMORY_ONLY;
     std::string _file_upload_dir = "/tmp";
     bool _generate_random_filename_on_upload = false;
     bool _deferred_enabled = false;
     bool _single_resource = false;
     bool _tcp_nodelay = false;
     render_ptr _not_found_resource = nullptr;
     render_ptr _method_not_allowed_resource = nullptr;
     render_ptr _internal_error_resource = nullptr;

     friend class webserver;
};

}  // namespace httpserver

#endif  // SRC_HTTPSERVER_CREATE_WEBSERVER_HPP_
<|endoftext|>


<commit_before>#include <tuple>

template < typename Function , typename... Args >
auto curry( Function&& f , Args&&... args );

//   -----------------------------------------------------------------------------------
//  The curry-binder
//   -----------------------------------------------------------------------------------

template < typename Function , typename... Bound_args >
struct Currying_binder
{
private:

   Function const &    f_;
   std::tuple< typename std::remove_reference<Bound_args>::type... >   args_;

   struct curry_arguments {};
   struct try_to_infoke_function : curry_arguments {};

   template < typename... Args >
   auto dispatch( try_to_infoke_function , Args&&... args ) const -> decltype( f_(args...) )
   {  return  f_( std::forward<Args>(args)... );  }

   template < typename... Args >
   auto dispatch( curry_arguments , Args&&... args ) const -> decltype( curry( f_ , std::forward<Args>(args)... ) )
   { return  curry( f_ , std::forward<Args>(args)... ); }

   template < std::size_t... Ns , typename... Other_args >
   auto call( std::index_sequence<Ns...> , Other_args&&... other_args )
   {  return dispatch( try_to_infoke_function{} , std::get<Ns>(args_)... , std::forward<Other_args>(other_args)... );  }

public:

   Currying_binder( Function const &f , Bound_args&&... as )
   : f_(f) , args_( std::forward<Bound_args>(as)...) {}

   template < typename... Other_args >
   auto operator()( Other_args&&... other_args )
   {
      return  call( std::make_index_sequence<sizeof...(Bound_args)>()
                  , std::forward<Other_args>(other_args)... );
   }

};

template < typename Function , typename... Args >
auto curry( Function&& f , Args&&... args )
{
   return Currying_binder<Function,Args...>( f , std::forward<Args>(args)... );
}

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR( FUNCTOR , FUNCTION_TEMPLATE )                        \
namespace {                                                                    \
   struct {                                                                    \
      template < typename V1 , typename V2 >                                   \
      auto operator()( V1&& v1 , V2&& v2 ) const                               \
      {                                                                        \
         return FUNCTION_TEMPLATE( std::forward<V1>(v1)                        \
                                 , std::forward<V2>(v2) );                     \
      }                                                                        \
   }                                                                           \
   FUNCTOR;                                                                    \
}                                                                              \

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR2( FUNCTOR , FUNCTION_TEMPLATE )                       \
namespace {                                                                    \
   auto FUNCTOR = []( auto&& v1 , auto&& v2 )                                  \
   {                                                                           \
      return FUNCTION_TEMPLATE( std::forward<decltype(v1)>(v1)                 \
                              , std::forward<decltype(v2)>(v2) );              \
   };                                                                          \
}                                                                              \

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR3( FUNCTOR , FUNCTION_TEMPLATE )                       \
namespace {                                                                    \
   auto FUNCTOR = []( auto&&... vs )                                           \
   {                                                                           \
      return FUNCTION_TEMPLATE( std::forward<decltype(vs)>(vs) );              \
   };                                                                          \
}                                                                              \

//   ----------------------------------------------------------------------------

#define CURRY( CURRY_FUNCTION , FUNCTION_TEMPLATE )                            \
   MAKE_TPL_FUNCTOR2( FUNCTION_TEMPLATE##__CURRYFIED____ , FUNCTION_TEMPLATE ) \
   auto CURRY_FUNCTION  =  curry( FUNCTION_TEMPLATE##__CURRYFIED____ );        \

template < typename Value1 , typename Value2 >//, requires< is_addable<Value1,Value2>()... >
auto add_impl( Value1 const & v1 , Value2 const & v2 )
{
   return v1 + v2;
}

CURRY( add , add_impl );

auto sub  = curry( [](auto x , auto y) { return x-y; } );
auto mul3 = curry( [](auto x , auto y , auto z) { return x*y*z; } );

#include <cassert>
using namespace std;

int main()
{
   auto add3to = add(3);
   assert( add3to(4) == 7 );
   assert( add(3)(4) == 7 );
   assert( add(3, 4) == 7 );

   auto subfrom8 = sub(8);
   assert( subfrom8(3) == 5 );
   assert( sub(8)(3)   == 5 );
   assert( sub(8, 3)   == 5 );

   assert( mul3(1)(2,3)        == 6 );
   assert( mul3(1,2)(3)        == 6 );
   assert( mul3(1)(2)(3)       == 6 );
   assert( mul3()(1)()(2)()(3) == 6 );
}
<commit_msg>fixed typo<commit_after>#include <tuple>

template < typename Function , typename... Args >
auto curry( Function&& f , Args&&... args );

//   -----------------------------------------------------------------------------------
//  The curry-binder
//   -----------------------------------------------------------------------------------

template < typename Function , typename... Bound_args >
struct Currying_binder
{
private:

   Function const &    f_;
   std::tuple< typename std::remove_reference<Bound_args>::type... >   args_;

   struct curry_arguments {};
   struct try_to_invoke_function : curry_arguments {};

   template < typename... Args >
   auto dispatch( try_to_invoke_function , Args&&... args ) const -> decltype( f_(args...) )
   {  return  f_( std::forward<Args>(args)... );  }

   template < typename... Args >
   auto dispatch( curry_arguments , Args&&... args ) const -> decltype( curry( f_ , std::forward<Args>(args)... ) )
   { return  curry( f_ , std::forward<Args>(args)... ); }

   template < std::size_t... Ns , typename... Other_args >
   auto call( std::index_sequence<Ns...> , Other_args&&... other_args )
   {  return dispatch( try_to_invoke_function{} , std::get<Ns>(args_)... , std::forward<Other_args>(other_args)... );  }

public:

   Currying_binder( Function const &f , Bound_args&&... as )
   : f_(f) , args_( std::forward<Bound_args>(as)...) {}

   template < typename... Other_args >
   auto operator()( Other_args&&... other_args )
   {
      return  call( std::make_index_sequence<sizeof...(Bound_args)>()
                  , std::forward<Other_args>(other_args)... );
   }

};

template < typename Function , typename... Args >
auto curry( Function&& f , Args&&... args )
{
   return Currying_binder<Function,Args...>( f , std::forward<Args>(args)... );
}

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR( FUNCTOR , FUNCTION_TEMPLATE )                        \
namespace {                                                                    \
   struct {                                                                    \
      template < typename V1 , typename V2 >                                   \
      auto operator()( V1&& v1 , V2&& v2 ) const                               \
      {                                                                        \
         return FUNCTION_TEMPLATE( std::forward<V1>(v1)                        \
                                 , std::forward<V2>(v2) );                     \
      }                                                                        \
   }                                                                           \
   FUNCTOR;                                                                    \
}                                                                              \

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR2( FUNCTOR , FUNCTION_TEMPLATE )                       \
namespace {                                                                    \
   auto FUNCTOR = []( auto&& v1 , auto&& v2 )                                  \
   {                                                                           \
      return FUNCTION_TEMPLATE( std::forward<decltype(v1)>(v1)                 \
                              , std::forward<decltype(v2)>(v2) );              \
   };                                                                          \
}                                                                              \

//   ----------------------------------------------------------------------------

#define MAKE_TPL_FUNCTOR3( FUNCTOR , FUNCTION_TEMPLATE )                       \
namespace {                                                                    \
   auto FUNCTOR = []( auto&&... vs )                                           \
   {                                                                           \
      return FUNCTION_TEMPLATE( std::forward<decltype(vs)>(vs) );              \
   };                                                                          \
}                                                                              \

//   ----------------------------------------------------------------------------

#define CURRY( CURRY_FUNCTION , FUNCTION_TEMPLATE )                            \
   MAKE_TPL_FUNCTOR2( FUNCTION_TEMPLATE##__CURRYFIED____ , FUNCTION_TEMPLATE ) \
   auto CURRY_FUNCTION  =  curry( FUNCTION_TEMPLATE##__CURRYFIED____ );        \

template < typename Value1 , typename Value2 >//, requires< is_addable<Value1,Value2>()... >
auto add_impl( Value1 const & v1 , Value2 const & v2 )
{
   return v1 + v2;
}

CURRY( add , add_impl );

auto sub  = curry( [](auto x , auto y) { return x-y; } );
auto mul3 = curry( [](auto x , auto y , auto z) { return x*y*z; } );

#include <cassert>
using namespace std;

int main()
{
   auto add3to = add(3);
   assert( add3to(4) == 7 );
   assert( add(3)(4) == 7 );
   assert( add(3, 4) == 7 );

   auto subfrom8 = sub(8);
   assert( subfrom8(3) == 5 );
   assert( sub(8)(3)   == 5 );
   assert( sub(8, 3)   == 5 );

   assert( mul3(1)(2,3)        == 6 );
   assert( mul3(1,2)(3)        == 6 );
   assert( mul3(1)(2)(3)       == 6 );
   assert( mul3()(1)()(2)()(3) == 6 );
}
<|endoftext|>


<commit_before>#include <cstring>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

#include "canvas/Utilities/InputTag.h"
#include "canvas/Persistency/Common/Assns.h"
#include "canvas/Persistency/Provenance/EventAuxiliary.h"
#include "gallery/Event.h"
#include "gallery/ValidHandle.h"
#include "lardataobj/RecoBase/Cluster.h"
#include "lardataobj/RecoBase/Vertex.h"
#include "lardataobj/RecoBase/Hit.h"
#include "lardataobj/MCBase/MCHitCollection.h"

#include "h5fnal.h"

#define MASTER_RUN_CONTAINER    "master_run_container"
#define BADNAME                 "REPLACEME"     // TODO: Replace this with a good name

using namespace art;
using namespace std;

int main(int argc, char* argv[]) {

  size_t totalHits = 0L;
  hid_t   fid 		= H5FNAL_BAD_HID_T;
  hid_t   fapl_id 	= H5FNAL_BAD_HID_T;
  hid_t   master_id = H5FNAL_BAD_HID_T;
  hid_t   run_id 	= H5FNAL_BAD_HID_T;
  hid_t   subrun_id = H5FNAL_BAD_HID_T;
  hid_t   event_id 	= H5FNAL_BAD_HID_T;
  int prevRun 		= -1;
  int prevSubRun 	= -1;
  h5fnal_vect_hitcoll_t *h5vmchc = NULL;

  InputTag mchits_tag { "mchitfinder" };
  InputTag vertex_tag { "linecluster" };
  InputTag assns_tag  { "linecluster" };

  vector<string> filenames { argv+1, argv+argc }; // filenames from command line
  if (2 != filenames.size()) {
    std::cerr << "Please supply input and output filenames\n";
    exit(EXIT_FAILURE);
  }

  /* Create the HDF5 file */
  string h5FileName = filenames.back();
  filenames.pop_back();
  if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
    H5FNAL_HDF5_ERROR;
  if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
    H5FNAL_HDF5_ERROR;
  if ((fid = H5Fcreate(h5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
    H5FNAL_HDF5_ERROR;

  /* Create a top-level containing group in which creation order is tracked and indexed.
   * There is no way to do this in the root group, so we can't use that.
   */
  if ((master_id = h5fnal_create_run(fid, MASTER_RUN_CONTAINER, FALSE)) < 0)
    H5FNAL_PROGRAM_ERROR("could not create master run containing group");

  /* Allocate memory for the data product struct
   *
   * This will be re-used for all data products we read in root and create
   * in HDF5 (it's re-initialized on close).
   */
  if (NULL == (h5vmchc = (h5fnal_vect_hitcoll_t *)calloc(1, sizeof(h5fnal_vect_hitcoll_t))))
    H5FNAL_PROGRAM_ERROR("could not get memory for HDF5 data product struct");

  // The gallery::Event object acts as a cursor into the stream of events.
  // A newly-constructed gallery::Event is at the start if its stream.
  // Use gallery::Event::atEnd() to check if you've reached the end of the stream.
  // Use gallery::Event::next() to go to the next event.

  // Loop over all the events in the root file
  for (gallery::Event ev(filenames); !ev.atEnd(); ev.next()) {

    vector<h5fnal_hit_t> hits;
    vector<h5fnal_hitcoll_t> hit_collections;
    auto const& aux = ev.eventAuxiliary();
    hsize_t first_hit;
    h5fnal_vect_hitcoll_data_t hc_data;

    std::cout << "Processing event: " << aux.run()
              << ',' << aux.subRun()
              << ',' << aux.event() << '\n';

    unsigned int currentRun = aux.run();
    unsigned int currentSubRun = aux.subRun();

    if ((int)currentRun != prevRun) {
      // Create a new run (create name from the integer ID)
      if (run_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(run_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close run")

      if ((run_id = h5fnal_create_run(master_id, std::to_string(currentRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create run");

      // Create a new sub-run (create name from the integer ID)
      if (subrun_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(subrun_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close sub-run");

      if ((subrun_id = h5fnal_create_run(run_id, std::to_string(currentSubRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create sub-run");

      prevRun = currentRun;
      prevSubRun = currentSubRun;
    }
    else if ((int)currentSubRun != prevSubRun) {
      // make new group for SubRun in the same run
      if (subrun_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(subrun_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close sub-run");

      if ((subrun_id = h5fnal_create_run(run_id, std::to_string(currentSubRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create sub-run");

      prevSubRun = currentSubRun;
    }

    // Create a new event (create name from the integer ID)
    unsigned int currentEvent = aux.event();
    if ((event_id = h5fnal_create_event(subrun_id, std::to_string(currentEvent).c_str(), FALSE)) < 0)
      H5FNAL_PROGRAM_ERROR("could not create event");

    // getValidHandle() is preferred to getByLabel(), for both art and
    // gallery use. It does not require in-your-face error handling.
    // art::Assns<recob::Cluster, recob::Hit> const& clusters_hits = *ev.getValidHandle<art::Assns<recob::Cluster, recob::Hit>>(assns_tag);
    auto const& clusters_hits =  *ev.getValidHandle<art::Assns<recob::Cluster, recob::Hit>>(assns_tag);

    // Create the Vector of MC Hit Collection via h5fnal.
    // This will create a group containing datasets. The name for this group should be something like:
    // "MCHitCollections_mchitfinder_"
    // The empty string following the 2nd underscore indicates and empty 'product instance name'.
    // There is no need to represent the 'process name' because that is a top-level of the file entity -- in the root group.
    // TODO: Update the name (using a cheap, hard-coded name for now)
#if 0
    if (h5fnal_create_v_mc_hit_collection(event_id, BADNAME, h5vmchc) < 0)
      H5FNAL_PROGRAM_ERROR("could not create HDF5 data product");

    // Process all MC Hit Collections
    first_hit = 0;
    for (auto const& p : clusters_hits) {
      h5fnal_hitcoll_t hc;
      hsize_t hitcount = 0;

      // Iterate through all hits
      for (sim::MCHit const& hit : hitcol) {
        h5fnal_hit_t h5hit;

        h5hit.signal_time 	= hit.PeakTime();
        h5hit.signal_width	= hit.PeakWidth();
        h5hit.peak_amp 		= hit.Charge(true);
        h5hit.charge 		= hit.Charge(false);
        h5hit.part_vertex_x	= (hit.PartVertex())[0];
        h5hit.part_vertex_y 	= (hit.PartVertex())[1];
        h5hit.part_vertex_z 	= (hit.PartVertex())[2];
        h5hit.part_energy 	= hit.PartEnergy();
        h5hit.part_track_id 	= hit.PartTrackId();

        hitcount++;
        hits.push_back(h5hit);
      } /* end loop over hits */

      hc.channel = hitcol.Channel();
      hc.count = hitcount;
      hc.start = (hitcount > 0) ? first_hit : 0;
      hit_collections.push_back(hc);

      first_hit += hitcount;

    } /* end loop over hit collections */

    // Write the data to the HDF5 data product
    hc_data.n_hits = hits.size();
    hc_data.n_hit_collections = hit_collections.size();
    hc_data.hits = &hits[0];
    hc_data.hit_collections = &hit_collections[0];

    if (h5fnal_append_hits(h5vmchc, &hc_data) < 0)
      H5FNAL_PROGRAM_ERROR("could not write hits to the HDF5 data product");

    totalHits += hits.size();
    cout << "Wrote " << hits.size() << " hits to the HDF5 file." << endl;

    /* Close the event and HDF5 data product */
    if (h5fnal_close_v_mc_hit_collection(h5vmchc) < 0)
      H5FNAL_PROGRAM_ERROR("could not close HDF5 data product");
#endif
    if (h5fnal_close_event(event_id) < 0)
      H5FNAL_PROGRAM_ERROR("could not close event");
  }

  /* Clean up */
  if (H5Pclose(fapl_id) < 0)
    H5FNAL_HDF5_ERROR;
  if (H5Fclose(fid) < 0)
    H5FNAL_HDF5_ERROR;
  if (h5fnal_close_run(master_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close master run container")
  // These will still be open after the loop.
  if (h5fnal_close_run(run_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close run")
  if (h5fnal_close_run(subrun_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close sub-run")

  free(h5vmchc);

  cout << "Wrote " << totalHits << " TOTAL hits to the HDF5 file." << endl;
  std::cout << "*** SUCCESS ***\n";
  exit(EXIT_SUCCESS);

error:

  H5E_BEGIN_TRY {
    H5Pclose(fapl_id);
    H5Fclose(fid);
    h5fnal_close_run(run_id);
    h5fnal_close_run(subrun_id);
    h5fnal_close_event(event_id);
    h5fnal_close_run(master_id);
    h5fnal_close_v_mc_hit_collection(h5vmchc);
  } H5E_END_TRY;

  free(h5vmchc);

  std::cout << "*** FAILURE ***\n";
  exit(EXIT_FAILURE);
}
<commit_msg>Updated assns_write, but it's still not finished.<commit_after>#include <cstring>
#include <iostream>
#include <iterator>
#include <numeric>
#include <string>
#include <vector>

#include "canvas/Utilities/InputTag.h"
#include "canvas/Persistency/Common/Assns.h"
#include "canvas/Persistency/Provenance/EventAuxiliary.h"
#include "gallery/Event.h"
#include "gallery/ValidHandle.h"
#include "lardataobj/RecoBase/Cluster.h"
#include "lardataobj/RecoBase/Vertex.h"
#include "lardataobj/RecoBase/Hit.h"
#include "lardataobj/MCBase/MCHitCollection.h"

#include "h5fnal.h"

#define MASTER_RUN_CONTAINER    "master_run_container"
#define BADNAME                 "ASSNS"         // TODO: Replace this with a better name

using namespace art;
using namespace std;

int main(int argc, char* argv[]) {

  size_t totalHits = 0L;
  hid_t   fid 		= H5FNAL_BAD_HID_T;
  hid_t   fapl_id 	= H5FNAL_BAD_HID_T;
  hid_t   master_id = H5FNAL_BAD_HID_T;
  hid_t   run_id 	= H5FNAL_BAD_HID_T;
  hid_t   subrun_id = H5FNAL_BAD_HID_T;
  hid_t   event_id 	= H5FNAL_BAD_HID_T;
  int prevRun 		= -1;
  int prevSubRun 	= -1;
  h5fnal_assns_t *h5assns = NULL;

  InputTag mchits_tag { "mchitfinder" };
  InputTag vertex_tag { "linecluster" };
  InputTag assns_tag  { "linecluster" };

  vector<string> filenames { argv+1, argv+argc }; // filenames from command line
  if (2 != filenames.size()) {
    std::cerr << "Please supply input and output filenames\n";
    exit(EXIT_FAILURE);
  }

  /* Create the HDF5 file */
  string h5FileName = filenames.back();
  filenames.pop_back();
  if ((fapl_id = H5Pcreate(H5P_FILE_ACCESS)) < 0)
    H5FNAL_HDF5_ERROR;
  if (H5Pset_libver_bounds(fapl_id, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST) < 0)
    H5FNAL_HDF5_ERROR;
  if ((fid = H5Fcreate(h5FileName.c_str(), H5F_ACC_TRUNC, H5P_DEFAULT, fapl_id)) < 0)
    H5FNAL_HDF5_ERROR;

  /* Create a top-level containing group in which creation order is tracked and indexed.
   * There is no way to do this in the root group, so we can't use that.
   */
  if ((master_id = h5fnal_create_run(fid, MASTER_RUN_CONTAINER, FALSE)) < 0)
    H5FNAL_PROGRAM_ERROR("could not create master run containing group");

  /* Allocate memory for the data product struct
   *
   * This will be re-used for all data products we read in root and create
   * in HDF5 (it's re-initialized on close).
   */
  if (NULL == (h5assns = (h5fnal_assns_t *)calloc(1, sizeof(h5fnal_assns_t))))
    H5FNAL_PROGRAM_ERROR("could not get memory for HDF5 data product struct");

  // The gallery::Event object acts as a cursor into the stream of events.
  // A newly-constructed gallery::Event is at the start if its stream.
  // Use gallery::Event::atEnd() to check if you've reached the end of the stream.
  // Use gallery::Event::next() to go to the next event.

  // Loop over all the events in the root file
  for (gallery::Event ev(filenames); !ev.atEnd(); ev.next()) {

    auto const& aux = ev.eventAuxiliary();
    h5fnal_assns_data_t assns_data;

    std::cout << "Processing event: " << aux.run()
              << ',' << aux.subRun()
              << ',' << aux.event() << '\n';

    unsigned int currentRun = aux.run();
    unsigned int currentSubRun = aux.subRun();

    if ((int)currentRun != prevRun) {
      // Create a new run (create name from the integer ID)
      if (run_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(run_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close run")

      if ((run_id = h5fnal_create_run(master_id, std::to_string(currentRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create run");

      // Create a new sub-run (create name from the integer ID)
      if (subrun_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(subrun_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close sub-run");

      if ((subrun_id = h5fnal_create_run(run_id, std::to_string(currentSubRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create sub-run");

      prevRun = currentRun;
      prevSubRun = currentSubRun;
    }
    else if ((int)currentSubRun != prevSubRun) {
      // make new group for SubRun in the same run
      if (subrun_id != H5FNAL_BAD_HID_T)
        if (h5fnal_close_run(subrun_id) < 0)
          H5FNAL_PROGRAM_ERROR("could not close sub-run");

      if ((subrun_id = h5fnal_create_run(run_id, std::to_string(currentSubRun).c_str(), FALSE)) < 0)
        H5FNAL_PROGRAM_ERROR("could not create sub-run");

      prevSubRun = currentSubRun;
    }

    // Create a new event (create name from the integer ID)
    unsigned int currentEvent = aux.event();
    if ((event_id = h5fnal_create_event(subrun_id, std::to_string(currentEvent).c_str(), FALSE)) < 0)
      H5FNAL_PROGRAM_ERROR("could not create event");

    // getValidHandle() is preferred to getByLabel(), for both art and
    // gallery use. It does not require in-your-face error handling.
    // art::Assns<recob::Cluster, recob::Hit> const& clusters_hits = *ev.getValidHandle<art::Assns<recob::Cluster, recob::Hit>>(assns_tag);
    auto const& clusters_hits =  *ev.getValidHandle<art::Assns<recob::Cluster, recob::Hit>>(assns_tag);

    // Create the Assns via h5fnal.
    // The empty string following the 2nd underscore indicates and empty 'product instance name'.
    // There is no need to represent the 'process name' because that is a top-level of the file entity -- in the root group.
    // TODO: Update the name (using a cheap, hard-coded name for now)
    // TODO: What strings should LEFT and RIGHT be?
    if (h5fnal_create_assns(event_id, BADNAME, "recob::Cluster", "recob:Hit", H5T_NATIVE_INT, h5assns) < 0)
      H5FNAL_PROGRAM_ERROR("could not create HDF5 data product");

    // Process all Assns
    for (auto const& p : clusters_hits) {

    } /* end loop over Assns */

    /* Close the event and HDF5 data product */
    if (h5fnal_close_assns(h5assns) < 0)
      H5FNAL_PROGRAM_ERROR("could not close HDF5 data product");
    if (h5fnal_close_event(event_id) < 0)
      H5FNAL_PROGRAM_ERROR("could not close event");
  } /* End of loop over events */

  /* Clean up */
  if (H5Pclose(fapl_id) < 0)
    H5FNAL_HDF5_ERROR;
  if (H5Fclose(fid) < 0)
    H5FNAL_HDF5_ERROR;
  if (h5fnal_close_run(master_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close master run container")
  // These will still be open after the loop.
  if (h5fnal_close_run(run_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close run")
  if (h5fnal_close_run(subrun_id) < 0)
    H5FNAL_PROGRAM_ERROR("could not close sub-run")

  free(h5assns);

  cout << "Wrote " << totalHits << " TOTAL hits to the HDF5 file." << endl;
  std::cout << "*** SUCCESS ***\n";
  exit(EXIT_SUCCESS);

error:

  H5E_BEGIN_TRY {
    H5Pclose(fapl_id);
    H5Fclose(fid);
    h5fnal_close_run(run_id);
    h5fnal_close_run(subrun_id);
    h5fnal_close_event(event_id);
    h5fnal_close_run(master_id);
    h5fnal_close_assns(h5assns);
  } H5E_END_TRY;

  free(h5assns);

  std::cout << "*** FAILURE ***\n";
  exit(EXIT_FAILURE);
}

<|endoftext|>


<commit_before><commit_msg>update get_account_history_by_operations<commit_after><|endoftext|>


<commit_before><commit_msg>SWDEV-86035 - Update the new DOPP flag in PAL interface<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2016 Hewlett Packard Enterprise Development LP
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "interface/standard/Interface.h"

#include <cassert>

#include "application/Application.h"
#include "interface/standard/InputQueue.h"
#include "interface/standard/MessageReassembler.h"
#include "interface/standard/Ejector.h"
#include "interface/standard/PacketReassembler.h"
#include "types/MessageOwner.h"
#include "types/Credit.h"

namespace Standard {

Interface::Interface(const std::string& _name, const Component* _parent,
                     u32 _id, Json::Value _settings)
    : ::Interface(_name, _parent, _id, _settings) {
  u32 initCredits = _settings["init_credits"].asUInt();
  assert(initCredits > 0);

  inputQueues_.resize(numVcs_);
  crossbar_ = new Crossbar("Crossbar", this, numVcs_, 1, _settings["crossbar"]);
  crossbarScheduler_ = new CrossbarScheduler(
      "CrossbarScheduler", this, numVcs_, numVcs_, 1,
      _settings["crossbar_scheduler"]);

  for (u32 vc = 0; vc < numVcs_; vc++) {
    // initialize the credit count in the CrossbarScheduler
    crossbarScheduler_->initCreditCount(vc, initCredits);

    // create the input queue
    inputQueues_.at(vc) = new InputQueue(
        "InputQueue_" + std::to_string(vc), this, crossbarScheduler_, vc,
        crossbar_, vc, vc);

    // link queue to scheduler
    crossbarScheduler_->setClient(vc, inputQueues_.at(vc));
  }

  ejector_ = new Ejector("Ejector", this);
  crossbar_->setReceiver(0, ejector_, 0);

  // create packet reassemblers
  packetReassemblers_.resize(numVcs_);
  for (u32 vc = 0; vc < numVcs_; vc++) {
    std::string tname = "PacketReassembler_" + std::to_string(vc);
    packetReassemblers_.at(vc) = new PacketReassembler(tname, this);
  }

  // create message reassembler
  messageReassembler_ = new MessageReassembler("MessageReassembler", this);
}

Interface::~Interface() {
  delete ejector_;
  delete crossbarScheduler_;
  delete crossbar_;
  for (u32 i = 0; i < numVcs_; i++) {
    delete inputQueues_.at(i);
    delete packetReassemblers_.at(i);
  }
  delete messageReassembler_;
}

void Interface::setInputChannel(Channel* _channel) {
  inputChannel_ = _channel;
  _channel->setSink(this, 0);
}

void Interface::setOutputChannel(Channel* _channel) {
  outputChannel_ = _channel;
  _channel->setSource(this, 0);
}

void Interface::receiveMessage(Message* _message) {
  dbgprintf("received message from terminal");
  assert(_message != nullptr);
  u64 now = gSim->time();

  // push all flits into the corresponding input queue
  for (u32 p = 0; p < _message->numPackets(); p++) {
    Packet* packet = _message->getPacket(p);
    u32 pktVc = packet->getFlit(0)->getVc();
    for (u32 f = 0; f < packet->numFlits(); f++) {
      Flit* flit = packet->getFlit(f);
      flit->setSendTime(now);
      u32 vc = flit->getVc();
      assert(vc == pktVc);
      inputQueues_.at(vc)->receiveFlit(flit);
    }
  }
}

void Interface::receiveFlit(u32 _port, Flit* _flit) {
  assert(_port == 0);
  assert(_flit != nullptr);

  // send credit
  Control* ctrl = inputChannel_->getNextControl();
  Credit* cred;
  if (ctrl == nullptr) {
    cred = new Credit(numVcs_);
    inputChannel_->setNextControl(cred);
  } else {
    cred = dynamic_cast<Credit*>(ctrl);
    assert(cred);
  }
  cred->putNum(_flit->getVc());

  // check destination is correct
  u32 dest = _flit->getPacket()->getMessage()->getDestinationId();
  assert(dest == getId());

  // mark the receive time
  _flit->setReceiveTime(gSim->time());

  // process flit, attempt to create packet
  Packet* packet = packetReassemblers_.at(_flit->getVc())->receiveFlit(_flit);
  // if a packet was completed, process it
  if (packet) {
    // process packet, attempt to create message
    Message* message = messageReassembler_->receivePacket(packet);
    if (message) {
      getMessageReceiver()->receiveMessage(message);
    }
  }
}

void Interface::receiveControl(u32 _port, Control* _control) {
  assert(_port == 0);
  Credit* cred = dynamic_cast<Credit*>(_control);
  assert(cred);
  while (cred->more()) {
    u32 vc = cred->getNum();
    crossbarScheduler_->incrementCreditCount(vc);
  }
  delete _control;
}

void Interface::sendFlit(Flit* _flit) {
  assert(outputChannel_->getNextFlit() == nullptr);
  outputChannel_->setNextFlit(_flit);
}

}  // namespace Standard
<commit_msg>added dbgprintf to standard::Interface.cc<commit_after>/*
 * Copyright 2016 Hewlett Packard Enterprise Development LP
 *
 * Licensed under the Apache License, Version 2.0 (the 'License');
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include "interface/standard/Interface.h"

#include <cassert>

#include "application/Application.h"
#include "interface/standard/InputQueue.h"
#include "interface/standard/MessageReassembler.h"
#include "interface/standard/Ejector.h"
#include "interface/standard/PacketReassembler.h"
#include "types/MessageOwner.h"
#include "types/Credit.h"

namespace Standard {

Interface::Interface(const std::string& _name, const Component* _parent,
                     u32 _id, Json::Value _settings)
    : ::Interface(_name, _parent, _id, _settings) {
  u32 initCredits = _settings["init_credits"].asUInt();
  assert(initCredits > 0);

  inputQueues_.resize(numVcs_);
  crossbar_ = new Crossbar("Crossbar", this, numVcs_, 1, _settings["crossbar"]);
  crossbarScheduler_ = new CrossbarScheduler(
      "CrossbarScheduler", this, numVcs_, numVcs_, 1,
      _settings["crossbar_scheduler"]);

  for (u32 vc = 0; vc < numVcs_; vc++) {
    // initialize the credit count in the CrossbarScheduler
    crossbarScheduler_->initCreditCount(vc, initCredits);

    // create the input queue
    inputQueues_.at(vc) = new InputQueue(
        "InputQueue_" + std::to_string(vc), this, crossbarScheduler_, vc,
        crossbar_, vc, vc);

    // link queue to scheduler
    crossbarScheduler_->setClient(vc, inputQueues_.at(vc));
  }

  ejector_ = new Ejector("Ejector", this);
  crossbar_->setReceiver(0, ejector_, 0);

  // create packet reassemblers
  packetReassemblers_.resize(numVcs_);
  for (u32 vc = 0; vc < numVcs_; vc++) {
    std::string tname = "PacketReassembler_" + std::to_string(vc);
    packetReassemblers_.at(vc) = new PacketReassembler(tname, this);
  }

  // create message reassembler
  messageReassembler_ = new MessageReassembler("MessageReassembler", this);
}

Interface::~Interface() {
  delete ejector_;
  delete crossbarScheduler_;
  delete crossbar_;
  for (u32 i = 0; i < numVcs_; i++) {
    delete inputQueues_.at(i);
    delete packetReassemblers_.at(i);
  }
  delete messageReassembler_;
}

void Interface::setInputChannel(Channel* _channel) {
  inputChannel_ = _channel;
  _channel->setSink(this, 0);
}

void Interface::setOutputChannel(Channel* _channel) {
  outputChannel_ = _channel;
  _channel->setSource(this, 0);
}

void Interface::receiveMessage(Message* _message) {
  dbgprintf("received message from terminal");
  assert(_message != nullptr);
  u64 now = gSim->time();

  // push all flits into the corresponding input queue
  for (u32 p = 0; p < _message->numPackets(); p++) {
    Packet* packet = _message->getPacket(p);
    u32 pktVc = packet->getFlit(0)->getVc();
    for (u32 f = 0; f < packet->numFlits(); f++) {
      Flit* flit = packet->getFlit(f);
      flit->setSendTime(now);
      u32 vc = flit->getVc();
      assert(vc == pktVc);
      inputQueues_.at(vc)->receiveFlit(flit);
    }
  }
}

void Interface::receiveFlit(u32 _port, Flit* _flit) {
  dbgprintf("port = %u", _port);

  assert(_port == 0);
  assert(_flit != nullptr);

  // send credit
  Control* ctrl = inputChannel_->getNextControl();
  Credit* cred;
  if (ctrl == nullptr) {
    cred = new Credit(numVcs_);
    inputChannel_->setNextControl(cred);
  } else {
    cred = dynamic_cast<Credit*>(ctrl);
    assert(cred);
  }
  cred->putNum(_flit->getVc());

  // check destination is correct
  u32 dest = _flit->getPacket()->getMessage()->getDestinationId();
  assert(dest == getId());

  // mark the receive time
  _flit->setReceiveTime(gSim->time());

  // process flit, attempt to create packet
  Packet* packet = packetReassemblers_.at(_flit->getVc())->receiveFlit(_flit);
  // if a packet was completed, process it
  if (packet) {
    // process packet, attempt to create message
    Message* message = messageReassembler_->receivePacket(packet);
    if (message) {
      getMessageReceiver()->receiveMessage(message);
    }
  }
}

void Interface::receiveControl(u32 _port, Control* _control) {
  assert(_port == 0);
  Credit* cred = dynamic_cast<Credit*>(_control);
  assert(cred);
  while (cred->more()) {
    u32 vc = cred->getNum();
    dbgprintf("port = %u, vc = %u", _port, vc);
    crossbarScheduler_->incrementCreditCount(vc);
  }
  delete _control;
}

void Interface::sendFlit(Flit* _flit) {
  assert(outputChannel_->getNextFlit() == nullptr);
  outputChannel_->setNextFlit(_flit);
}

}  // namespace Standard
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_INTRUSIVE_PTR_BASE
#define TORRENT_INTRUSIVE_PTR_BASE

#include <boost/detail/atomic_count.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	template<class T>
	struct intrusive_ptr_base
	{
		intrusive_ptr_base(intrusive_ptr_base<T> const&)
			: m_refs(0) {}

		friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
		{
			assert(s->m_refs >= 0);
			assert(s != 0);
			++s->m_refs;
		}

		friend void intrusive_ptr_release(intrusive_ptr_base<T> const* s)
		{
			assert(s->m_refs > 0);
			assert(s != 0);
			if (--s->m_refs == 0)
				delete static_cast<T const*>(s);
		}

		boost::intrusive_ptr<T> self()
		{ return boost::intrusive_ptr<T>((T*)this); }

		boost::intrusive_ptr<const T> self() const
		{ return boost::intrusive_ptr<const T>((T const*)this); }

		int refcount() const { return m_refs; }

		intrusive_ptr_base(): m_refs(0) {}
	private:
		// reference counter for intrusive_ptr
		mutable boost::detail::atomic_count m_refs;
	};

}

#endif

<commit_msg>fix to make torrent_info assignable<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_INTRUSIVE_PTR_BASE
#define TORRENT_INTRUSIVE_PTR_BASE

#include <boost/detail/atomic_count.hpp>
#include "libtorrent/config.hpp"
#include "libtorrent/assert.hpp"

namespace libtorrent
{
	template<class T>
	struct intrusive_ptr_base
	{
		intrusive_ptr_base(intrusive_ptr_base<T> const&)
			: m_refs(0) {}

		intrusive_ptr_base& operator=(intrusive_ptr_base const& rhs) {}

		friend void intrusive_ptr_add_ref(intrusive_ptr_base<T> const* s)
		{
			assert(s->m_refs >= 0);
			assert(s != 0);
			++s->m_refs;
		}

		friend void intrusive_ptr_release(intrusive_ptr_base<T> const* s)
		{
			assert(s->m_refs > 0);
			assert(s != 0);
			if (--s->m_refs == 0)
				delete static_cast<T const*>(s);
		}

		boost::intrusive_ptr<T> self()
		{ return boost::intrusive_ptr<T>((T*)this); }

		boost::intrusive_ptr<const T> self() const
		{ return boost::intrusive_ptr<const T>((T const*)this); }

		int refcount() const { return m_refs; }

		intrusive_ptr_base(): m_refs(0) {}
	private:
		// reference counter for intrusive_ptr
		mutable boost::detail::atomic_count m_refs;
	};

}

#endif

<|endoftext|>