/***************************************************************************** Major portions of this software are copyrighted by the Medical College of Wisconsin, 1994-2000, and are released under the Gnu General Public License, Version 2. See the file README.Copyright for details. ******************************************************************************/ /*#define CLIPSECTIONS */ /* Contrary to the good tradition, this .h file will include */ /* function declarations and definitions. */ /* The reason for this is that the plugin has to be a stand alone*/ /* code and I must provide all the code for the functions. */ /* This is just a way of splitting the code into smaller pieces */ /* This file will hold all support functions for the plugin code */ /*-------------------------------------------------------------------*/ /* taken from #include "/usr/people/ziad/Programs/C/Z/Zlib/prototype.h" */ #ifndef NOWAYXCORCOEF #define NOWAYXCORCOEF 0 /* A flag value indicating that something lethal went on */ #endif /* do not change these three*/ #define METH_SECONDS 0 #define METH_DEGREES 1 #define METH_RADIANS 2 #define ERROR_NOTHINGTODO 1 /* Nothing to do in hilbertdelay_V2 function */ #define ERROR_LARGENSEG 2 /* Too many segments specified in hilbertdelay_V2 function */ #define ERROR_LONGDELAY 3 /* Could not detect zero crossing before half of time course was gone */ #define ERROR_WRONGUNIT 8 /* Wrong units selected to pass to the delay functions */ #define ERROR_WARPVALUES 9 #define ERROR_FSVALUES 10 #define ERROR_TVALUES 11 #define ERROR_TaUNITVALUES 12 #define ERROR_TaWRAPVALUES 13 #define ERROR_FILEOPEN 15 #define ERROR_SERIESLENGTH 16 #define ERROR_OPTIONS 17 #define ERROR_NULLTIMESERIES 18 #define ERROR_OUTCONFLICT 19 #define ERROR_BADLENGTH 20 #define ERROR_QUIT 21 typedef struct { float real, imag; } COMPLEX; /* taken from #include "/usr/people/ziad/Programs/C/DSP_in_C/dft.h" */ /* dft.h - function prototypes and structures for dft and fft functions */ int delay_verb(void); void set_delay_verb(int); static int Read_file (float *x,char *f_name,int n_points); static void linear_reg (float *x,float *y,int size,float *a,float *b,int *err); static int equal_strings (char *s1,char *s2); static int float_file_size (char *f_name); static void error_message (char *origin,char *cause,int ext); static char **allocate2D (int rows,int cols,int element_size); static void free2D(char **a,int rows); static void linear_interp (float *x1,float *y1,float *x2,float *y2,float *x,float *y,int ln); static void float_to_complex (float *x,COMPLEX *xc,int ln); static void c_conj (COMPLEX *x,COMPLEX *y,int ln); static void c_get (COMPLEX *x,float *y,int p,int ln); static void c_scale (COMPLEX *x,COMPLEX *y,float scl,int ln); static void c_padd (COMPLEX *x,COMPLEX *y,COMPLEX pad_val,int ix,int lnx,int lny); static void c_mult (COMPLEX *x,COMPLEX *y,COMPLEX *z,int ln); static void detrend (float *y,float *yd,int lny,float *a,float *b); static void padd (float *x,float *y,float pad_val,int ix,int lnx,int lny); static void hanning (float *x,int l,int opt); static float punwrap (float p,int opt ); static float Lagrange_interp (float *x,float *y,float xi,int ln); static void f_mult (float *x,float *y,float *z,int ln); static int hilbertdelay_V2 (float *x,float *y,int lng_full,int Nseg,int Pover,\ int opt,int dtrnd, float Dtx, int biasrem,\ float *del,float *slp,float *xcor,float *xcorCoef,\ float *vx, float *vy); static void hunwrap (float del, float fs, float T, float slp, int wrp, int unt, int rev, float scl, float *delu ); static int isarg (int argc, char *argv[], char *probe); static float mean_array (float *ar,int size); static void zeromean (float *x, float *y, int ln ); static void disp_comp_vect (COMPLEX *v,int l); static void disp_vect (float *v,int l); static int is_vect_null ( float * v , int npts ); static int write_float (float *x,char *f_name,int n_points); /* definition and declaration part to support the main algorithm */ /* -----------------------END-----------------------------------*/ #define free_well(a) { if ((a)) free((a)) ; (a) = NULL; } static int delay_verb_level; int delay_verb() { static byte init=0; if (!init) { delay_verb_level = 0; init=1; } return(delay_verb_level); } void set_delay_verb(int v) { delay_verb_level = v; }; /* -------------------------------------------------------------*/ /* support functions declaration for main algorithm */ /* -----------------------START---------------------------------*/ static void error_message (char *s1,char *s2,int ext) { printf ("\n\n\a\33[1mError: \33[0m%s\n",s2); printf ("\33[1mError origin:\33[0m %s\n\n",s1); if (ext == 1) { printf ("Exiting Program ..\n\n"); exit (0); } else return; } /*--------------------------------------------------------------------------*/ /************************************************************************** allocate2D.c - Make matrix of given size (rows x cols) and type The type is given by element_size (2 = ints, 4 = floats, 8 = doubles). Exits if the matrix could not be allocated. char **allocate2D(int rows,int cols,int element_size) SIZE might vary depending on platform used This function was adapted from DSP_in_C library functions Ziad Saad Oct_21_96 *************************************************************************/ static char **allocate2D (int rows,int cols,int element_size) { int i; char **A; /* try to allocate the request */ switch(element_size) { case sizeof(short): { /* integer matrix */ short **int_matrix; int_matrix = (short **)calloc(rows,sizeof(short *)); if(!int_matrix) { printf("\nError making pointers in %dx%d int matrix\n" ,rows,cols); exit(1); } for(i = 0 ; i < rows ; i++) { int_matrix[i] = (short *)calloc(cols,sizeof(short)); if(!int_matrix[i]) { printf("\nError making row %d in %dx%d int matrix\n" ,i,rows,cols); exit(1); } } A = (char **)int_matrix; break; } case sizeof(float): { /* float matrix */ float **float_matrix; float_matrix = (float **)calloc(rows,sizeof(float *)); if(!float_matrix) { printf("\nError making pointers in %dx%d float matrix\n" ,rows,cols); exit(1); } for(i = 0 ; i < rows ; i++) { float_matrix[i] = (float *)calloc(cols,sizeof(float)); if(!float_matrix[i]) { printf("\nError making row %d in %dx%d float matrix\n" ,i,rows,cols); exit(1); } } A = (char **)float_matrix; break; } case sizeof(double): { /* double matrix */ double **double_matrix; double_matrix = (double **)calloc(rows,sizeof(double *)); if(!double_matrix) { printf("\nError making pointers in %dx%d double matrix\n" ,rows,cols); exit(1); } for(i = 0 ; i < rows ; i++) { double_matrix[i] = (double *)calloc(cols,sizeof(double)); if(!double_matrix[i]) { printf("\nError making row %d in %dx%d double matrix\n" ,i,rows,cols); exit(1); } } A = (char **)double_matrix; break; } default: printf("\nERROR in matrix_allocate: unsupported type\n"); exit(1); } return(A); } /*--------------------------------------------------------------------------*/ /************************************************************************** free2D.c - Free all elements of matrix Frees the 2D array (rows and cols) allocated using allocate2D Error message and exit if improper structure is passed to it (null pointers or zero size matrix). void free2D(char **a, int rows); This function was adapted from DSP_in_C library functions Ziad Saad Oct_22_96 *************************************************************************/ static void free2D(char **a,int rows) { int i; /* free each row of data */ for(i = 0 ; i < rows ; i++) free(a[i]); /* free each row pointer */ free((char *)a); a = NULL; /* set to null for error */ return; } /*--------------------------------------------------------------------------*/ static void hanning (float *x,int l,int opt) { int i; float arg; arg = 2.0*3.14159/(l-1); if (opt == 0) { for (i=0;i lnx+1) { error_message ("padd","ix > lnx+1 !",1); exit(1); } for (i=0;ireal = (float)wrecur_real; xj->imag = (float)wrecur_imag; xj++; wtemp_real = wrecur_real*w_real - wrecur_imag*w_imag; wrecur_imag = wrecur_real*w_imag + wrecur_imag*w_real; wrecur_real = wtemp_real; } } /* start fft */ le = n; windex = 1; for (l = 0 ; l < m ; l++) { le = le/2; /* first iteration with no multiplies */ for(i = 0 ; i < n ; i = i + 2*le) { xi = x + i; xip = xi + le; temp.real = xi->real + xip->real; temp.imag = xi->imag + xip->imag; xip->real = xi->real - xip->real; xip->imag = xi->imag - xip->imag; *xi = temp; } /* remaining iterations use stored w */ wptr = w + windex - 1; for (j = 1 ; j < le ; j++) { u = *wptr; for (i = j ; i < n ; i = i + 2*le) { xi = x + i; xip = xi + le; temp.real = xi->real + xip->real; temp.imag = xi->imag + xip->imag; tm.real = xi->real - xip->real; tm.imag = xi->imag - xip->imag; xip->real = tm.real*u.real - tm.imag*u.imag; xip->imag = tm.real*u.imag + tm.imag*u.real; *xi = temp; } wptr = wptr + windex; } windex = 2*windex; } /* rearrange data by bit reversing */ j = 0; for (i = 1 ; i < (n-1) ; i++) { k = n/2; while(k <= j) { j = j - k; k = k/2; } j = j + k; if (i < j) { xi = x + i; xj = x + j; temp = *xj; *xj = *xi; *xi = temp; } } } /*--------------------------------------------------------------------------*/ /************************************************************************** ifft - In-place radix 2 decimation in time inverse FFT Requires pointer to complex array, x and power of 2 size of FFT, m (size of FFT = 2**m). Places inverse FFT output on top of input frequency domain COMPLEX array. void ifft(COMPLEX *x, int m) *************************************************************************/ static void ifft(COMPLEX *x,int m) { static COMPLEX *w; /* used to store the w complex array */ static int mstore = 0; /* stores m for future reference */ static int n = 1; /* length of ifft stored for future */ COMPLEX u,temp,tm; COMPLEX *xi,*xip,*xj,*wptr; int i,j,k,l,le,windex; double arg,w_real,w_imag,wrecur_real,wrecur_imag,wtemp_real; float scale; if(m != mstore) { /* free previously allocated storage and set new m */ if(mstore != 0) free(w); mstore = m; if(m == 0) return; /* if m=0 then done */ /* n = 2**m = inverse fft length */ n = 1 << m; le = n/2; /* allocate the storage for w */ w = (COMPLEX *) calloc(le-1,sizeof(COMPLEX)); if(!w) { printf("\nUnable to allocate complex W array\n"); exit(1); } /* calculate the w values recursively */ arg = 4.0*atan(1.0)/le; /* PI/le calculation */ wrecur_real = w_real = cos(arg); wrecur_imag = w_imag = sin(arg); /* opposite sign from fft */ xj = w; for (j = 1 ; j < le ; j++) { xj->real = (float)wrecur_real; xj->imag = (float)wrecur_imag; xj++; wtemp_real = wrecur_real*w_real - wrecur_imag*w_imag; wrecur_imag = wrecur_real*w_imag + wrecur_imag*w_real; wrecur_real = wtemp_real; } } /* start inverse fft */ le = n; windex = 1; for (l = 0 ; l < m ; l++) { le = le/2; /* first iteration with no multiplies */ for(i = 0 ; i < n ; i = i + 2*le) { xi = x + i; xip = xi + le; temp.real = xi->real + xip->real; temp.imag = xi->imag + xip->imag; xip->real = xi->real - xip->real; xip->imag = xi->imag - xip->imag; *xi = temp; } /* remaining iterations use stored w */ wptr = w + windex - 1; for (j = 1 ; j < le ; j++) { u = *wptr; for (i = j ; i < n ; i = i + 2*le) { xi = x + i; xip = xi + le; temp.real = xi->real + xip->real; temp.imag = xi->imag + xip->imag; tm.real = xi->real - xip->real; tm.imag = xi->imag - xip->imag; xip->real = tm.real*u.real - tm.imag*u.imag; xip->imag = tm.real*u.imag + tm.imag*u.real; *xi = temp; } wptr = wptr + windex; } windex = 2*windex; } /* rearrange data by bit reversing */ j = 0; for (i = 1 ; i < (n-1) ; i++) { k = n/2; while(k <= j) { j = j - k; k = k/2; } j = j + k; if (i < j) { xi = x + i; xj = x + j; temp = *xj; *xj = *xi; *xi = temp; } } /* scale all results by 1/n */ scale = (float)(1.0/n); for(i = 0 ; i < n ; i++) { x->real = scale*x->real; x->imag = scale*x->imag; x++; } } /************************************************************ rfft - trig recombination real input FFT Requires real array pointed to by x, pointer to complex output array, y and the size of real FFT in power of 2 notation, m (size of input array and FFT, N = 2**m). On completion, the COMPLEX array pointed to by y contains the lower N/2 + 1 elements of the spectrum. void rfft(float *x, COMPLEX *y, int m) ***************************************************************/ static void rfft(float *x,COMPLEX *y,int m) { static COMPLEX *cf; static int mstore = 0; int p,num,k,index; float Realsum, Realdif, Imagsum, Imagdif; double factor, arg; COMPLEX *ck, *xk, *xnk, *cx; /* First call the fft routine using the x array but with half the size of the real fft */ p = m - 1; cx = (COMPLEX *) x; fft(cx,p); /* Next create the coefficients for recombination, if required */ num = 1 << p; /* num is half the real sequence length. */ if (m!=mstore){ if (mstore != 0) free(cf); cf = (COMPLEX *) calloc(num - 1,sizeof(COMPLEX)); if(!cf){ printf("\nUnable to allocate trig recomb coefficients."); exit(1); } factor = 4.0*atan(1.0)/num; for (k = 1; k < num; k++){ arg = factor*k; cf[k-1].real = (float)cos(arg); cf[k-1].imag = (float)sin(arg); } } /* DC component, no multiplies */ y[0].real = cx[0].real + cx[0].imag; y[0].imag = 0.0; /* other frequencies by trig recombination */ ck = cf; xk = cx + 1; xnk = cx + num - 1; for (k = 1; k < num; k++){ Realsum = ( xk->real + xnk->real ) / 2; Imagsum = ( xk->imag + xnk->imag ) / 2; Realdif = ( xk->real - xnk->real ) / 2; Imagdif = ( xk->imag - xnk->imag ) / 2; y[k].real = Realsum + ck->real * Imagsum - ck->imag * Realdif ; y[k].imag = Imagdif - ck->imag * Imagsum - ck->real * Realdif ; ck++; xk++; xnk--; } } /*--------------------------------------------------------------------------*/ static void float_to_complex (float *x,COMPLEX *xc,int ln) { int i; if ((ln-1) == 0) { (*xc).real = (*x); (*xc).imag = 0.0; return; } else { for (i=0;i lnx+1) { error_message ("c_padd","ix > lnx+1 !",1); exit(1); } for (i=0;inx; nrow = im->ny; mri_free(im); im = NULL; return(ncol); } /*--------------------------------------------------------------------------*/ static int Read_file (float *x,char *f_name,int n_points) { /* pass a 0 to n_points if you want to read till EOF */ int cnt=0,ex,dec; FILE*internal_file; internal_file = fopen (f_name,"r"); if (internal_file == NULL) { printf ("\aCould not open %s \n",f_name); printf ("Exiting @ Read_file function\n"); exit (0); } ex = fscanf (internal_file,"%f",&x[cnt]); while (ex != EOF) { ++cnt; /* NOT WORKING, RETURNS SIZEOF (FLOAT) ..... if (sizeof(x) < cnt) { printf ("%d = sizeof(x)\n",sizeof(x)); printf ("\nNot Enough Memory Allocated \n\a"); printf ("Exiting @Read_file function\n"); exit (0); } ............................................ */ ex = fscanf (internal_file,"%f",&x[cnt]); if ((n_points != 0) && (cnt == n_points)) ex = EOF; } if (cnt < n_points) { printf ("\a\nAttempt to read %d points failed,\n",n_points); printf (" file contains %d points only.\n",cnt); do { printf ("End Execution (Yes (1) No (0) ? : "); ex=scanf ("%d",&dec); } while (ex != 1 || (dec != 1 && dec !=0)); if (dec) { printf ("Exiting @ Read_file function\n"); exit (0); } else printf ("\nContinuing execution with %d points\n",cnt); } fclose (internal_file); return (cnt); } /*--------------------------------------------------------------------------*/ static void linear_reg (float *x,float *y,int size,float *a,float *b,int *err) {/* linear_reg*/ int i; float n,sum_x,sum_y,sum_x2,sum_xy; *err = 3; if (size <= 0) { *err = 1; return; } sum_x = 0.0; sum_y = 0.0; sum_xy = 0.0; sum_x2 = 0.0; n = (float)size; for (i=0;i topi/2.0) alf = topi/2.0-alf; return (alf); }/*punwrap*/ /*--------------------------------------------------------------------------*/ static float Lagrange_interp (float *x,float *y,float xi,int ln) { int i,j; float yi,p; yi = 0.0; for (i=0;i 1) { fprintf (stderr, "Resetting hilbertdelay_V2 ...\n"); } free_well (fftx); free_well (fftxc); free_well (ffty); free_well (fftyc); free_well (Px); free_well (Py); free_well (Pxx); free_well (Pyy); free_well (Pxy); free_well (Rxx); free_well (Ryy); free_well (Rxy); free_well (HRxy); free_well (xp); free_well (yp); free_well (ubias); free_well (xcpy); free_well (ycpy); free_well (tmp_f_vect); free_well (tmp_f_vect2); if (fftyca) free2D ((char **)fftyca,lng+2); fftyca = NULL; if (Pxya) free2D ((char **)Pxya,lng+2); Pxya = NULL; if (Rxxa) free2D ((char **)Rxxa,lng+2); Rxxa = NULL; if (Ryya) free2D ((char **)Ryya,lng+2); Ryya = NULL; i_call=0, olng = 0, m =0, lng_use =0, lng = 0, strt = 0, nd = 0, sg = 0, cnt = 0,maxdel = 0; a=0.0,var_y=0.0,varu_y=0.0,stdv_y=0.0, stdvu_y=0.0,var_x=0.0,varu_x=0.0,stdv_x=0.0,stdvu_x=0.0; /* [PT: Aug 25, 2022] *don't* return here, but keep going to try the calc; 0 should still be returned in other bad cases if a solution can't be found. If this *does* return here, then it starts a stream of all-zeros being returned in some cases of hitting one 'problem' voxel. -> goes along with setting 'opt=0' in main 3ddelay.c file. */ //return (0); } *del = NoWayDelay; /* initialize to an unlikely value ...*/ *xcorCoef = NoWayxcorCoef; /*--------------------------------------------------------------------------*/ /* First call, init. and do computations for reference time series */ /*--------------------------------------------------------------------------*/ if (i_call == 0) {/*i_call == 0*/ if ((Nseg < 1) || (Nseg >= lng_full/5)) { sprintf (buf,"Number of segments (%d) null or too large,\n" "or vector length too small (%d) for %d segments ", Nseg,lng_full,Nseg); error_message ("hilbertdelay_V2",buf,0); return (2); } lng = (int)((float)lng_full / (float)Nseg); /* individ. seg. length */ maxdel = lng/2; /* delays should not exceed one third of the segment length (and that's pushing it !)*/ m=0; while ((int)pow((double)2,(double)m) < lng) ++m; /* find closest power of two to the length of the series */ olng = lng; /* save old length*/ lng = (int)pow((double)2,(double)m); /* set new length as power of two actual padding length will double in order to correct for circular convolution effects */ lng_use = lng; /* useful length of spectrum after correction for circular convolution effects */ if (delay_verb()>1) { fprintf (stderr, "selected m=%d for a padded segment length of %d,\n" "old segment length was %d\n" "Vector holds %d segments\n",m,lng,olng,Nseg); } if (fftx || fftxc || ffty || fftyc || Pxy || Px || Pxx || Py || Pyy || Rxx || Ryy || Rxy || HRxy || xcpy || ycpy || xp || yp || ubias || tmp_f_vect || tmp_f_vect2 || fftyca || Pxya || Ryya || Rxxa ) { sprintf (buf,"Initialization problem!\n"); error_message ("hilbertdelay_V2",buf,0); return (ERROR_QUIT); } fftx = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); fftxc = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); ffty = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); fftyc = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Pxy = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Px = (float *) calloc ((2*lng)+2,sizeof(float)); Pxx = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Py = (float *) calloc ((2*lng)+2,sizeof(float)); Pyy = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Rxx = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Ryy = (COMPLEX *) calloc ((2*lng)+2,sizeof(COMPLEX)); Rxy = (float *) calloc ((2*lng)+2,sizeof(float)); HRxy = (float *) calloc ((2*lng)+2,sizeof(float)); xcpy = (float *) calloc ((2*olng)+2,sizeof(float)); ycpy = (float *) calloc ((2*olng)+2,sizeof(float)); xp = (float *) calloc ((2*lng)+2,sizeof(float)); yp = (float *) calloc ((2*lng)+2,sizeof(float)); ubias = (float *) calloc ((2*lng)+2,sizeof(float)); tmp_f_vect = (float *) calloc ((2*lng)+2,sizeof(float)); tmp_f_vect2 = (float *) calloc ((2*lng)+2,sizeof(float)); fftyca = (COMPLEX **) allocate2D ((2*lng)+2,Nseg,sizeof(COMPLEX)); Pxya = (COMPLEX **) allocate2D ((2*lng)+2,Nseg,sizeof(COMPLEX)); Ryya = (COMPLEX **) allocate2D ((2*lng)+2,Nseg,sizeof(COMPLEX)); Rxxa = (COMPLEX **) allocate2D ((2*lng)+2,Nseg,sizeof(COMPLEX)); if (fftx == NULL || fftxc == NULL || ffty == NULL || fftyc == NULL || Pxy == NULL || Px == NULL || Py == NULL || xp == NULL || yp == NULL || ubias == NULL || tmp_f_vect == NULL || Pxx == NULL || Pyy == NULL || Rxx == NULL || Ryy == NULL || fftyca == NULL || Pxya == NULL || Ryya == NULL || Rxxa == NULL || tmp_f_vect2 == NULL) { printf ("\nFatal Error : Failed to Allocate memory\a\n"); printf ("Abandon Lab Immediately !\n\n"); return(ERROR_QUIT); } /* creating a vector to remove the bowtie artifact from the auto and cross correlation curves, and set to zero their irrelevant values */ if (biasrem == 1) { for (i=0;i<(2*lng);++i) { if (i < olng) { ubias[i] = (float)olng / (float)(olng - i); } else { ubias[i] = 0.0; } } } a = (float)olng; /* Scaling parameter for spectral estimates */ strt = 0; /* setting up for segments loop */ nd = 0; for (sg=0;sg 0 */ Ryy[i].real = Ryy[i].real + Ryya[i][sg].real; Ryy[i].imag = Ryy[i].imag + Ryya[i][sg].imag; }/* sg > 0 */ }/* for i */ }/* for sg */ c_scale (Ryy,Ryy,1.0/((float)Nseg * a),2*lng); /* scaling periodogram */ ifft (Ryy,m+1); /* autocorrelation of y*/ }/*i_call == 0*/ /*--------------------------------------------------------------------------*/ /* Steps for each new time series */ /*--------------------------------------------------------------------------*/ strt = 0; /* setting up for segments loop */ nd =0; for (sg=0;sg 1) { write_float (xp,"dbg_xdp.txt",2*lng); write_float (yp,"dbg_ydp.txt",2*lng); fprintf (stderr,"a = %f\n",a); } for (i=0;i<2*lng;++i) { /* fftyc at segment sg from storage array */ fftyc[i].real = fftyca[i][sg].real; fftyc[i].imag = fftyca[i][sg].imag; } c_mult (fftx,fftyc,Pxy,2*lng); /* Computing the cross power spectrum */ for (i=0;i<2*lng;++i) { /* storing the power spectrum and the cross power spectrum at different segments */ Pxya[i][sg].real = Pxy[i].real; Pxya[i][sg].imag = Pxy[i].imag; Rxxa[i][sg].real = Rxx[i].real; Rxxa[i][sg].imag = Rxx[i].imag; } }/* for sg */ for (sg=0;sg 1) { write_float (Rxy,"dbg_Rxy.txt",2*lng); write_float (HRxy,"dbg_HRxy.txt",2*lng); write_float (ubias,"dbg_ubias.txt",2*lng); } for (i=0;i maxdel) {/* i > maxdel */ /*sprintf (buf,"Delay larger than 1/2 segment length (%d)",maxdel); error_message ("hilbertdelay_V2",buf,0);*/ return (3); }/* i > maxdel */ if (HRxy[i] == 0.0) {/* HRxy[i] == 0.0 */ if (Rxy[i] > 0.0) *slp = 1.0; else *slp = -1.0; izero = (float) i; *xcor = Rxy[i]; /* storing value of max covariance */ i=lng; } else {/* HRxy[i] != 0.0 */ if ((HRxy[i] * HRxy[i+1]) < 0.0) { /* the sign of slp was used to determine the sign of the cross correlation. The sign of slp should be the same as that of Rxy[i] close to izero. Moreover, I think the use of the sign of Rxy[i] is better since with no subtraction performed, I am less sensitive to high freq. noise */ if (Rxy[i] >= 0.0) *slp = 1.0; else *slp = -1.0; if ((*slp > 0.0)) { f_i = (float) (i); f_i1 = (float) (i+1); reg_pnt = 0.0; linear_interp (&HRxy[i],&f_i,&HRxy[i+1],&f_i1, ®_pnt,&izero,1); /* find the peak of the cross correlation curve */ k = 0; for (j=-3;j<=3;++j) { if (((i+j) >= 0) && ((i+j) < lng)) { tmp_f_vect[k] = (float) (i+j); tmp_f_vect2[k] = Rxy[i+j]; ++k; } } if (k > 1) {/* at least a 1st order interpolation must be performed */ *xcor = Lagrange_interp (tmp_f_vect,tmp_f_vect2,izero,k); } i = lng; } } }/* HRxy[i] != 0.0 */ }/* for i */ *del = izero + Dtx; /* delay is in sample units corrected by the sampling time difference*/ if (Rxx[0].real && Ryy[0].real) { *xcorCoef = *xcor / sqrt (Rxx[0].real * Ryy[0].real) * *slp; /* correction for sign of cross correlation coefficient (slp = 1.0 or -1.00*/ } else { if (delay_verb() > 2) { printf ("\nZero Variance...\n"); } } /* set vx and vy */ *vx = Rxx[0].real; *vy = Ryy[0].real; ++i_call; return (0); } /*--------------------------------------------------------------------------*/ static void hunwrap (float del, float fs, float T, float slp, int wrp, int unt, int rev, float scl, float *delu ) {/*hunwrap*/ float pi = 3.1416, tmp; if (fs > 0.0) { /* delay should be in seconds */ del = del / fs; } if (T > 0.0) {/* Period unwrapping possible */ if (slp < 0.0) {/* Unwrapping required to determine correct delay */ tmp = del * 360.0 / T; /* from time to polar angle */ tmp = punwrap (tmp,1); /* unwrap */ tmp = tmp + 180.0; /* augment by pi */ del = tmp * T / 360.0; /* from polar to time */ } /* Now for the case where we get negative delays although no wrapping has been done, namely because of the sampling time correction. */ if (del < 0.0 || del > T) { tmp = del * 360.0 / T; /* from time to polar angle */ if (del < 0.0) { tmp = tmp + 360.0; } else { if (del > T) tmp = tmp - 360.0; } del = tmp * T / 360.0; /* from polar to time */ } if (rev == 1) { del = T - del; /* reverse direction */ } if (scl != 1.0) { del = del*scl; } if (wrp == 1) {/* map of (0-pi) to (0-pi) and (pi-2pi) to (pi-0) */ if (scl != 1.0) { static int iwarn = 0; if (!iwarn) { fprintf(stderr, "\n" "WARNING: wrap is meaningless with scl != 1.0\n" " Check your results.\n"); ++iwarn; } } tmp = del * 360.0 / T; /* from time to polar angle */ tmp = punwrap (tmp,1); /* unwrap */ del = tmp * T / 360.0; /* from polar to time */ }/* map of (0-pi) to (0-pi) and (pi-2pi) to (pi-0) */ if (unt == METH_DEGREES) del = del * 360.0 / T; /* from time to polar angle in degrees*/ if (unt == METH_RADIANS) del = del * 2 * pi / T; /* from time to polar angle in degrees*/ }/* Period unwrapping possible */ *delu = del; return; }/*hunwrap*/ /*--------------------------------------------------------------------------*/ static void disp_comp_vect (COMPLEX *v,int l) { int i; printf ("\n"); if ((l-1) == 0) { printf ("V = (%f,%f)\n",(*v).real,(*v).imag); } else { for (i=0;i