diff --git a/src/libCom/Makefile b/src/libCom/Makefile index 5cc4ff630..2a3b1b91a 100644 --- a/src/libCom/Makefile +++ b/src/libCom/Makefile @@ -224,11 +224,6 @@ SRC_DIRS += $(LIBCOM)/tsDefs INC += tsDefs.h SRCS += tsDefs.c -SRC_DIRS += $(LIBCOM)/math -SRCS += epicsFFT.cpp -INC += epicsDSP.h -INC += epicsTemplateFFT.h - # For WIN32 SRCS_WIN32 += dllmain.cpp SRCS_WIN32 += forceBadAllocException.cpp diff --git a/src/libCom/math/epicsDSP.h b/src/libCom/math/epicsDSP.h deleted file mode 100644 index f22ba80a6..000000000 --- a/src/libCom/math/epicsDSP.h +++ /dev/null @@ -1,42 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -/* - * Author: Jeff Hill - * Date: 9-29-03 - */ - -#ifndef epicsDSP_h -#define epicsDSP_h - -#ifdef __cplusplus - -#if !defined ( __GNUC__ ) || ( __GNUC__ > 2 || ( __GNUC__ == 2 && __GNUC_MINOR__ >= 95 ) ) - namespace std { - template < class T > class complex; - } -#else - template < class T > class complex; -#endif - -// -// One dimensional FFT computing template function -// -// vec[] Input Sequence replaced by output sequence -// ln Log base two of the number of point in vec -// inverse Inverse fft if true -// -template < class T > -void epicsOneDimFFT ( std::complex < T > vec[], - const unsigned ln, bool inverse ); - -#endif /* __cplusplus */ - -#endif /* epicsDSP_h */ - diff --git a/src/libCom/math/epicsFFT.cpp b/src/libCom/math/epicsFFT.cpp deleted file mode 100644 index ed011cbea..000000000 --- a/src/libCom/math/epicsFFT.cpp +++ /dev/null @@ -1,31 +0,0 @@ - -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// Simple fft computing functions -// -// Author: Jeff Hill -// Date: 9-29-03 -// - -#include - -#define epicsExportSharedSymbols -#include -#include - -// template epicsShareFunc void epicsShareAPI epicsOneDimFFT ( -// std::complex < float > vec[], -// const unsigned ln, bool inverse ); - -template epicsShareFunc void epicsShareAPI epicsOneDimFFT ( - std::complex < double > vec[], - const unsigned ln, bool inverse ); - diff --git a/src/libCom/math/epicsTemplateFFT.h b/src/libCom/math/epicsTemplateFFT.h deleted file mode 100644 index f1048d12c..000000000 --- a/src/libCom/math/epicsTemplateFFT.h +++ /dev/null @@ -1,78 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ - -// -// Author: Jeff Hill -// Date: 9-29-03 -// - -#ifndef epicsTemplateFFT_h -#define epicsTemplateFFT_h - -#include - -#include - -// -// Simple one dimensional FFT computing template function -// -// vec[] Input Sequence replaced by output sequence -// ln Log base two of the number of point in vec -// inverse Inverse fft if true -// -template < class T > -void epicsOneDimFFT ( std::complex < T > vec[], - const unsigned ln, bool inverse ) -{ - static const T one = 1.0; - static const T four = 4.0; - static const T PI = four * atan ( one ); - const unsigned n = 1u << ln; - const unsigned nv2 = n >> 1u; - - { - unsigned j = 1u; - - for ( unsigned i = 1; i < n; i++ ) { - if ( i < j ) { - std::complex < T > t = vec[i - 1]; - vec[i - 1] = vec[j - 1]; - vec[j - 1] = t; - } - unsigned k = nv2; - while ( k < j ) { - j = j - k; - k = k >> 1u; - } - j = j + k; - } - } - - const T sign = inverse ? 1.0 : -1.0; - for ( unsigned l = 1; l <= ln; l++ ) { - const unsigned le = 1u << l; - const unsigned le1 = le >> 1u; - const T radians = sign * PI / le1; - const std::complex < T > w = std::polar ( one, radians ); - std::complex < T > u ( 1, 0 ); - - for ( unsigned m = 1u; m <= le1; m++ ) { - for ( unsigned i = m - 1; i < n; i = i + le ) { - unsigned ip = i + le1; - std::complex < T > t0 = vec [ ip ] * u; - vec [ ip ] = vec [ i ] - t0; - vec [ i ] = vec [ i ] + t0; - } - u = u * w; - } - } -} - -#endif // epicsTemplateFFT_h - diff --git a/src/rec/Makefile b/src/rec/Makefile index e5f0fa24a..5a442c42d 100644 --- a/src/rec/Makefile +++ b/src/rec/Makefile @@ -46,7 +46,6 @@ DBDINC += stringoutRecord DBDINC += subRecord DBDINC += subArrayRecord DBDINC += waveformRecord -DBDINC += spectrumRecord LIBSRCS += aaiRecord.c LIBSRCS += aaoRecord.c @@ -80,7 +79,6 @@ LIBSRCS += stringoutRecord.c LIBSRCS += subRecord.c LIBSRCS += subArrayRecord.c LIBSRCS += waveformRecord.c -LIBSRCS += spectrumRecord.c LIBRARY_IOC += recIoc diff --git a/src/rec/spectrumRecord.cpp b/src/rec/spectrumRecord.cpp deleted file mode 100644 index 16cc92727..000000000 --- a/src/rec/spectrumRecord.cpp +++ /dev/null @@ -1,437 +0,0 @@ -/*************************************************************************\ -* Copyright (c) 2002 The University of Chicago, as Operator of Argonne -* National Laboratory. -* Copyright (c) 2002 The Regents of the University of California, as -* Operator of Los Alamos National Laboratory. -* Subject to a Software License Agreement found -* in file LICENSE that is included with this distribution. -\*************************************************************************/ -/* base/src/rec $Id$ */ - -/* - * spectrum analyzer record support routines - * - * Author: Jeff Hill - * Ancestry: Based on the waveform record by Bob Dalesio and Marty Kraimer - * Date: 9-29-03 - */ -#include -#include -#include -#include -#include -#include -#include - -#include "dbDefs.h" -#include "epicsPrint.h" -#include "alarm.h" -#include "dbAccess.h" -#include "dbEvent.h" -#include "dbFldTypes.h" -#include "dbScan.h" -#include "devSup.h" -#include "errMdef.h" -#include "recSup.h" -#include "recGbl.h" -#include "special.h" -#include "epicsDSP.h" - -typedef double fft_t; - -#define GEN_SIZE_OFFSET -#include "spectrumRecord.h" -#undef GEN_SIZE_OFFSET - -static const fft_t one = 1.0; -static const fft_t four = 4.0; -static const fft_t PI = four * atan ( one ); - -static void changeFrequencies ( struct spectrumRecord * pwf ) -{ - unsigned long L = 1ul << pwf->logl; - - // freq change is unsuccessful if improper input parameters - if ( pwf->hfrq <= pwf->lfrq ) { - pwf->frok = 0; - return; - } - if ( pwf->hfrq > pwf->ifrq / 2.0 ) { - pwf->frok = 0; - return; - } - if ( pwf->ifrq <= 0.0 ) { - pwf->frok = 0; - return; - } - - if ( ! ( pwf->g && pwf->h && pwf->ival && - pwf->mag && pwf->ang && pwf->hamw ) ) { - pwf->frok = 0; - return; - } - - const fft_t phi0d2 = ( PI / 2.0 / pwf->nelm ) * - ( pwf->hfrq - pwf->lfrq ) / pwf->ifrq ; - for ( unsigned n = 0; n < pwf->nelm; n++ ) - { - const fft_t nd = n; - const fft_t radians = nd * nd * phi0d2; - pwf->h[n] = std::polar ( one, radians ); - } - for ( unsigned n = pwf->nelm; n < L-pwf->nin; n++ ) - { - pwf->h[n] = std::complex < fft_t > ( 0.0, 0.0 ); - } - for ( unsigned n = L-pwf->nin; n < L; n++ ) - { - const fft_t index = L - n; - const fft_t radians = index * index * phi0d2; - pwf->h[n] = std::polar ( one, radians ); - } - epicsOneDimFFT ( pwf->h, pwf->logl, false ); - pwf->frok = true; -} - -static void changeResolution ( struct spectrumRecord * pwf ) -{ - { - long nElemInTmp; - long status = dbGetNelements ( - & pwf->inpw, & nElemInTmp ); - if ( status ) { - pwf->nin = 1; - } - else { - if ( nElemInTmp < 1 ) { - pwf->nin = 1; - } - else { - pwf->nin = static_cast < unsigned long > - ( nElemInTmp ); - } - } - } - - if ( pwf->nelm <= 0 ) - pwf->nelm = 1; - - { - double tot = pwf->nin + pwf->nelm; - double dblL = 1.0 + log ( tot ) / log ( 2.0 ); - pwf->logl = static_cast < unsigned long > ( dblL + 0.5 ); - } - - unsigned long L = 1ul << pwf->logl; - assert ( L >= pwf->nin + pwf->nelm ); - delete pwf->g; - delete pwf->h; - delete pwf->ival; - delete pwf->hamw; - delete pwf->mag; - delete pwf->ang; - try { - pwf->g = new std::complex < fft_t > [L]; - pwf->h = new std::complex < fft_t > [L]; - pwf->ival = new fft_t [pwf->nin]; - pwf->hamw = new fft_t [pwf->nin]; - pwf->mag = new fft_t [pwf->nelm]; - pwf->ang = new fft_t [pwf->nelm]; - // initialize hamming window - // see Oppenhiem and Schafer figure 5.33 - for ( unsigned long n = 0; n < pwf->nin; n++ ) - { - pwf->hamw[n] = 0.54 - 0.46 * - cos ( 2 * PI * n / ( pwf->nin - 1 ) ); - } - } - catch (... ) { - recGblSetSevr ( pwf, CALC_ALARM, INVALID_ALARM ); - pwf->frok = false; - return; - } - changeFrequencies ( pwf ); -} - -static long init_record ( struct spectrumRecord * pwf, int pass ) -{ - if ( pass == 1 ) { - changeResolution ( pwf ); - } - return 0; -} - -static long special ( struct dbAddr * paddr, int after ) -{ - struct spectrumRecord * pwf = - reinterpret_cast < struct spectrumRecord * > ( paddr->precord ); - long status = 0; - if ( after ) { - switch ( paddr->special ) { - case ( SPC_MOD ): - if ( paddr->pfield == (void *) & pwf->nelm || - paddr->pfield == (void *) & pwf->inpw ) { - changeResolution ( pwf ); - } - else { - changeFrequencies ( pwf ); - } - break; - default: - recGblDbaddrError ( S_db_badChoice, paddr, "spectrum: special" ); - status = S_db_badChoice; - break; - } - } - return status; -} - -static void monitor ( struct spectrumRecord *pwf ) -{ - unsigned short monitor_mask; - - monitor_mask = recGblResetAlarms(pwf); - monitor_mask |= ( DBE_LOG | DBE_VALUE ); - if ( monitor_mask ) { - db_post_events ( pwf, pwf->mag, monitor_mask ); - db_post_events ( pwf, pwf->ang, monitor_mask ); - } - return; -} - -static long process ( struct spectrumRecord * pwf ) -{ - if ( ! pwf->frok ) { - recGblSetSevr ( pwf, CALC_ALARM, INVALID_ALARM ); - return 0; - } - long nRequest = static_cast < long > ( pwf->nin ); - long status = dbGetLink ( & pwf->inpw, DBR_DOUBLE, - pwf->ival, 0, & nRequest ); - if ( status ) { - recGblSetSevr ( pwf, CALC_ALARM, INVALID_ALARM ); - return 0; - } - - unsigned long nActual; - if ( nRequest < 0 ) { - recGblSetSevr ( pwf, CALC_ALARM, INVALID_ALARM ); - return 0; - } - else { - nActual = static_cast < unsigned long > ( nRequest ); - } - - //epicsTime begin = epicsTime::getCurrent(); - - const unsigned L = 1 << pwf->logl; - - const fft_t phi0d2 = ( PI / 2.0 / pwf->nelm ) * - ( pwf->hfrq - pwf->lfrq ) / pwf->ifrq ; - const fft_t theta0 = PI * pwf->lfrq / pwf->ifrq; - - for ( unsigned long n = 0; n < nActual; n++ ) - { - const fft_t nd = n; - const fft_t psi = nd * theta0 + - nd * nd * phi0d2; - pwf->g[n] = pwf->ival[n] * pwf->hamw[n] * - std::polar ( one, - psi ); - } - for( unsigned long n = nActual ; n < L; n++ ) - { - pwf->g[n] = 0.0; - } - - epicsOneDimFFT ( pwf->g, pwf->logl, false ); - - for( unsigned n = 0; n < L; n++ ) - { - pwf->g[n] = pwf->g[n] * pwf->h[n]; - // epicsOneDimFFT does not scale - pwf->g[n] /= L; - } - - epicsOneDimFFT ( pwf->g, pwf->logl, true ); - - for ( unsigned k = 0; k < pwf->nelm; k++ ) - { - const fft_t kd = k; - const fft_t psi = kd * kd * phi0d2; - pwf->g[k] = pwf->g[k] * std::polar ( one, - psi ); - pwf->mag[k] = abs ( pwf->g[k] ); - pwf->ang[k] = arg ( pwf->g[k] ); - } - - //epicsTime end = epicsTime::getCurrent(); - - //cout << "delay per spectrum point " << - // ((end - begin) / pwf->nelm ) * 1e6 << " uS " << endl; - - //for ( unsigned i = 0; i < pwf->nelm; i++ ) { - // cout << i << g[i] << endl; - //} - - pwf->udf = FALSE; - recGblGetTimeStamp ( pwf) ; - - monitor ( pwf ); - // process the forward scan link record - recGblFwdLink ( pwf ); - - pwf->pact=FALSE; - return 0; -} - -static long cvt_dbaddr( struct dbAddr * paddr ) -{ - struct spectrumRecord * pwf = - reinterpret_cast < struct spectrumRecord * > - ( paddr->precord ); - - if ( paddr->pfield == (void *) & pwf->val ) { - paddr->pfield = pwf->mag; - paddr->no_elements = pwf->nelm; - paddr->field_type = DBF_DOUBLE; - paddr->field_size = 8; - paddr->dbr_field_type = DBF_DOUBLE; - } - else if ( paddr->pfield == (void *) & pwf->mag ) { - paddr->pfield = pwf->mag; - paddr->no_elements = pwf->nelm; - paddr->field_type = DBF_DOUBLE; - paddr->field_size = 8; - paddr->dbr_field_type = DBF_DOUBLE; - } - else if ( paddr->pfield == (void *) & pwf->ang ) { - paddr->pfield = pwf->ang; - paddr->no_elements = pwf->nelm; - paddr->field_type = DBF_DOUBLE; - paddr->field_size = 8; - paddr->dbr_field_type = DBF_DOUBLE; - } - return(0); -} - -static long get_array_info ( struct dbAddr * paddr, long * no_elements, long * offset ) -{ - struct spectrumRecord * pwf = ( struct spectrumRecord * ) paddr->precord; - *no_elements = pwf->nelm; - *offset = 0; - return 0; -} - -static long put_array_info ( struct dbAddr * paddr, long nNew ) -{ - return 0; -} - -static long get_units ( struct dbAddr * paddr, char * units ) -{ - struct spectrumRecord * pwf = ( struct spectrumRecord * ) paddr->precord; - strncpy ( units,pwf->egu, DB_UNITS_SIZE ); - return 0; -} - -static long get_precision ( struct dbAddr * paddr, long * precision ) -{ - struct spectrumRecord * pwf = ( struct spectrumRecord * ) paddr->precord; - - if ( paddr->pfield == (void *) pwf->mag ) { - *precision = pwf->prec; - } - else if ( paddr->pfield == (void *) pwf->ang ) { - *precision = pwf->prec; - } - else { - recGblGetPrec ( paddr, precision ); - } - return 0; -} - -static long get_graphic_double ( struct dbAddr * paddr, struct dbr_grDouble *pgd ) -{ - struct spectrumRecord * pwf = (struct spectrumRecord *) paddr->precord; - if ( paddr->pfield == (void *) pwf->mag ) { - pgd->upper_disp_limit = pwf->hopr; - pgd->lower_disp_limit = pwf->lopr; - } - else if ( paddr->pfield == (void *) pwf->ang ) { - pgd->upper_disp_limit = +PI; - pgd->lower_disp_limit = -PI; - } - else if ( paddr->pfield == (void *) & pwf->hfrq ) { - pgd->upper_disp_limit = pwf->ifrq / 2.0; - pgd->lower_disp_limit = 0; - } - else if ( paddr->pfield == (void *) & pwf->lfrq ) { - pgd->upper_disp_limit = pwf->ifrq / 2.0; - pgd->lower_disp_limit = 0; - } - else { - recGblGetGraphicDouble ( paddr, pgd ) ; - } - return 0; -} - -static long get_control_double ( struct dbAddr * paddr, struct dbr_ctrlDouble * pcd ) -{ - struct spectrumRecord * pwf = ( struct spectrumRecord * ) paddr->precord; - - if ( paddr->pfield == (void *) pwf->mag ) { - pcd->upper_ctrl_limit = pwf->hopr; - pcd->lower_ctrl_limit = pwf->lopr; - } - else if ( paddr->pfield == (void *) pwf->ang ) { - pcd->upper_ctrl_limit = +PI; - pcd->lower_ctrl_limit = -PI; - } - else if ( paddr->pfield == (void *) & pwf->hfrq ) { - pcd->upper_ctrl_limit = pwf->ifrq / 2.0; - pcd->lower_ctrl_limit = 0; - } - else if ( paddr->pfield == (void *) & pwf->lfrq ) { - pcd->upper_ctrl_limit = pwf->ifrq / 2.0; - pcd->lower_ctrl_limit = 0; - } - else { - recGblGetControlDouble ( paddr, pcd ); - } - - return 0; -} - -/* Create RSET - Record Support Entry Table*/ -#define report NULL -#define initialize NULL -#define get_value NULL -#define get_enum_str NULL -#define get_enum_strs NULL -#define put_enum_str NULL -#define get_alarm_double NULL -rset spectrumRSET={ - RSETNUMBER, - (RECSUPFUN) report, - (RECSUPFUN) initialize, - (RECSUPFUN) init_record, - (RECSUPFUN) process, - (RECSUPFUN) special, - (RECSUPFUN) get_value, - (RECSUPFUN) cvt_dbaddr, - (RECSUPFUN) get_array_info, - (RECSUPFUN) put_array_info, - (RECSUPFUN) get_units, - (RECSUPFUN) get_precision, - (RECSUPFUN) get_enum_str, - (RECSUPFUN) get_enum_strs, - (RECSUPFUN) put_enum_str, - (RECSUPFUN) get_graphic_double, - (RECSUPFUN) get_control_double, - (RECSUPFUN) get_alarm_double -}; - -extern "C" { - epicsExportAddress ( rset, spectrumRSET ); -} - - diff --git a/src/rec/spectrumRecord.dbd b/src/rec/spectrumRecord.dbd deleted file mode 100644 index 9c8eed83f..000000000 --- a/src/rec/spectrumRecord.dbd +++ /dev/null @@ -1,116 +0,0 @@ -#************************************************************************* -# Copyright (c) 2002 The University of Chicago, as Operator of Argonne -# National Laboratory. -# Copyright (c) 2002 The Regents of the University of California, as -# Operator of Los Alamos National Laboratory. -# EPICS BASE Versions 3.13.7 -# and higher are distributed subject to a Software License Agreement found -# in file LICENSE that is included with this distribution. -#************************************************************************* -recordtype(spectrum) { - include "dbCommon.dbd" - field(VAL,DBF_DOUBLE) { - prompt("Power Spectral Density") - asl(ASL0) - special(SPC_DBADDR) - extra("fft_t * val") - } - field(MAG,DBF_NOACCESS) { - prompt("Power Spectral Density Magnitude Pointer") - special(SPC_DBADDR) - extra("fft_t * mag") - } - field(ANG,DBF_NOACCESS) { - prompt("Power Spectral Density Phase Pointer") - special(SPC_DBADDR) - extra("fft_t * ang") - } - field(IVAL,DBF_NOACCESS) { - prompt("Input Array Pointer") - special(SPC_NOMOD) - extra("fft_t * ival") - } - field(hamw,DBF_NOACCESS) { - prompt("Hamming window") - special(SPC_NOMOD) - extra("fft_t * hamw") - } - field(G,DBF_NOACCESS) { - prompt("Complex Array Pointer") - special(SPC_NOMOD) - extra("std::complex < fft_t > * g") - } - field(H,DBF_NOACCESS) { - prompt("Complex Array Pointer") - special(SPC_NOMOD) - extra("std::complex < fft_t > * h") - } - field(LFRQ,DBF_DOUBLE) { - prompt("Lowest frequency of interest (Hz)") - promptgroup(GUI_DISPLAY) - interest(1) - pp(TRUE) - special(SPC_MOD) - } - field(HFRQ,DBF_DOUBLE) { - prompt("Highest frequency of interest (Hz)") - promptgroup(GUI_DISPLAY) - interest(1) - pp(TRUE) - special(SPC_MOD) - } - field(IFRQ,DBF_DOUBLE) { - prompt("Input INPW samples per second (Hz)") - promptgroup(GUI_DISPLAY) - interest(1) - pp(TRUE) - special(SPC_MOD) - } - field(PREC,DBF_SHORT) { - prompt("Display Precision") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(INPW,DBF_INLINK) { - prompt("Input Specification") - promptgroup(GUI_INPUTS) - interest(1) - special(SPC_MOD) - } - field(EGU,DBF_STRING) { - prompt("Engineering Units Name") - promptgroup(GUI_DISPLAY) - interest(1) - size(16) - } - field(HOPR,DBF_DOUBLE) { - prompt("High Operating Range") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(LOPR,DBF_DOUBLE) { - prompt("Low Operating Range") - promptgroup(GUI_DISPLAY) - interest(1) - } - field(NELM,DBF_ULONG) { - prompt("Number of Elements") - promptgroup(GUI_WAVE) - special(SPC_MOD) - } - field(NIN,DBF_ULONG) { - prompt("Max number of Input Elements") - promptgroup(GUI_WAVE) - special(SPC_NOMOD) - } - field(LOGL,DBF_ULONG) { - prompt("Log of Number of Computational Elements") - promptgroup(GUI_WAVE) - special(SPC_NOMOD) - } - field(FROK,DBF_USHORT) { - prompt("Freq parameters are valid") - promptgroup(GUI_WAVE) - special(SPC_NOMOD) - } -}