00001
00005 #include <stdio.h>
00006 #include <bpm/bpm_units.h>
00007 #include <bpm/bpm_messages.h>
00008 #include <bpm/bpm_process.h>
00009
00027 int process_waveform( enum bpmtype_t type, bpmconf_t *bpm, bpmcalib_t *cal, bpmsignal_t *sig,
00028 bpmproc_t *proc, bpmproc_t *trig, unsigned int mode ) {
00029
00030
00031 int have_fft_pars = FALSE;
00032 int have_fit_pars = FALSE;
00033 double freq, tdecay, amp, phase;
00034 char msg[128];
00035
00036 if ( ! bpm || ! sig || ! proc || ! trig ) {
00037 bpm_error( "Invalid pointer arguments in process_waveform(...)",
00038 __FILE__, __LINE__ );
00039 return BPM_FAILURE;
00040 }
00041
00042
00043 proc->fft_success = FALSE;
00044 proc->fit_success = FALSE;
00045 proc->ddc_success = FALSE;
00046
00047
00048 if( bpm->cav_type != type ) {
00049 sprintf( msg, "Wrong cavity type for BPM %s in process_waveform(...)", bpm->name );
00050 bpm_error( msg, __FILE__, __LINE__ );
00051 return BPM_FAILURE;
00052 }
00053
00054
00055 if ( ! sig->wf ) {
00056 sprintf( msg, "No signal present for BPM %s in process_waveform(...)", bpm->name );
00057 bpm_error( msg, __FILE__, __LINE__ );
00058 return BPM_FAILURE;
00059 }
00060
00061
00062 if ( get_pedestal( sig->wf, bpm->digi_nsamples, 20,
00063 &(proc->voltageoffset) ,&(proc->ampnoise) ) == BPM_FAILURE ) {
00064 sprintf( msg, "Error getting pedestal of BPM %s in process_waveform(...)", bpm->name );
00065 bpm_error( msg, __FILE__, __LINE__ );
00066 return BPM_FAILURE;
00067 }
00068
00069
00070 if ( mode & PROC_DO_FFT ) {
00071
00072
00073 if ( fft_waveform( sig->wf, bpm->digi_nsamples, proc->fftwf ) == BPM_FAILURE ) {
00074 sprintf( msg, "Could not perform fft for BPM %s in process_waveform(...)", bpm->name );
00075 bpm_warning( msg, __FILE__, __LINE__ );
00076
00077 } else {
00078
00079 if( fit_fft( proc->fftwf, bpm->digi_nsamples, bpm->digi_freq,
00080 &(proc->fft_freq), &(proc->fft_tdecay), NULL, NULL ) == BPM_FAILURE ) {
00081 sprintf( msg, "Could not fit the FFT for BPM %s in process_waveform(...)", bpm->name );
00082 bpm_warning( msg, __FILE__, __LINE__ );
00083 } else {
00084 have_fft_pars = TRUE;
00085 proc->fft_success = TRUE;
00086 }
00087
00088
00089 }
00090
00091 }
00092
00093
00094
00095 if ( mode & PROC_DO_FIT ) {
00096
00097
00098 freq = tdecay = amp = phase = 0.;
00099
00100
00101
00102
00103
00104 if ( proc->fit_freq <= 0.*MHz || proc->fit_freq > ( bpm->digi_freq/2.) ) {
00105 if ( ( bpm->rf_LOfreq > 0. ) && ( bpm->cav_freq > 0. ) ) {
00106 freq = ABS( bpm->cav_freq - bpm->rf_LOfreq );
00107 } else freq = 20.0*MHz;
00108 } else freq = proc->fit_freq;
00109
00110 if ( proc->fit_tdecay <= 10.*nsec || proc->fit_tdecay > 1.0*usec ) {
00111 if ( bpm->cav_decaytime > 0. ) tdecay = bpm->cav_decaytime;
00112 else tdecay = 0.2*usec;
00113 } else tdecay = proc->fit_tdecay;
00114
00115
00116 if( ABS( proc->fit_amp ) < 100000. ) amp = proc->fit_amp; else amp = 3000.;
00117 phase = proc->fit_phase;
00118
00119
00120
00121 if( have_fft_pars ) {
00122 freq = proc->fft_freq;
00123 tdecay = proc->fft_tdecay;
00124 }
00125
00126
00127
00128 int unsat_sample;
00129 if ( handle_saturation( sig->wf, bpm->digi_nsamples, 200, bpm->digi_nbits, 64, &unsat_sample ) == BPM_FAILURE ) {
00130 bpm_error( "Unable to handle saturation in process_waveform(...)",
00131 __FILE__, __LINE__ );
00132 return BPM_FAILURE;
00133 }
00134
00135 double t0;
00136 sample_to_time(bpm->digi_freq, bpm->digi_nsamples, unsat_sample, &t0 );
00137 t0 = ( t0 > ( trig->t0 + cal->t0Offset ) ? t0 : trig->t0 + cal->t0Offset);
00138
00139 if ( fit_waveform( sig->wf, bpm->digi_nsamples, t0, bpm->digi_freq,
00140 freq, tdecay, amp, phase,
00141 &(proc->fit_freq), &(proc->fit_tdecay), &(proc->fit_amp) ,
00142 &(proc->fit_phase) ) == BPM_FAILURE ) {
00143 sprintf( msg, "Could not fit for BPM %s in process_waveform(...)", bpm->name );
00144 bpm_warning( msg, __FILE__, __LINE__ );
00145 } else {
00146 have_fit_pars = TRUE;
00147 proc->fit_success = TRUE;
00148
00149
00150 proc->fit_amp *= exp( ( t0 - trig->t0 ) / proc->fit_tdecay );
00151 proc->fit_phase -= (t0 - trig->t0) * proc->fit_freq * 2. * PI;
00152 }
00153
00154 }
00155
00156
00157
00158 if ( mode & PROC_DO_DDC ) {
00159
00160
00161 freq = tdecay = 0.;
00162
00163
00164 if ( mode & PROC_DDC_FITFREQ ) {
00165 if ( have_fit_pars ) freq = proc->fit_freq;
00166 else freq = cal->freq;
00167 } else if ( mode & PROC_DDC_FFTFREQ ) {
00168 if ( have_fft_pars ) freq = proc->fft_freq;
00169 else freq = cal->freq;
00170 } else {
00171
00172 freq = cal->freq;
00173 }
00174
00175
00176 if ( mode & PROC_DDC_FITTDECAY ) {
00177 if ( have_fit_pars ) tdecay = proc->fit_tdecay;
00178 else tdecay = cal->tdecay;
00179 } else if ( mode & PROC_DDC_FFTTDECAY ) {
00180 if ( have_fft_pars ) tdecay = proc->fft_tdecay;
00181 else tdecay = cal->tdecay;
00182 } else {
00183
00184 tdecay = cal->tdecay;
00185 }
00186
00187
00188 if ( ddc_sample_waveform( sig->wf, bpm->digi_nsamples, bpm->digi_nbits, bpm->digi_freq,
00189 trig->t0, cal->t0Offset, freq, tdecay,
00190 cal->ddcfiltBW, cal->ddcepsFilt,
00191 &(proc->ddc_amp), &(proc->ddc_phase) ) == BPM_FAILURE ) {
00192 sprintf( msg, "Could not downconvert BPM %s waveform in process_waveform(...)", bpm->name );
00193 bpm_warning( msg, __FILE__, __LINE__ );
00194 } else {
00195
00196 proc->ddc_success = TRUE;
00197
00198 if ( mode & PROC_DDC_STOREFULL ) {
00199
00200
00201 ddc_waveform( sig->wf, bpm->digi_nsamples, bpm->digi_nbits, bpm->digi_freq,
00202 trig->t0, freq, tdecay, cal->ddcfiltBW, cal->ddcepsFilt,
00203 proc->ddcwf );
00204
00205
00206
00207
00208
00209
00210
00211
00212 }
00213
00214
00215 }
00216
00217
00218 }
00219
00220 return BPM_SUCCESS;
00221 }