bpmwf/intwf.c

Go to the documentation of this file.
00001 
00006 #include <bpm/bpm_wf.h>
00007 
00008 intwf_t* intwf( int ns, double fs ) {
00009   
00010   intwf_t *w;
00011 
00012   if ( fs <= 0 ) {
00013     bpm_error( "Cannot have sampling frequency <= 0. in intwf()",
00014                __FILE__, __LINE__ );
00015     return NULL;
00016   }
00017   
00018   if ( ns > MAX_ALLOWED_NS ) {
00019     bpm_error( "Maximum allowed number of samples exceeded, failed to allocate.",
00020                __FILE__, __LINE__ );
00021     return NULL;
00022   }
00023 
00024  if ( ns > 1 ) {
00025     w = (intwf_t*) calloc( 1, sizeof(intwf_t) );
00026     if ( ! w ) {
00027       bpm_error( "Cannot allocate memory for waveform structure in intwf()",
00028                  __FILE__, __LINE__ );
00029       return NULL;
00030     }
00031     w->ns = ns;
00032     w->fs = fs;
00033     w->wf = (int*) calloc( w->ns, sizeof( int ) );
00034     if ( ! w->wf ) {
00035       bpm_error( "Cannot allocate memory for waveform data in intwf()",
00036                  __FILE__, __LINE__ );
00037       free( w );
00038       return NULL;
00039     }
00040   } else {
00041     bpm_error( "Invalid number of samples in intwf()", __FILE__, __LINE__ );
00042     return NULL;
00043   }
00044 
00045   return w;
00046 }
00047 
00048 // ----------------------------------------------------------------------------
00049 
00050 intwf_t* intwf_sample_series( int ns, double fs ) {
00051 
00052   int i = 0;
00053   intwf_t *w = intwf( ns, fs );
00054 
00055   if ( ! w ) return w;
00056   for ( i=0; i<w->ns; i++ ) w->wf[i] = i;
00057 
00058   return w;
00059 }
00060 
00061 // ----------------------------------------------------------------------------
00062 
00063 intwf_t* intwf_copy_new( intwf_t *w ) {
00064   
00065   int i = 0;
00066   intwf_t *s = intwf( w->ns, w->fs );
00067   
00068   if ( ! s ) {
00069     bpm_error( "Cannot allocate memory in intwf_copy_new()", 
00070                __FILE__, __LINE__ );
00071     return NULL;
00072   };
00073 
00074   for ( i=0; i<w->ns; i++ ) s->wf[i] = w->wf[i];
00075 
00076   return s;
00077 }
00078 
00079 // ----------------------------------------------------------------------------
00080 
00081 int intwf_copy( intwf_t *copy, intwf_t *src ) {
00082   
00083   int i = 0;
00084 
00085   if ( ! copy || ! src ) {
00086     bpm_error( "Invalid pointer arguments in intwf_copy()", __FILE__, __LINE__ );
00087     return BPM_FAILURE;
00088   };
00089 
00090   if ( intwf_compat( copy, src ) ) {
00091     for ( i=0; i<copy->ns; i++ ) copy->wf[i] = src->wf[i];
00092   } else {
00093     bpm_error( "Incompatible waveforms for in intwf_copy()", __FILE__, __LINE__ );
00094     return BPM_FAILURE;
00095   }
00096 
00097   return BPM_SUCCESS;
00098 }
00099 
00100 // ----------------------------------------------------------------------------
00101 
00102 int intwf_subset( intwf_t *sub, intwf_t *w, int i1, int i2 ) {
00103   
00104   int i = 0;
00105 
00106   if ( ! sub || ! w ) {
00107     bpm_error( "Invalid pointer arguments in intwf_subset()", __FILE__, __LINE__ );
00108     return BPM_FAILURE;
00109   };
00110 
00111   // reset the number of samples in the subset
00112   sub->ns = 0;
00113   sub->fs = w->fs;
00114 
00115   for ( i=MAX(0,i1); i<=MIN(w->ns-1,i2); i++ ) {
00116     sub->wf[i] = w->wf[i-i1];
00117     sub->ns++;
00118   }
00119 
00120 
00121   return BPM_SUCCESS;
00122 }
00123 
00124 // ----------------------------------------------------------------------------
00125 
00126 int intwf_setvalues( intwf_t *w, int *x ) {
00127 
00128   int i = 0;
00129   if ( ! w || ! x ) {
00130     bpm_error( "Invalid pointer arguments in intwf_setvalues()",
00131                __FILE__, __LINE__ );
00132     return BPM_FAILURE;
00133   }
00134 
00135   for ( i=0; i<w->ns; i++ ) w->wf[i] = x[i];
00136 
00137   return BPM_SUCCESS;
00138 }
00139 
00140 // ----------------------------------------------------------------------------
00141 
00142 int intwf_setfunction( intwf_t *w, 
00143                        int (*wffun)( double, int, double* ),
00144                        int npars, double *par ) {
00145   
00146   int i = 0;
00147   if ( ! w || ! wffun ) {
00148     bpm_error( "Invalid pointer arguments in intwf_setfunction()",
00149                __FILE__, __LINE__ );
00150     return BPM_FAILURE;
00151   }
00152   
00153   for ( i=0; i<w->ns; i++ ) w->wf[i] = (*wffun)( (double) i / w->fs, npars, par );
00154 
00155   return BPM_SUCCESS;
00156 }
00157 
00158 // ----------------------------------------------------------------------------
00159 
00160 int intwf_reset( intwf_t *w ) {
00161 
00162   int i = 0;
00163 
00164   if ( ! w  ) {
00165     bpm_error( "Invalid pointer argument in intwf_reset()", 
00166                __FILE__, __LINE__ );
00167     return BPM_FAILURE;
00168   }
00169 
00170   for ( i=0; i<w->ns; i++ ) w->wf[i] = 0;
00171 
00172   return BPM_SUCCESS;
00173 }
00174 
00175 // ----------------------------------------------------------------------------
00176 
00177 void intwf_delete( intwf_t *w ) {
00178 
00179   if ( w ) {
00180     if ( w->wf ) free( w->wf ); else
00181       bpm_warning( "Cannot free intwf_t::wf pointer in intwf()_delete, already NULL !",
00182                    __FILE__, __LINE__ );
00183     free( w );
00184   } else {
00185     bpm_warning( "Cannot free intwf_t pointer in intwf()_delete, already NULL !", 
00186                  __FILE__, __LINE__ );
00187   }
00188   
00189   return;
00190 }
00191 
00192 // ----------------------------------------------------------------------------
00193 
00194 doublewf_t* doublewf_cast_new( intwf_t *iw ) {
00195 
00196   int i = 0;
00197   doublewf_t *w;
00198 
00199   if ( ! w ) {
00200     bpm_error( "Invalid pointer argument in doublewf_cast_new()", 
00201                __FILE__, __LINE__ );
00202     return NULL;
00203   }
00204 
00205   w = doublewf( iw->ns, iw->fs );
00206   if ( ! w ) {
00207     bpm_error( "Cannot allocate memory for doublewf_t in doublewf_cast_new()",
00208                __FILE__, __LINE__ );
00209     return NULL;
00210   }
00211   
00212   // cast to the double waveform
00213   for (i=0;i<iw->ns;i++) w->wf[i] = (double) iw->wf[i];
00214 
00215   return w;
00216 }
00217 
00218 // ----------------------------------------------------------------------------
00219 
00220 int doublewf_cast( doublewf_t *w, intwf_t *iw ) {
00221 
00222   int i = 0;
00223 
00224   if ( ! w || ! iw ) {
00225     bpm_error( "Invalid pointer argument in doublewf_cast()", 
00226                __FILE__, __LINE__ );
00227     return BPM_FAILURE;
00228   }
00229 
00230   // cast to the double waveform
00231   for (i=0;i<iw->ns;i++) w->wf[i] = (double) iw->wf[i];
00232 
00233   return BPM_SUCCESS;
00234 }
00235 
00236 // ----------------------------------------------------------------------------
00237 
00238 int intwf_compat( intwf_t *w1, intwf_t *w2 ) {
00239 
00240   if ( ! w1 || ! w2 ) {
00241     bpm_error( "Invalid pointer arguments in intwf_compat()", 
00242                __FILE__, __LINE__ );
00243     return 0;
00244   }
00245   
00246   return ((w1->ns==w2->ns)&&(fabs(w1->fs-w2->fs)<WF_EPS)?1:0);
00247 }
00248 
00249 // ----------------------------------------------------------------------------
00250 
00251 int intwf_add( intwf_t *w1, intwf_t *w2 ) {
00252 
00253   int i = 0;
00254 
00255   if ( ! w1 || ! w2 ) {
00256     bpm_error( "Invalid pointer arguments in intwf_add()", 
00257                __FILE__, __LINE__ );
00258     return BPM_FAILURE;
00259   }
00260 
00261   if ( ! intwf_compat( w1, w2 ) ) {
00262     bpm_warning( "Incompatible waveforms in intwf_add()", __FILE__, __LINE__ );
00263   }
00264   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] += w2->wf[i];
00265   
00266   return BPM_SUCCESS;
00267 }
00268 
00269 // ----------------------------------------------------------------------------
00270 
00271 int intwf_subtract( intwf_t *w1, intwf_t *w2 ) {
00272   
00273   int i = 0;
00274   
00275   if ( ! w1 || ! w2 ) {
00276     bpm_error( "Invalid pointer arguments in intwf_subtract()", 
00277                __FILE__, __LINE__ );
00278     return BPM_FAILURE;
00279   }
00280 
00281   if ( ! intwf_compat( w1, w2 ) ) {
00282     bpm_warning( "Incompatible waveforms in intwf_subtract()", __FILE__, __LINE__ );
00283   }
00284   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] -= w2->wf[i];
00285   
00286   return BPM_SUCCESS;
00287 }
00288 
00289 // ----------------------------------------------------------------------------
00290 
00291 int intwf_multiply( intwf_t *w1, intwf_t *w2 ) {
00292 
00293   int i = 0;
00294   
00295   if ( ! w1 || ! w2 ) {
00296     bpm_error( "Invalid pointer arguments in intwf_multiply()", 
00297                __FILE__, __LINE__ );
00298     return BPM_FAILURE;
00299   }
00300 
00301   if ( ! intwf_compat( w1, w2 ) ) {
00302     bpm_warning( "Incompatible waveforms in intwf_multiply()", 
00303                  __FILE__, __LINE__ );
00304   }
00305 
00306   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) w1->wf[i] *= w2->wf[i];
00307 
00308   return BPM_SUCCESS;
00309 }
00310 
00311 // ----------------------------------------------------------------------------
00312 
00313 int intwf_divide( intwf_t *w1, intwf_t *w2 ) {
00314   
00315   int i = 0;
00316   
00317   if ( ! w1 || ! w2 ) {
00318     bpm_error( "Invalid pointer arguments in intwf_divide()", 
00319                __FILE__, __LINE__ );
00320     return BPM_FAILURE;
00321   }
00322 
00323   if ( ! intwf_compat( w1, w2 ) ) {
00324     bpm_warning( "Incompatible waveforms in intwf_divide()", 
00325                  __FILE__, __LINE__ );
00326   }
00327 
00328   for ( i=0; i < MIN(w1->ns,w2->ns); i++ ) {
00329     if ( w2->wf[i] != 0. ) {
00330       w1->wf[i] /= w2->wf[i] ;
00331     } else {
00332       bpm_warning( "Trapped division by 0. in intwf_divide()", 
00333                    __FILE__, __LINE__ );
00334       w1->wf[i] = 0.;
00335     } 
00336   } 
00337 
00338   return BPM_SUCCESS;
00339 }
00340 
00341 // ----------------------------------------------------------------------------
00342 
00343 int intwf_scale( int f, intwf_t *w ) {
00344 
00345   int i = 0;
00346   
00347   if ( ! w ) {
00348     bpm_error( "Invalid pointer argument in intwf_scale()", 
00349                __FILE__, __LINE__ );
00350     return BPM_FAILURE;
00351   }
00352 
00353   for ( i=0; i<w->ns; i++ ) w->wf[i] *= f;
00354 
00355   return BPM_SUCCESS;
00356 }
00357 
00358 // ----------------------------------------------------------------------------
00359 
00360 int intwf_bias( int c, intwf_t *w ) {
00361 
00362   int i = 0;
00363   
00364   if ( ! w ) {
00365     bpm_error( "Invalid pointer argument in intwf_bias()", 
00366                __FILE__, __LINE__ );
00367     return BPM_FAILURE;
00368   }
00369 
00370   for ( i=0; i<w->ns; i++ ) w->wf[i] += c;
00371 
00372   return BPM_SUCCESS;
00373 }
00374 
00375 // ----------------------------------------------------------------------------
00376 
00377 int intwf_add_cwtone( intwf_t *w, double amp, double phase, double freq,
00378                       double phasenoise ) {
00379 
00380   int i = 0;
00381   
00382   if ( ! w ) {
00383     bpm_error( "Invalid pointer argument in intwf_add_cwtone()", 
00384                __FILE__, __LINE__ );
00385     return BPM_FAILURE;
00386   }
00387   
00388   for (i=0; i<w->ns; i++ ) 
00389     w->wf[i] += (int) dround ( amp * cos( 2. * PI * freq * (double) i /  w->fs + 
00390                                           nr_rangauss( phase, phasenoise ) ) );
00391   
00392   return BPM_SUCCESS;
00393 }
00394 
00395 // ----------------------------------------------------------------------------
00396 
00397 int intwf_add_dcywave( intwf_t *w, double amp, double phase, double freq, 
00398                        double ttrig, double tdcy, double phasenoise ) {
00399   
00400   int    i = 0;
00401   double t = 0.;
00402   
00403   if ( ! w ) {
00404     bpm_error( "Invalid pointer argument in intwf_add_dcywave()", 
00405                __FILE__, __LINE__ );
00406     return BPM_FAILURE;
00407   }
00408   
00409   for (i=0; i<w->ns; i++ ) {
00410     t = (double) i / w->fs;
00411     if ( t >= ttrig ) {
00412       w->wf[i] += (int) dround( amp * exp( -( t - ttrig ) / tdcy ) * 
00413                                 cos( 2. * PI * freq * ( t - ttrig ) + 
00414                                      nr_rangauss( phase, phasenoise ) ) );
00415     }
00416   }
00417 
00418   return BPM_SUCCESS;
00419 }
00420 
00421 // ----------------------------------------------------------------------------
00422 
00423 int intwf_add_ampnoise( intwf_t *w, double sigma ) {
00424   
00425   int i = 0;
00426   
00427   if ( ! w ) {
00428     bpm_error( "Invalid pointer argument in intwf_add_ampnoise()", 
00429                __FILE__, __LINE__ );
00430     return BPM_FAILURE;
00431   }
00432 
00433   for (i=0; i<w->ns; i++ ) {
00434     w->wf[i] += (int) dround( nr_rangauss( 0., sigma ) );
00435   }
00436 
00437   return BPM_SUCCESS;
00438 
00439 }
00440 
00441 // ----------------------------------------------------------------------------
00442 
00443 int intwf_basic_stats( intwf_t *w, int s0, int s1, wfstat_t *stats ) {
00444   
00445   doublewf_t *dw = NULL;
00446   
00447   if ( ! w || ! stats ) {
00448     bpm_error( "Invalid pointer arguments in intwf_basic_stats()", 
00449                __FILE__, __LINE__ );
00450     return BPM_FAILURE;
00451   }
00452 
00453   dw = doublewf_cast_new( w );
00454   if ( ! dw ) {
00455     bpm_error( "Cannot allocate memory for temporary doublewf in intwf_basic_stats",
00456                __FILE__, __LINE__ );
00457     return BPM_FAILURE;
00458   }
00459 
00460   if ( doublewf_basic_stats( dw, s0, s1, stats ) ) return BPM_FAILURE;
00461   
00462   doublewf_delete( dw );
00463   
00464   return BPM_SUCCESS;
00465 }
00466 
00467 // ----------------------------------------------------------------------------
00468 
00469 int intwf_derive( intwf_t *w ) {
00470 
00471   int     i = 0;
00472   double dt = 0;
00473 
00474   if ( ! w ) {
00475     bpm_error( "Invalid pointer argument in intwf_derive()", 
00476                __FILE__, __LINE__ );
00477     return BPM_FAILURE;
00478   }
00479   
00480   // the time step...
00481   dt = 1./w->fs;
00482 
00483   // derivative...
00484   for ( i=0; i<w->ns-1; i++ ) w->wf[i] = (int) dround( ( w->wf[i+1] - w->wf[i] ) / dt );
00485   
00486   // the last sample.. extrapolate linear, so same slope
00487   w->wf[w->ns-1] = w->wf[w->ns-2];
00488   
00489   return BPM_SUCCESS;
00490 }
00491 
00492 // ----------------------------------------------------------------------------
00493 
00494 int intwf_integrate( intwf_t *w ) {
00495 
00496   double tmp = 0., tmp_prev = 0.;
00497   double dt = 0.;
00498   int i = 0;
00499 
00500   if ( ! w ) {
00501     bpm_error( "Invalid pointer argument in intwf_integrate()", 
00502                __FILE__, __LINE__ );
00503     return BPM_FAILURE;
00504   }
00505 
00506   // the time step...
00507   dt = 1./w->fs;
00508 
00509   // integral
00510   for ( i=0; i<w->ns; i++ ) {
00511     tmp  = (double) w->wf[i];
00512     tmp *= dt;
00513     
00514     if ( i > 0 ) tmp += tmp_prev;
00515 
00516     w->wf[i] = (int) dround( tmp );
00517     tmp_prev = tmp;
00518   }
00519   
00520   return BPM_SUCCESS;
00521 }
00522 
00523 // ----------------------------------------------------------------------------
00524 
00525  void intwf_print( FILE *of, intwf_t *w ) {
00526 
00527   int i = 0;
00528   if ( !of || !w ) {
00529     bpm_error( "Invalid pointers in intwf_print()", __FILE__, __LINE__ );
00530     return;
00531   }
00532   
00533   fprintf( of, "Waveform:\n" );
00534   fprintf( of, "Number of samples  : %d\n",     w->ns );
00535   fprintf( of, "Sampling frequency : %f MHz\n", w->fs / MHz );
00536   for( i = 0; i < w->ns; i++ )  fprintf( of, "  wf[%5d] = %d \n", i, w->wf[i] );
00537   fflush( of );
00538 
00539   return;
00540 }
00541 
00542 // ----------------------------------------------------------------------------
00543 
00544 int intwf_getvalue( intwf_t *w, double t, unsigned int mode ) {
00545   
00546   int val = 0;
00547   doublewf_t *dw = NULL;
00548 
00549   if ( ! w ) {
00550     bpm_error( "Invalid pointer arguments in intwf_getvalue()", 
00551                __FILE__, __LINE__ );
00552     return BPM_FAILURE;
00553   }
00554 
00555   dw = doublewf_cast_new( w );
00556   if ( ! dw ) {
00557     bpm_error( "Cannot allocate memory for temporary doublewf in intwf_getvalue()",
00558                __FILE__, __LINE__ );
00559     return BPM_FAILURE;
00560   }
00561 
00562   val = (int) dround ( doublewf_getvalue( dw, t, mode ) );
00563 
00564   doublewf_delete( dw );
00565   
00566   return val;
00567 }
00568 
00569 // ----------------------------------------------------------------------------
00570 
00571 int intwf_resample( intwf_t *w2, double fs, intwf_t *w1, unsigned int mode ) {
00572 
00573   int i = 0;
00574   doublewf_t *dw = NULL;
00575 
00576   if ( ! w1 || ! w2 ) {
00577     bpm_error( "Invalid pointer arguments in intwf_resample()",
00578                __FILE__, __LINE__ );
00579     return BPM_FAILURE;
00580   }
00581 
00582   dw = doublewf_cast_new( w1 );
00583   if ( ! dw ) {
00584     bpm_error( "Cannot allocate memory for temporary doublewf in intwf_resample()",
00585                __FILE__, __LINE__ );
00586     return BPM_FAILURE;
00587   }
00588 
00589   // number of samples
00590   w2->ns = (int) (w1->ns * fs / w1->fs);
00591   w2->fs = fs;
00592 
00593   if ( w2->ns > MAX_ALLOWED_NS ) {
00594     bpm_error( "Maximum allowed number of samples exceeded in intwf_resample()",
00595                __FILE__, __LINE__ );
00596     return BPM_FAILURE;
00597   }
00598 
00599   if ( w2->ns < 1 ) {
00600     bpm_error( "Number of new samples is zero in intwf_resample()",
00601                __FILE__, __LINE__ );
00602     return BPM_FAILURE;
00603   }
00604 
00605   // fill the new waveform
00606   for ( i=0; i<w2->ns; i++ ) {
00607     w2->wf[i] = (int) dround( doublewf_getvalue( dw, (double) i / w2->fs, mode ) );
00608   }
00609 
00610   doublewf_delete( dw );
00611 
00612   return BPM_SUCCESS;
00613 }

Generated on Thu Jan 10 10:18:05 2008 for libbpm by  doxygen 1.5.1