Esempio n. 1
0
void fit_noise(struct complex *ncf,int *badlag,struct FitACFBadSample *badsmp,
			   double skynoise,struct FitPrm *prm,
			   struct FitRange *ptr) {
 
  int lag_lim;
  int istat, j;
  double A, tau, t;
  

  lag_lim = prm->mplgs/2;	/* require at least 1/2 of lags be OK*/

  istat = fit_acf(ncf, 1, badlag, badsmp, lag_lim, prm, 0.0, 0,0.0,ptr);

  tau = prm->mpinc * 1.0e-6;

  if (istat ==1 && (ptr->v == 0.0)) ptr->v = 1.0;
  if (istat == 1 && (fabs(ptr->v_err/ptr->v) < 0.05)) {
    if (ptr->w_l_err <= ptr->w_s_err) {
      if (ptr->p_s > skynoise) ptr->p_s = skynoise;
      A = exp(ptr->p_s);
      for (j=0; j < prm->mplgs; ++j) {
        t = (prm->lag[1][j] - prm->lag[0][j])*tau;
        ncf[j].x = A*exp(-ptr->w_l*t)*cos(ptr->v*t);
        ncf[j].y = A*exp(-ptr->w_l*t)*sin(ptr->v*t);
      }
    } else {
      if (ptr->p_s > skynoise) ptr->p_s = skynoise;
      A = exp(ptr->p_s);
      for (j=0; j < prm->mplgs; ++j) {
        t = (prm->lag[1][j] - prm->lag[0][j])*tau;
        ncf[j].x = A*exp(-(ptr->w_s*t)*(ptr->w_s*t))*cos(ptr->v*t);
        ncf[j].y = A*exp(-(ptr->w_s*t)*(ptr->w_s*t))*sin(ptr->v*t);
      }
    }
  } else
    for (j=0; j < prm->mplgs; ++j) {
      ncf[j].x = 0;
      ncf[j].y = 0;
    }
  return;
}
Esempio n. 2
0
int do_fit(struct FitBlock *iptr,int lag_lim,int goose,
	   struct FitRange *ptr,struct FitRange *xptr,
           struct FitElv *elv,
	   struct FitNoise *nptr) {

  struct FitACFBadSample badsmp;
  int badlag[MAX_RANGE][LAG_SIZE];

  int i=0,k;

  double pwrd[MAX_RANGE],pwrt[MAX_RANGE];
  double mnpwr, skylog, freq_to_vel, range;
  double xomega=0.0;

  double noise_pwr=0.0; 
  int ni;

  nptr->skynoise=0.0;
  nptr->lag0=0.0;
  nptr->vel=0.0;


  if (iptr->prm.nave <= 1) return 0;

  freq_to_vel = C/(4*PI)/(iptr->prm.tfreq * 1000.0);

  if (iptr->prm.channel==0) FitACFBadlags(&iptr->prm,&badsmp);	
  else FitACFBadlagsStereo(&iptr->prm,&badsmp);  


  /* Determine the lag_0 noise level (0 dB reference) and the noise level at 
   which fit_acf is to quit (average power in the 
   fluctuations of the acfs which are pure noise) */

 
	for (i=0; i < iptr->prm.nrang; i++) {
	  pwrd[i] = (double) iptr->prm.pwr0[i];	/* transfer powers into local array */
	  pwrt[i] = pwrd[i];
	}
	qsort(pwrt, iptr->prm.nrang, sizeof(double), dbl_cmp);
	/* determine the average lag0 power of the 10 lowest power acfs */
	
	ni = 0;
	i = 0;
	mnpwr = 0.0;
	
	/*  look for the lowest 10 values of lag0 power and average to 
		get the noise level.  Ignore values that are exactly 0.  If
		you can't find 10 useable values within the first 1/3 of the
		sorted power list, then just use whatever you got in that 
		first 1/3.  If you didn't get any useable values, then use
		the NOISE parameter */
		
	while ((ni < 10) && (i < iptr->prm.nrang/3)) {
          if (pwrt[i]) ++ni;
          mnpwr += pwrt[i++];
	  
	}

	ni = (ni > 0) ? ni :  1;
	mnpwr = mnpwr/ni;
	if (mnpwr < 1.0) mnpwr = iptr->prm.noise;
	nptr->skynoise = mnpwr;

/* Now determine the level which will be used as the cut-off power 
	for fit_acf.  This is the average power at all non-zero lags of all
	acfs which have lag0 power < 1.6*mnpwr + 1 stnd. deviation from that
	average power level */

	noise_pwr = noise_stat(mnpwr,&iptr->prm,&badsmp,
                           iptr->acfd); 



  /*	convert the lag0 powers to dB */

  if (nptr->skynoise > 0.0) skylog = 10.0 * log10(nptr->skynoise);
  else skylog = 0.0;

  for (i=0; i<iptr->prm.nrang; i++) {	
    pwrd[i] = pwrd[i] - nptr->skynoise;
	if (pwrd[i] <= 0.0) ptr[i].p_0 = -50.0;
	else ptr[i].p_0 = 10.0*log10(pwrd[i]) - skylog;
  }

  /*	reset the output arrays */

  for (i=0; i<MAX_RANGE; i++) {
	ptr[i].p_l = -50.0;
	ptr[i].p_s = -50.0;
	ptr[i].p_l_err= 0.0;
	ptr[i].p_s_err= 0.0;
	ptr[i].w_l = 0.0;
	ptr[i].w_s = 0.0;
	ptr[i].w_l_err = 0.0;
	ptr[i].w_s_err = 0.0;
	ptr[i].v = 0.0;
	ptr[i].v_err = 0.0;
	ptr[i].phi0 = 0.0;
	ptr[i].phi0_err=0.0;
	ptr[i].sdev_l = 0.0;
	ptr[i].sdev_s = 0.0;
	ptr[i].sdev_phi = 0.0;
	ptr[i].gsct = 0.0;
        ptr[i].qflg = 0;
	ptr[i].nump=0;

	xptr[i].p_l = -50.0;
	xptr[i].p_s = -50.0;
	xptr[i].p_l_err= 0.0;
	xptr[i].p_s_err= 0.0;
	xptr[i].w_l = 0.0;
	xptr[i].w_s = 0.0;
	xptr[i].w_l_err = 0.0;
	xptr[i].w_s_err = 0.0;
	xptr[i].v = 0.0;
	xptr[i].v_err = 0.0;
	xptr[i].phi0 = 0.0;
	xptr[i].phi0_err=0.0;
	xptr[i].sdev_l = 0.0;
	xptr[i].sdev_s = 0.0;
	xptr[i].sdev_phi = 0.0;
	xptr[i].gsct = 0.0;
	xptr[i].qflg = 0;
        xptr[i].nump=0;

	elv[i].normal= 0.0;
	elv[i].low = 0.0;
	elv[i].high = 0.0;


  }

 /* ----------------------------------------------------------------------*/
 /* 	Now do the fits for each acf */

  for (k=0, i=0; k<iptr->prm.nrang;k++) {

	ptr[k].qflg = fit_acf(iptr->acfd[k], k+1,badlag[k],&badsmp,
                              lag_lim,&iptr->prm,noise_pwr,0,0.0,&ptr[k]);
        xomega=ptr[k].v;
	if (ptr[k].qflg == 1)	{
          /* several changes have been made here to 
	     fix an apparent problem in handling HUGE_VAL.
	     
	     If there are too few points in an ACF to allow
	     the error on a parameter to be calculated then
	     the subroutine fit_acf sets the value to HUGE_VAL.

	     However, in this routine the error values are converted
	     to natural units (e.g. velocity instead of frequency).
	     It appears that multiplying HUGE_VAL by something causes
	     a floating point exception that then sets the result of
	     the calculation to 0.  Thus the error values that were being
	     stored in the file would be zero instead of HUGE_VAL.

	     The code now checks to see if the value is set to
	     HUGE_VAL before doing the conversion.  If it is then
	     instead of a converted version the error value is
	     reset to HUGE_VAL.
	     */

 /* convert power from natural log to dB */

	  ptr[k].p_l = ptr[k].p_l*LN_TO_LOG - skylog;
	  ptr[k].p_s = ptr[k].p_s*LN_TO_LOG - skylog;

	  ptr[k].p_l_err = (ptr[k].p_l_err == HUGE_VAL) ?
	                   HUGE_VAL :
	                   ptr[k].p_l_err*LN_TO_LOG;

	  ptr[k].p_s_err = (ptr[k].p_s_err == HUGE_VAL) ?
	                   HUGE_VAL :
	                   ptr[k].p_s_err*LN_TO_LOG;

	  /* convert Doppler frequency to velocity */

	  ptr[k].v = iptr->prm.vdir*freq_to_vel*ptr[k].v;

          /* flag absurdly high velocities with qflg of 8 */

          if (ptr[k].v > (freq_to_vel* (PI* 1000.0* 1000.0)/ iptr->prm.mpinc))
              ptr[k].qflg= 8;	  
	  
	  ptr[k].v_err = (ptr[k].v_err == HUGE_VAL) ?
			  HUGE_VAL : 
			  freq_to_vel*ptr[k].v_err;



	  /* convert decay parameters to spectral widths */

	  ptr[k].w_l = freq_to_vel*2*ptr[k].w_l;
	  ptr[k].w_l_err = (ptr[k].w_l_err == HUGE_VAL) ?
	                   HUGE_VAL :
	                   freq_to_vel*2*ptr[k].w_l_err;

	  /* sigma is returned as sigma**2 so check the sign for validity
	  if sigma**2 is negative take sqrt of the abs and transfer the sign */

	  ptr[k].w_s = (ptr[k].w_s >= 0) ? 
                      sqrt(ptr[k].w_s) : -sqrt(-ptr[k].w_s);


	  if ((ptr[k].w_s !=0.0) && (ptr[k].w_s_err != HUGE_VAL))
	    ptr[k].w_s_err = 0.5*ptr[k].w_s_err/fabs(ptr[k].w_s);
          else ptr[k].w_s_err=HUGE_VAL;




	  ptr[k].w_s = 3.33*freq_to_vel*ptr[k].w_s;
	  ptr[k].w_s_err = (ptr[k].w_s_err == HUGE_VAL) ?
	                    HUGE_VAL :
	                    3.33*freq_to_vel*ptr[k].w_s_err;
        


  	  /*  Now check the values of power, velocity and width
	      to see if this should be flagged as ground-scatter */
	        
	  if (ptr[k].gsct == 0) ptr[k].gsct=ground_scatter(&ptr[k]); 
	}
	
	if ((iptr->prm.xcf != 0) && (ptr[k].qflg == 1)) {
	   xptr[k].qflg = fit_acf(iptr->xcfd[k], k+1,badlag[k],&badsmp,
                                  lag_lim,&iptr->prm,noise_pwr,1,xomega,
				  &xptr[k]);
	}

	if (xptr[k].qflg == 1) {
          xptr[k].p_l = xptr[k].p_l*LN_TO_LOG - skylog;
	  xptr[k].p_s = xptr[k].p_s*LN_TO_LOG - skylog;
	  xptr[k].p_l_err = (xptr[k].p_l_err == HUGE_VAL) ?
	                    HUGE_VAL :
	                    xptr[k].p_l_err*LN_TO_LOG;

	  xptr[k].p_s_err = (xptr[k].p_s_err == HUGE_VAL) ?
	                    HUGE_VAL :
	                    xptr[k].p_s_err*LN_TO_LOG;

	  /* convert Doppler frequency to velocity */

	  xptr[k].v = iptr->prm.vdir*freq_to_vel*xptr[k].v;
	  xptr[k].v_err = (xptr[k].v_err == HUGE_VAL) ?
	                  HUGE_VAL :
	                  freq_to_vel*xptr[k].v_err;

	  /* convert decay parameters to spectral widths */

	  xptr[k].w_l = freq_to_vel*2*xptr[k].w_l;
	  xptr[k].w_l_err = (xptr[k].w_l_err == HUGE_VAL) ?
	                    HUGE_VAL :
	                    freq_to_vel*2*xptr[k].w_l_err;

	  /* sigma is returned as sigma**2 so check the sign for validity  
	  if sigma**2 is negative take sqrt of the abs and transfer the sign */

	  xptr[k].w_s = (xptr[k].w_s >= 0) ? 
                      sqrt(xptr[k].w_s) : -sqrt(-xptr[k].w_s);

	  if ((xptr[k].w_s !=0.0) && (xptr[k].w_s_err != HUGE_VAL))
	    xptr[k].w_s_err = 0.5*xptr[k].w_s_err/fabs(xptr[k].w_s);
          else xptr[k].w_s_err=HUGE_VAL;

	  xptr[k].w_s = 3.33*freq_to_vel*xptr[k].w_s;
	  xptr[k].w_s_err = (xptr[k].w_s_err == HUGE_VAL) ?
	                    HUGE_VAL :
	                    3.33*freq_to_vel*xptr[k].w_s_err;


		
	  /* calculate the elevation angle */
	
	  if (xptr[k].phi0 > PI)  xptr[k].phi0 = xptr[k].phi0 - 2*PI;
	  if (xptr[k].phi0 < -PI) xptr[k].phi0 = xptr[k].phi0 + 2*PI;
	  if (iptr->prm.phidiff != 0) 
	    xptr[k].phi0 = xptr[k].phi0*iptr->prm.phidiff;
 
          /* changes which array is first */
		
	  range = 0.15*(iptr->prm.lagfr + iptr->prm.smsep*(k-1));
          if (goose==0) {
	    elv[k].normal = elevation(&iptr->prm,range, xptr[k].phi0);
	    elv[k].low = 
            elevation(&iptr->prm,range, xptr[k].phi0+xptr[k].phi0_err);
	    elv[k].high = 
            elevation(&iptr->prm,range,xptr[k].phi0-xptr[k].phi0_err);
          } else {
  	    elv[k].normal = elev_goose(&iptr->prm,range, xptr[k].phi0);
	    elv[k].low = 
            elev_goose(&iptr->prm,range, xptr[k].phi0+xptr[k].phi0_err);
	    elv[k].high = 
            elev_goose(&iptr->prm,range, xptr[k].phi0-xptr[k].phi0_err);
          }
    }
    if( (ptr[k].qflg == 1)) i++;
  
  }

  return i;
}
Esempio n. 3
0
void low_do_autocorr(const char *fn,const output_env_t oenv,const char *title,
		     int nframes,int nitem,int nout,real **c1,
		     real dt,unsigned long mode,int nrestart,
		     gmx_bool bAver,gmx_bool bNormalize,
		     gmx_bool bVerbose,real tbeginfit,real tendfit,
		     int eFitFn,int nskip)
{
  FILE    *fp,*gp=NULL;
  int     i,k,nfour;
  real    *csum;
  real    *ctmp,*fit;
  real    c0,sum,Ct2av,Ctav;
  gmx_bool    bFour = acf.bFour;
 
  /* Check flags and parameters */ 
  nout = get_acfnout();
  if (nout == -1)
    nout = acf.nout = (nframes+1)/2;
  else if (nout > nframes)
    nout=nframes;
  
  if (MODE(eacCos) && MODE(eacVector))
    gmx_fatal(FARGS,"Incompatible options bCos && bVector (%s, %d)",
		__FILE__,__LINE__);
  if ((MODE(eacP3) || MODE(eacRcross)) && bFour) {
    fprintf(stderr,"Can't combine mode %lu with FFT, turning off FFT\n",mode);
    bFour = FALSE;
  }
  if (MODE(eacNormal) && MODE(eacVector)) 
    gmx_fatal(FARGS,"Incompatible mode bits: normal and vector (or Legendre)");
    
  /* Print flags and parameters */
  if (bVerbose) {
    printf("Will calculate %s of %d thingies for %d frames\n",
	   title ? title : "autocorrelation",nitem,nframes);
    printf("bAver = %s, bFour = %s bNormalize= %s\n",
	   bool_names[bAver],bool_names[bFour],bool_names[bNormalize]);
    printf("mode = %lu, dt = %g, nrestart = %d\n",mode,dt,nrestart);
  }
  if (bFour) {  
    c0 = log((double)nframes)/log(2.0);
    k  = c0;
    if (k < c0)
      k++;
    k++;
    nfour = 1<<k;
    if (debug)
      fprintf(debug,"Using FFT to calculate %s, #points for FFT = %d\n",
	      title,nfour);
	
    /* Allocate temp arrays */
    snew(csum,nfour);
    snew(ctmp,nfour);
  } else {
    nfour = 0; /* To keep the compiler happy */
    snew(csum,nframes);
    snew(ctmp,nframes);
  }
  
  /* Loop over items (e.g. molecules or dihedrals) 
   * In this loop the actual correlation functions are computed, but without
   * normalizing them.
   */
  k = max(1,pow(10,(int)(log(nitem)/log(100))));
  for(i=0; i<nitem; i++) {
    if (bVerbose && ((i%k==0 || i==nitem-1)))
      fprintf(stderr,"\rThingie %d",i+1);
    
    if (bFour)
      do_four_core(mode,nfour,nframes,nframes,c1[i],csum,ctmp);
    else 
      do_ac_core(nframes,nout,ctmp,c1[i],nrestart,mode);
  }
  if (bVerbose)
    fprintf(stderr,"\n");
  sfree(ctmp);
  sfree(csum);
  
  if (fn) {
    snew(fit,nout);
    fp=xvgropen(fn,title,"Time (ps)","C(t)",oenv);
  } else {
    fit = NULL;
    fp  = NULL;
  }
  if (bAver) {
    if (nitem > 1)
      average_acf(bVerbose,nframes,nitem,c1);
    
    if (bNormalize)
      normalize_acf(nout,c1[0]);
    
    if (eFitFn != effnNONE) {
      fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[0],fit);
      sum = print_and_integrate(fp,nout,dt,c1[0],fit,1);
    } else {
      sum = print_and_integrate(fp,nout,dt,c1[0],NULL,1);
      if (bVerbose)
	printf("Correlation time (integral over corrfn): %g (ps)\n",sum);
    }
  } else {
    /* Not averaging. Normalize individual ACFs */
    Ctav = Ct2av = 0;
    if (debug)
      gp = xvgropen("ct-distr.xvg","Correlation times","item","time (ps)",oenv);
    for(i=0; i<nitem; i++) {
      if (bNormalize)
	normalize_acf(nout,c1[i]);
      if (eFitFn != effnNONE) {
	fit_acf(nout,eFitFn,oenv,fn!=NULL,tbeginfit,tendfit,dt,c1[i],fit);
	sum = print_and_integrate(fp,nout,dt,c1[i],fit,1);
      } else {
	sum = print_and_integrate(fp,nout,dt,c1[i],NULL,1);
	if (debug)
	  fprintf(debug,
		  "CORRelation time (integral over corrfn %d): %g (ps)\n",
		  i,sum);
      }
      Ctav += sum;
      Ct2av += sum*sum;
      if (debug)
	fprintf(gp,"%5d  %.3f\n",i,sum);
    }
    if (debug)
      ffclose(gp);
    if (nitem > 1) {
      Ctav  /= nitem;
      Ct2av /= nitem;
      printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n",
	     Ctav,sqrt((Ct2av - sqr(Ctav))),
	     sqrt((Ct2av - sqr(Ctav))/(nitem-1)));
    }
  }
  if (fp)
    ffclose(fp);
  sfree(fit);
}
Esempio n. 4
0
void low_do_autocorr(const char *fn, const gmx_output_env_t *oenv, const char *title,
                     int nframes, int nitem, int nout, real **c1,
                     real dt, unsigned long mode, int nrestart,
                     gmx_bool bAver, gmx_bool bNormalize,
                     gmx_bool bVerbose, real tbeginfit, real tendfit,
                     int eFitFn)
{
    FILE       *fp, *gp = NULL;
    int         i;
    real       *csum;
    real       *ctmp, *fit;
    real        sum, Ct2av, Ctav;
    gmx_bool    bFour = acf.bFour;

    /* Check flags and parameters */
    nout = get_acfnout();
    if (nout == -1)
    {
        nout = acf.nout = (nframes+1)/2;
    }
    else if (nout > nframes)
    {
        nout = nframes;
    }

    if (MODE(eacCos) && MODE(eacVector))
    {
        gmx_fatal(FARGS, "Incompatible options bCos && bVector (%s, %d)",
                  __FILE__, __LINE__);
    }
    if ((MODE(eacP3) || MODE(eacRcross)) && bFour)
    {
        if (bVerbose)
        {
            fprintf(stderr, "Can't combine mode %lu with FFT, turning off FFT\n", mode);
        }
        bFour = FALSE;
    }
    if (MODE(eacNormal) && MODE(eacVector))
    {
        gmx_fatal(FARGS, "Incompatible mode bits: normal and vector (or Legendre)");
    }

    /* Print flags and parameters */
    if (bVerbose)
    {
        printf("Will calculate %s of %d thingies for %d frames\n",
               title ? title : "autocorrelation", nitem, nframes);
        printf("bAver = %s, bFour = %s bNormalize= %s\n",
               gmx::boolToString(bAver), gmx::boolToString(bFour),
               gmx::boolToString(bNormalize));
        printf("mode = %lu, dt = %g, nrestart = %d\n", mode, dt, nrestart);
    }
    /* Allocate temp arrays */
    snew(csum, nframes);
    snew(ctmp, nframes);

    /* Loop over items (e.g. molecules or dihedrals)
     * In this loop the actual correlation functions are computed, but without
     * normalizing them.
     */
    for (int i = 0; i < nitem; i++)
    {
        if (bVerbose && (((i % 100) == 0) || (i == nitem-1)))
        {
            fprintf(stderr, "\rThingie %d", i+1);
            fflush(stderr);
        }

        if (bFour)
        {
            do_four_core(mode, nframes, c1[i], csum, ctmp);
        }
        else
        {
            do_ac_core(nframes, nout, ctmp, c1[i], nrestart, mode);
        }
    }
    if (bVerbose)
    {
        fprintf(stderr, "\n");
    }
    sfree(ctmp);
    sfree(csum);

    if (fn)
    {
        snew(fit, nout);
        fp = xvgropen(fn, title, "Time (ps)", "C(t)", oenv);
    }
    else
    {
        fit = NULL;
        fp  = NULL;
    }
    if (bAver)
    {
        if (nitem > 1)
        {
            average_acf(bVerbose, nframes, nitem, c1);
        }

        if (bNormalize)
        {
            normalize_acf(nout, c1[0]);
        }

        if (eFitFn != effnNONE)
        {
            fit_acf(nout, eFitFn, oenv, fn != NULL, tbeginfit, tendfit, dt, c1[0], fit);
            sum = print_and_integrate(fp, nout, dt, c1[0], fit, 1);
        }
        else
        {
            sum = print_and_integrate(fp, nout, dt, c1[0], NULL, 1);
        }
        if (bVerbose)
        {
            printf("Correlation time (integral over corrfn): %g (ps)\n", sum);
        }
    }
    else
    {
        /* Not averaging. Normalize individual ACFs */
        Ctav = Ct2av = 0;
        if (debug)
        {
            gp = xvgropen("ct-distr.xvg", "Correlation times", "item", "time (ps)", oenv);
        }
        for (i = 0; i < nitem; i++)
        {
            if (bNormalize)
            {
                normalize_acf(nout, c1[i]);
            }
            if (eFitFn != effnNONE)
            {
                fit_acf(nout, eFitFn, oenv, fn != NULL, tbeginfit, tendfit, dt, c1[i], fit);
                sum = print_and_integrate(fp, nout, dt, c1[i], fit, 1);
            }
            else
            {
                sum = print_and_integrate(fp, nout, dt, c1[i], NULL, 1);
                if (debug)
                {
                    fprintf(debug,
                            "CORRelation time (integral over corrfn %d): %g (ps)\n",
                            i, sum);
                }
            }
            Ctav  += sum;
            Ct2av += sum*sum;
            if (debug)
            {
                fprintf(gp, "%5d  %.3f\n", i, sum);
            }
        }
        if (debug)
        {
            xvgrclose(gp);
        }
        if (nitem > 1)
        {
            Ctav  /= nitem;
            Ct2av /= nitem;
            printf("Average correlation time %.3f Std. Dev. %.3f Error %.3f (ps)\n",
                   Ctav, std::sqrt((Ct2av - gmx::square(Ctav))),
                   std::sqrt((Ct2av - gmx::square(Ctav))/(nitem-1)));
        }
    }
    if (fp)
    {
        xvgrclose(fp);
    }
    sfree(fit);
}