- m_fail = false;
- m_nPoints = n;
- m_xmin = xmin;
- m_xmax = xmax;
- m_vecFilter = new double[n];
-
- double xinc = (m_xmax - m_xmin) / (m_nPoints - 1);
-
- if (m_idFilter == FILTER_SHEPP) {
- double a = 2 * m_bw;
- double c = - 4. / (a * a);
- int center = (m_nPoints - 1) / 2;
- int sidelen = center;
- m_vecFilter[center] = 4. / (a * a);
-
- for (int i = 1; i <= sidelen; i++ )
- m_vecFilter [center + i] = m_vecFilter [center - i] = c / (4 * (i * i) - 1);
- } else if (m_idDomain == DOMAIN_FREQ) {
- double x;
- int i;
- for (x = m_xmin, i = 0; i < m_nPoints; x += xinc, i++)
- m_vecFilter[i] = frequencyResponse (x, param);
- } else if (m_idDomain == DOMAIN_SPATIAL) {
- double x;
- int i;
- for (x = m_xmin, i = 0; i < m_nPoints; x += xinc, i++)
- if (numint == 0)
- m_vecFilter[i] = spatialResponseAnalytic (x, param);
- else
- m_vecFilter[i] = spatialResponseCalc (x, param, numint);
- } else {
- sys_error (ERR_WARNING, "Illegal domain %d [filt_generate]", m_idDomain);
+ m_nameFilterMethod = convertFilterMethodIDToName (m_idFilterMethod);
+ m_nSignalPoints = nSignalPoints;
+ m_signalInc = signalIncrement;
+ m_filterParam = filterParam;
+ m_zeropad = zeropad;
+ m_preinterpolationFactor = preinterpolationFactor;
+
+ m_vecFourierCosTable = NULL;
+ m_vecFourierSinTable = NULL;
+ m_vecFilter = NULL;
+
+ if (m_idFilterMethod == FILTER_METHOD_FFT) {
+#if HAVE_FFTW
+ m_idFilterMethod = FILTER_METHOD_RFFTW;
+#else
+ m_fail = true;
+ m_failMessage = "FFT not yet implemented";
+ return;
+#endif
+ }
+
+ if (m_idFilterMethod == FILTER_METHOD_FOURIER || m_idFilterMethod == FILTER_METHOD_FOURIER_TABLE || m_idFilterMethod == FILTER_METHOD_FFT
+#if HAVE_FFTW
+ || m_idFilterMethod == FILTER_METHOD_FFTW || m_idFilterMethod == FILTER_METHOD_RFFTW
+#endif
+ ) {
+ m_nFilterPoints = m_nSignalPoints;
+ if (m_zeropad > 0) {
+ double logBase2 = log(m_nSignalPoints) / log(2);
+ int nextPowerOf2 = static_cast<int>(floor(logBase2));
+ if (logBase2 != floor(logBase2))
+ nextPowerOf2++;
+ nextPowerOf2 += (m_zeropad - 1);
+ m_nFilterPoints = 1 << nextPowerOf2;
+ if (m_traceLevel >= TRACE_TEXT)
+ cout << "nFilterPoints = " << m_nFilterPoints << endl;
+ }
+ m_nOutputPoints = m_nFilterPoints * m_preinterpolationFactor;
+ m_filterMin = -1. / (2 * m_signalInc);
+ m_filterMax = 1. / (2 * m_signalInc);
+ m_filterInc = (m_filterMax - m_filterMin) / m_nFilterPoints;
+ m_vecFilter = new double [m_nFilterPoints];
+ int halfFilter = m_nFilterPoints / 2;
+ for (int i = 0; i <= halfFilter; i++)
+ m_vecFilter[i] = static_cast<double>(i) / halfFilter/ (2. * m_signalInc);
+ for (int i = 1; i <= halfFilter; i++)
+ m_vecFilter[m_nFilterPoints - i] = static_cast<double>(i) / halfFilter / (2. * m_signalInc);
+ }
+
+ // precalculate sin and cosine tables for fourier transform
+ if (m_idFilterMethod == FILTER_METHOD_FOURIER_TABLE) {
+ int nFourier = max(m_nFilterPoints,m_nOutputPoints) * max(m_nFilterPoints, m_nOutputPoints) + 1;
+ double angleIncrement = (2. * PI) / m_nFilterPoints;
+ m_vecFourierCosTable = new double[ nFourier ];
+ m_vecFourierSinTable = new double[ nFourier ];
+ double angle = 0;
+ for (int i = 0; i < nFourier; i++) {
+ m_vecFourierCosTable[i] = cos (angle);
+ m_vecFourierSinTable[i] = sin (angle);
+ angle += angleIncrement;
+ }
+ }
+
+#if HAVE_FFTW
+ if (m_idFilterMethod == FILTER_METHOD_FFTW || m_idFilterMethod == FILTER_METHOD_RFFTW) {
+ for (int i = 0; i < m_nFilterPoints; i++) //fftw uses unnormalized fft
+ m_vecFilter[i] /= m_nFilterPoints;
+ }
+
+ if (m_idFilterMethod == FILTER_METHOD_RFFTW) {
+ m_realPlanForward = rfftw_create_plan (m_nFilterPoints, FFTW_REAL_TO_COMPLEX, FFTW_ESTIMATE);
+ m_realPlanBackward = rfftw_create_plan (m_nOutputPoints, FFTW_COMPLEX_TO_REAL, FFTW_ESTIMATE);
+ m_vecRealFftInput = new fftw_real [ m_nFilterPoints ];
+ m_vecRealFftSignal = new fftw_real [ m_nOutputPoints ];
+ for (int i = 0; i < m_nFilterPoints; i++)
+ m_vecRealFftInput[i] = 0;
+ } else if (m_idFilterMethod == FILTER_METHOD_FFTW) {
+ m_complexPlanForward = fftw_create_plan (m_nFilterPoints, FFTW_FORWARD, FFTW_ESTIMATE);
+ m_complexPlanBackward = fftw_create_plan (m_nOutputPoints, FFTW_BACKWARD, FFTW_ESTIMATE);
+ m_vecComplexFftInput = new fftw_complex [ m_nFilterPoints ];
+ m_vecComplexFftSignal = new fftw_complex [ m_nOutputPoints ];
+ for (int i = 0; i < m_nFilterPoints; i++)
+ m_vecComplexFftInput[i].re = m_vecComplexFftInput[i].im = 0;
+ for (int i = 0; i < m_nOutputPoints; i++)
+ m_vecComplexFftSignal[i].re = m_vecComplexFftSignal[i].im = 0;
+ }
+#endif
+
+ if (m_idFilterMethod == FILTER_METHOD_CONVOLUTION) {
+ m_nFilterPoints = 2 * m_nSignalPoints - 1;
+ m_filterMin = -m_signalInc * (m_nSignalPoints - 1);
+ m_filterMax = m_signalInc * (m_nSignalPoints - 1);
+ m_filterInc = (m_filterMax - m_filterMin) / (m_nFilterPoints - 1);
+ m_vecFilter = new double[ m_nFilterPoints ];
+
+ if (m_idFilter == FILTER_SHEPP) {
+ double a = 2 * m_bw;
+ double c = - 4. / (a * a);
+ int center = (m_nFilterPoints - 1) / 2;
+ int sidelen = center;
+ m_vecFilter[center] = 4. / (a * a);
+
+ for (int i = 1; i <= sidelen; i++ )
+ m_vecFilter [center + i] = m_vecFilter [center - i] = c / (4 * (i * i) - 1);
+ } else if (m_idDomain == DOMAIN_FREQUENCY) {
+ double x;
+ int i;
+ for (x = m_filterMin, i = 0; i < m_nFilterPoints; x += m_filterInc, i++)
+ m_vecFilter[i] = frequencyResponse (x, m_filterParam);
+ } else if (m_idDomain == DOMAIN_SPATIAL) {
+ double x;
+ int i;
+ for (x = m_filterMin, i = 0; i < m_nFilterPoints; x += m_filterInc, i++)
+ if (haveAnalyticSpatial(m_idFilter))
+ m_vecFilter[i] = spatialResponseAnalytic (x, m_filterParam);
+ else
+ m_vecFilter[i] = spatialResponseCalc (x, m_filterParam);
+ } else {
+ m_failMessage = "Illegal domain name ";
+ m_failMessage += m_idDomain;