00001
00005 #include <stdio.h>
00006 #include <bpm/bpm_units.h>
00007 #include <bpm/bpm_messages.h>
00008 #include <bpm/bpm_process.h>
00009 #include <bpm/bpm_dsp.h>
00010
00011
00012 int process_waveform( doublewf_t *signal, bpmconf_t *bpm, bpmproc_t *proc, bpmproc_t *trig,
00013 unsigned int mode ) {
00014
00015 int have_fft_pars = FALSE;
00016 int have_fit_pars = FALSE;
00017 double frequency, tdecay, amp, phase;
00018 char msg[128];
00019 double t0, tSample;
00020
00021 if ( ! bpm || ! signal || ! proc ) {
00022 bpm_error( "Invalid pointer arguments in process_waveform(...)",
00023 __FILE__, __LINE__ );
00024 return BPM_FAILURE;
00025 }
00026
00027
00028 proc->fft_success = FALSE;
00029 proc->fit_success = FALSE;
00030 proc->ddc_success = FALSE;
00031
00032
00033 if ( ! signal ) {
00034 sprintf( msg, "No signal present for BPM %s in process_waveform(...)", bpm->name );
00035 bpm_error( msg, __FILE__, __LINE__ );
00036 return BPM_FAILURE;
00037 }
00038
00039
00040 proc->saturated = check_saturation( signal, bpm->digi_nbits, &(proc->iunsat) );
00041
00042
00043
00044
00045 if ( get_pedestal( signal, 20, &(proc->voltageoffset) ,&(proc->ampnoise) ) == BPM_FAILURE ) {
00046 sprintf( msg, "Error getting pedestal of BPM %s in process_waveform(...)", bpm->name );
00047 bpm_error( msg, __FILE__, __LINE__ );
00048 return BPM_FAILURE;
00049 }
00050
00051
00052 doublewf_bias( -proc->voltageoffset, signal );
00053
00054
00055
00056 if ( trig ) {
00057
00058 proc->t0 = trig->t0;
00059 } else {
00060
00061 proc->t0 = bpm->t0;
00062 }
00063
00064
00065 if ( mode & PROC_DO_FFT ) {
00066
00067
00068 if ( fft_waveform( signal, proc->ft ) == BPM_FAILURE ) {
00069 sprintf( msg, "Could not perform fft for BPM %s in process_waveform(...)", bpm->name );
00070 bpm_warning( msg, __FILE__, __LINE__ );
00071
00072 } else {
00073 proc->fft_success = TRUE;
00074
00075 if ( mode & PROC_FIT_FFT ) {
00076
00077 if( fit_fft( proc->ft, &(proc->fft_freq), &(proc->fft_tdecay), NULL, NULL )
00078 == BPM_FAILURE ) {
00079 sprintf( msg, "Could not fit the FFT for BPM %s in process_waveform(...)", bpm->name );
00080 bpm_warning( msg, __FILE__, __LINE__ );
00081 } else {
00082 have_fft_pars = TRUE;
00083 }
00084
00085 }
00086
00087 }
00088
00089 }
00090
00091
00092
00093 if ( mode & PROC_DO_FIT ) {
00094
00095
00096
00097
00098
00099 bpm_warning( "Libbpm waveform fitting is highly EXPERIMENTAL and contains bugs!",
00100 __FILE__, __LINE__ );
00101
00102
00103 frequency = tdecay = amp = phase = 0.;
00104
00105
00106 if ( proc->fit_freq <= 0.* _MHz__ || proc->fit_freq > ( bpm->digi_freq/2.) ) {
00107
00108
00109
00110
00111
00112
00113
00114 frequency = 20.0 * _MHz__;
00115 } else frequency = proc->fit_freq;
00116
00117
00118 if ( proc->fit_tdecay <= 10.* _nsec__ || proc->fit_tdecay > 1.0 * _sec__ ) {
00119 if ( bpm->cav_decaytime > 0. ) tdecay = bpm->cav_decaytime;
00120 else tdecay = 0.2 * _sec__;
00121 } else tdecay = proc->fit_tdecay;
00122
00123
00124 if( ABS( proc->fit_amp ) < 100000. ) amp = proc->fit_amp; else amp = 3000.;
00125 phase = proc->fit_phase;
00126
00127
00128
00129 if( have_fft_pars ) {
00130 frequency = proc->fft_freq;
00131 tdecay = proc->fft_tdecay;
00132 }
00133
00134
00135
00136 sample_to_time( bpm->digi_freq, bpm->digi_nsamples, proc->iunsat, &t0 );
00137 t0 = ( t0 > ( proc->t0 + bpm->fit_tOffset ) ? t0 : proc->t0 + bpm->fit_tOffset);
00138
00139 if ( fit_waveform( signal, t0, frequency, tdecay, amp, phase,
00140 &(proc->fit_freq), &(proc->fit_tdecay), &(proc->fit_amp) ,
00141 &(proc->fit_phase) ) == BPM_FAILURE ) {
00142 sprintf( msg, "Could not fit for BPM %s in process_waveform(...)", bpm->name );
00143 bpm_warning( msg, __FILE__, __LINE__ );
00144 } else {
00145 have_fit_pars = TRUE;
00146 proc->fit_success = TRUE;
00147
00148
00149 proc->fit_amp *= exp( ( t0 - proc->t0 ) / proc->fit_tdecay );
00150 proc->fit_phase -= (t0 - proc->t0) * proc->fit_freq * 2. * PI;
00151 norm_phase( &(proc->fit_phase) );
00152 }
00153
00154 }
00155
00156
00157
00158 if ( mode & PROC_DO_DDC ) {
00159
00160
00161 frequency = tdecay = 0.;
00162
00163
00164 if ( mode & PROC_DDC_FITFREQ ) {
00165 if ( have_fit_pars ) frequency = proc->fit_freq;
00166 else frequency = bpm->ddc_freq;
00167 } else if ( mode & PROC_DDC_FFTFREQ ) {
00168 if ( have_fft_pars ) frequency = proc->fft_freq;
00169 else frequency = bpm->ddc_freq;
00170 } else {
00171
00172 frequency = bpm->ddc_freq;
00173 }
00174
00175
00176 if ( mode & PROC_DDC_FITTDECAY ) {
00177 if ( have_fit_pars ) tdecay = proc->fit_tdecay;
00178 else tdecay = bpm->ddc_tdecay;
00179 } else if ( mode & PROC_DDC_FFTTDECAY ) {
00180 if ( have_fft_pars ) tdecay = proc->fft_tdecay;
00181 else tdecay = bpm->ddc_tdecay;
00182 } else {
00183
00184 tdecay = bpm->ddc_tdecay;
00185 }
00186
00187
00188 if ( proc->saturated == 1 ) {
00189
00190 sample_to_time( bpm->digi_freq, bpm->digi_nsamples, proc->iunsat, &(proc->ddc_tSample) );
00191
00192
00193 } else {
00194
00195 proc->ddc_tSample = proc->t0 + bpm->ddc_tOffset;
00196 }
00197
00198
00199 time_to_sample( bpm->digi_freq, bpm->digi_nsamples, proc->ddc_tSample, &(proc->ddc_iSample) );
00200
00201 if ( mode & PROC_DDC_FULL ) {
00202
00203 if ( ddc_waveform( signal, frequency, bpm->ddc_filter, proc->dc,
00204 bpm->ddc_buffer_re, bpm->ddc_buffer_im ) == BPM_FAILURE ) {
00205 sprintf( msg, "Could not ddc BPM %s waveform in process_waveform(...)", bpm->name );
00206 bpm_warning( msg, __FILE__, __LINE__ );
00207 proc->ddc_amp = 0.;
00208 proc->ddc_phase = 0.;
00209
00210 } else {
00211 proc->ddc_success = TRUE;
00212
00213
00214 proc->ddc_amp = exp( ( proc->ddc_tSample - proc->t0 ) / tdecay ) *
00215 c_abs( proc->dc->wf[ proc->ddc_iSample ] );
00216 proc->ddc_phase = c_arg( proc->dc->wf[ proc->ddc_iSample ] );
00217 norm_phase( &(proc->ddc_phase) );
00218 }
00219
00220 } else {
00221
00222 if ( ddc_sample_waveform( signal, frequency, bpm->ddc_filter, proc->ddc_iSample,
00223 proc->t0, tdecay, &(proc->ddc_amp), &(proc->ddc_phase),
00224 bpm->ddc_buffer_re, bpm->ddc_buffer_im ) == BPM_FAILURE ) {
00225 sprintf( msg, "Could not ddc_sample BPM %s waveform in process_waveform(...)", bpm->name );
00226 bpm_warning( msg, __FILE__, __LINE__ );
00227 } else {
00228 proc->ddc_success = TRUE;
00229 norm_phase( &(proc->ddc_phase) );
00230 }
00231 }
00232
00233 }
00234
00235 return BPM_SUCCESS;
00236 }