Пример #1
0
Vector_double stfnum::get_scale(Vector_double& data, double oldx) {
    Vector_double xyscale(4);

    if (data.size() == 0) {
        xyscale[0] = 1.0/oldx;
        xyscale[1] = 0.0;
        xyscale[2] = 1.0;
        xyscale[3] = 0.0;

        return xyscale;
    }

    double ymin,ymax,amp,off;

    ymin = *data.begin();
    ymax = ymin;
    for (Vector_double::iterator it = data.begin(); it != data.end(); ++it) {
        double v = *it;
        if (v < ymin) ymin = v;
        else if (ymax < v) ymax = v;
    }
    amp = ymax - ymin;
    off = ymin / amp;

    data = stfio::vec_scal_mul(data, 1.0 / amp);
    data = stfio::vec_scal_minus(data, off);

    xyscale[0] = 1.0/(data.size()*oldx);
    xyscale[1] = 0;
    xyscale[2] = 1.0/amp;
    xyscale[3] = off;
    
    return xyscale;
}
Пример #2
0
std::map<double, int>
stf::histogram(const Vector_double& data, int nbins) {

    if (nbins==-1) {
        nbins = int(data.size()/100.0);
    }

    double fmax = *std::max_element(data.begin(), data.end());
    double fmin = *std::min_element(data.begin(), data.end());
    fmax += (fmax-fmin)*1e-9;

    double bin = (fmax-fmin)/nbins;

    std::map<double,int> histo;
    for (int nbin=0; fmin + nbin*bin < fmax; ++nbin) {
        histo[fmin + nbin*bin] = 0;
    }
    for (std::size_t npoint=0; npoint < data.size(); ++npoint) {
        int nbin = int((data[npoint]-fmin) / bin);
        histo[fmin + nbin*bin]++;
    }
    return histo;
}
Пример #3
0
Vector_double
stf::deconvolve(const Vector_double& data, const Vector_double& templ,
                int SR, double hipass, double lopass, stfio::ProgressInfo& progDlg)
{
    bool skipped = false;
    progDlg.Update( 0, "Starting deconvolution...", &skipped );
    if (data.size()<=0 || templ.size() <=0 || templ.size() > data.size()) {
        std::out_of_range e("subscript out of range in stf::filter()");
        throw e;
    }
    /* pad templ */
    Vector_double templ_padded(data.size());
    std::copy(templ.begin(), templ.end(), templ_padded.begin());
    if (templ.size() < templ_padded.size()) {
        std::fill(templ_padded.begin()+templ.size(), templ_padded.end(), 0);
    }

    Vector_double data_return(data.size());
    if (skipped) {
        data_return.resize(0);
        return data_return;
    }

    double *in_data, *in_templ_padded;
    //fftw_complex is a double[2]; hence, out is an array of
    //double[2] with out[n][0] being the real and out[n][1] being
    //the imaginary part.
    fftw_complex *out_data, *out_templ_padded;
    fftw_plan p_data, p_templ, p_inv;

    //memory allocation as suggested by fftw:
    in_data =(double *)fftw_malloc(sizeof(double) * data.size());
    out_data = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * ((int)(data.size()/2)+1));
    in_templ_padded =(double *)fftw_malloc(sizeof(double) * templ_padded.size());
    out_templ_padded = (fftw_complex *)fftw_malloc(sizeof(fftw_complex) * ((int)(templ_padded.size()/2)+1));

    std::copy(data.begin(), data.end(), &in_data[0]);
    std::copy(templ_padded.begin(), templ_padded.end(), &in_templ_padded[0]);

    //plan the ffts and execute them:
    p_data =fftw_plan_dft_r2c_1d((int)data.size(), in_data, out_data,
                                 FFTW_ESTIMATE);
    fftw_execute(p_data);
    p_templ =fftw_plan_dft_r2c_1d((int)templ_padded.size(),
                                  in_templ_padded, out_templ_padded, FFTW_ESTIMATE);
    fftw_execute(p_templ);

    double SI=1.0/SR; //the sampling interval
    progDlg.Update( 25, "Performing deconvolution...", &skipped );
    if (skipped) {
        data_return.resize(0);
        return data_return;
    }
    Vector_double f_c(1);
    for (std::size_t n_point=0; n_point < (unsigned int)(data.size()/2)+1; ++n_point) {
        /* highpass filter */
        double f = n_point / (data.size()*SI);

        double rslt_hi = 1.0;
        if (hipass > 0) {
            f_c[0] = hipass;
            rslt_hi = 1.0-fgaussColqu(f, f_c);
        }

        /* lowpass filter */
        double rslt_lo = 1.0;
        if (lopass > 0) {
            f_c[0] = lopass;
            rslt_lo= fgaussColqu(f, f_c);
        }

        /* do the division in place */
        double a = out_data[n_point][0];
        double b = out_data[n_point][1];
        double c = out_templ_padded[n_point][0];
        double d = out_templ_padded[n_point][1];
        double mag2 = c*c + d*d;
        out_data[n_point][0] = rslt_hi * rslt_lo * (a*c + b*d)/mag2;
        out_data[n_point][1] = rslt_hi * rslt_lo * (b*c - a*d)/mag2;
    }

    //do the reverse fft:
    p_inv = fftw_plan_dft_c2r_1d((int)data.size(),out_data, in_data, FFTW_ESTIMATE);
    fftw_execute(p_inv);

    //fill the return array, adding the offset, and scaling by data.size()
    //(because fftw computes an unnormalized transform):
    for (std::size_t n_point=0; n_point < data.size(); ++n_point) {
        data_return[n_point]= in_data[n_point]/data.size();
    }

    fftw_destroy_plan(p_data);
    fftw_destroy_plan(p_templ);
    fftw_destroy_plan(p_inv);

    fftw_free(in_data);
    fftw_free(out_data);
    fftw_free(in_templ_padded);
    fftw_free(out_templ_padded);

    progDlg.Update( 50, "Computing data histogram...", &skipped );
    if (skipped) {
        data_return.resize(0);
        return data_return;
    }
    int nbins =  int(data_return.size()/500.0);
    std::map<double, int> histo = histogram(data_return, nbins);
    double max_value = -1;
    double max_time = 0;
    double maxhalf_time = 0;
    Vector_double histo_fit(0);
    for (std::map<double,int>::const_iterator it=histo.begin();
         it != histo.end(); ++it) {
        if (it->second > max_value) {
            max_value = it->second;
            max_time = it->first;
        }
        histo_fit.push_back(it->second);
#ifdef _STFDEBUG
        std::cout << it->first << "\t" << it->second << std::endl;
#endif
    }
    for (std::map<double,int>::const_iterator it=histo.begin();
         it != histo.end(); ++it) {
        if (it->second > 0.5*max_value) {
            maxhalf_time = it->first;
            break;
        }
    }
    maxhalf_time = fabs(max_time-maxhalf_time);
    progDlg.Update( 75, "Fitting Gaussian...", &skipped );
    if (skipped) {
        data_return.resize(0);
        return data_return;
    }
    /* Fit Gaussian to histogram */
    Vector_double opts = LM_default_opts();

    std::string info;
    int warning;
    std::vector< stf::storedFunc > funcLib = stf::GetFuncLib();
    
    double interval = (++histo.begin())->first-histo.begin()->first;
    /* Initial parameter guesses */
    Vector_double pars(3);
    pars[0] = max_value;
    pars[1] = (max_time - histo.begin()->first);
    pars[2] = maxhalf_time *sqrt(2.0)/2.35482;
#ifdef _STFDEBUG    
    std::cout << "nbins: " << nbins << std::endl;
    std::cout << "initial values:" << std::endl;
    for (std::size_t np=0; np<pars.size(); ++np) {
        std::cout << pars[np] << std::endl;
    }
#endif

#ifdef _STFDEBUG
    double chisqr =
#endif
        lmFit(histo_fit, interval, funcLib[funcLib.size()-1], opts, true,
              pars, info, warning );
#ifdef _STFDEBUG
    std::cout << chisqr << "\t" << interval << std::endl;
    std::cout << "final values:" << std::endl;
    for (std::size_t np=0; np<pars.size(); ++np) {
        std::cout << pars[np] << std::endl;
    }
#endif
    double sigma = pars[2]/sqrt(2.0);
    /* return data in terms of sigma */
    for (std::size_t n_point=0; n_point < data.size(); ++n_point) {
        data_return[n_point] /= sigma;
    }
    progDlg.Update( 100, "Done.", &skipped );
    return data_return;
}
Пример #4
0
Vector_double stfio::vec_vec_div(const Vector_double& vec1, const Vector_double& vec2) {
    Vector_double ret_vec(vec1.size());
    std::transform(vec1.begin(), vec1.end(), vec2.begin(), ret_vec.begin(), std::divides<double>());
    return ret_vec;
}
Пример #5
0
Vector_double stfio::vec_scal_div(const Vector_double& vec, double scalar) {
    Vector_double ret_vec(vec.size(), scalar);
    std::transform(vec.begin(), vec.end(), ret_vec.begin(), ret_vec.begin(), std::divides<double>());
    return ret_vec;
}