Example #1
0
HiVector DriftCorrect::Solve(const HiVector &d) {
    ostringstream hist;
    _data = d;
    if ( _skipFit || (!gotGoodLines(d))) {
        _b2 = _data;
        _coefs = HiVector(4, 0.0);
        _uncert = _coefs;
        _cc = HiVector(2, 0.0);
        _chisq = 0.0;
        if ( !gotGoodLines(d) ) {
            hist << "NotEnoughLines(GoodLines[" << goodLines(d)
                 << "],MinimumLines[" << _minLines << "]);";
        }

        hist << "SkipFit(TRUE: Not using LMFit)";
        _history.add(hist.str());
    }
    else {
        hist << "Fit(";
        _b2 = HiVector(goodLines(_data));
        if ( success(curvefit()) ) {
            _coefs = coefs();
            _uncert = uncert();
            hist << "Solved,#Iters[" << nIterations() << "],ChiSq[" << Chisq()
                 << "],DoF[" << DoF() << "])";
            _history.add(hist.str());
            _history.add("a0("+ToString(_coefs[0])+"+-"+ToString(_uncert[0])+")");
            _history.add("a1("+ToString(_coefs[1])+"+-"+ToString(_uncert[1])+")");
            _history.add("a2("+ToString(_coefs[2])+"+-"+ToString(_uncert[2])+")");
            _history.add("a3("+ToString(_coefs[3])+"+-"+ToString(_uncert[3])+")");
        }
        else {
            //  Punt, fit a straight line to the data
            _cc = poly_fit(d);
            HiVector a(4);
            a[0] = _cc[0];
            a[1] = _cc[1];
            a[2] = 0.0;
            a[3] = 0.0;
            _coefs = a;

            hist << "Failed::Reason("<< statusstr() << "),#Iters["
                 << nIterations() << "])";
            _history.add(hist.str());
            _history.add("a0("+ToString(_coefs[0])+")");
            _history.add("a1("+ToString(_coefs[1])+")");
            _history.add("a2("+ToString(_coefs[2])+")");
            _history.add("a3("+ToString(_coefs[3])+")");
            if ( _useLinFit ) {
                _history.add("OnFailureUse(LinearFit(Zf))");
            }
            else {
                _skipFit = true;
                _history.add("OnFailureUse(ZfBuffer)");
            }
        }
    }
    return (Yfit());
}
Example #2
0
bvec lorentzian_fit(double *x,bvec y)
{
  bvec d=poly_fit(x,1/y,2);
  bvec out(3,y.nboot,y.njack);
  //for(int i=0;i<3;i++) cout<<i<<" = "<<d[i]<<endl;
  out[1]=-0.5*d[1]/d[2];            //x0
  out[0]=1/(d[0]-sqr(out[1])*d[2]); //N
  out[2]=1/sqrt(d[2]*out[0]);       //sigma
  //cout<<"arg:"<<d[2]*out[0]<<endl;
  //for(int i=0;i<3;i++) cout<<i<<" out= "<<out[i]<<endl;

  return out;
}
Example #3
0
/**
 * @brief Compute the initial guess of the fit
 *
 * This method provides the non-linear fit with an initial guess of the
 * solution.  It involves a linear fit to the latter half of the data to
 * provide the first two coefficents, the difference of the averages of the
 * residuals at both ends of the data set and 5 times the last line time as
 * the final (fourth) element...a bit involved really.
 *
 * @return NLVector  4-element vector of the initial guess coefficients
 */
NonLinearLSQ::NLVector DriftCorrect::guess()  {
    int n = _data.dim();
    int nb = n - _badLines;

    HiVector b1 = _data.subarray(0, nb-1);
    LowPassFilterComp gfilter(b1, _history, _sWidth, _sIters);

    int nb2 = nb/2;
    _b2 = gfilter.ref();
    HiVector cc = poly_fit(_b2.subarray(nb2,_b2.dim()-1), nb2-1);

    //  Compute the 3rd term guess by getting the average of the residual
    //  at both ends of the data set.
    Statistics s;

    //  Get the head of the data set
    int n0 = MIN(nb, 20);
    for ( int k = 0 ; k < n0 ; k++ ) {
        double d = _b2[k] - (cc[0] + cc[1] * _timet(k));
        s.AddData(&d, 1);
    }
    double head = s.Average();

    //  Get the tail of the data set
    s.Reset();
    n0 = (int) (0.9 * nb);
    for ( int l = n0 ; l < nb ; l++ ) {
        double d = _b2[l] - (cc[0] + cc[1] * _timet(l));
        s.AddData(&d, 1);
    }
    double tail = s.Average();

    //  Populate the guess with the results
    NLVector g(4, 0.0);
    g[0] = cc[0];
    g[1] = cc[1];
    g[2] = head-tail;
    g[3] = -5.0/_timet(nb-1);
    _guess = g;
    _history.add("Guess["+ToString(_guess[0])+ ","+
                 ToString(_guess[1])+ ","+
                 ToString(_guess[2])+ ","+
                 ToString(_guess[3])+ "]");
    return (g);
}
int ws_inv_cmod5(double sigma0, double phi0, double theta0,
                 double *wnd1, double *wnd2,
                 double min_ws, double max_ws, int npts,
                 double hh)
{
  // ws_cmod5 will return a 2-element array where the first element is the sigma0
  // that you'd get at min_ws, and the second element is the sigma0 that you get
  // at max_ws;
  // (phi0 is phi_diff, the diff between wind_dir and r_look, and theta0 is incidence angle)
  // Note that the 0.0 (last parameter) is r_look according to ws_cmod5, but the ws_cmod5 function
  // doesn't make use of it ...or more accurately, it's already built into the phi0 value.
  g_assert(max_ws > min_ws);
  g_assert(npts > 0);
  double *wd;
  int i;

  // Make an npts-element array of windspeeds that range from min_ws to max_ws linearly
  wd = maken(min_ws, max_ws, npts);
  g_assert(wd != NULL);

  // Calculate an npts-element array of normalized radar cross section (NRCS) using
  // the CMOD5 algorithm
  double *sg0 = ws_cmod5(wd, npts, phi0, theta0, 0.0); // Returned sg0[] has npts elements in it
  g_assert(sg0 != NULL);

  // See lines 118-123 in ws_inv_cmod5.pro
  // NOTE: The CMOD5 and CMOD4 algorithms need an adjustment when the polarization
  // is HH (since the original algorithms were developed for VV polarization only)
  // hh == -3 when polarization is VV, hh == 0.6 when polarization is HH
  // FIXME: Add cases for hh eq to -1 and -2
  double rr = (hh > 0.0) ? ws_pol_ratio(theta0, hh) : 1.0;
  sigma0 = (hh != -3) ? sigma0 / rr : sigma0; // HH adjustment or not

  // If sigma0 is lower than what you'd get at minimum windspeed, then set the windspeed to
  // the minimum and return. (Line 129)
  double min_nrcs = arr_min(sg0, npts); // Min should be sg0[0], but make sure...
  if (sigma0 < min_nrcs) {
    *wnd1 = wd[0];
    *wnd2 = WND1_IS_MINIMUM_WIND;
    FREE(wd);
    FREE(sg0);
    return 0;
  }

  // Create sign of differences array
  int ct=0;
  double *s = (double *)MALLOC(sizeof(double) * npts);
  for (i=0; i<npts; i++) {
    s[i] = SIGN(sg0[i] - sigma0);
    ct += s[i] == 0 ? 1 : 0;
    s[i] = (ct > 0 && s[i] == 0) ? 1.0 : s[i];
  }

  // Count the sign changes
  ct = 0;
  int ww = -1; // Where first sign change occurs
  int ww2 = -1; // Where second sign change occurs
  for (i=1; i<npts; i++) {
    ct += (s[i] != s[i-1]) ? 1 : 0;
    ww = (ct > 0 && ww < 0) ? i : ww;
    ww2 = (ct > 0 && ww > 0 && ww2 < 0) ? i : ww2;
  }

  // Calculate wind for the 3 cases (no sign changes, one sign change, two sign changes, and other)
  switch(ct) {
    case 0:
      {
        // No sign changes means sigma0 > max(sg0[])
        int nn = npts;
        double max_sg0 = arr_max(sg0, npts);
        int idx_first_max = -1;
        int *w = (int *)CALLOC(nn, sizeof(int));
        int wx = 0;
        for (i=0; i<npts; i++) {
          if (sg0[i] >= max_sg0) {
            idx_first_max = (idx_first_max < 0) ? i : idx_first_max;
            w[wx++] = i; // Collect indices of max's
          }
        }
        if (idx_first_max == nn - 1) {
          // Last element was the largest element, so send back max wind
          *wnd1 = wd[nn-1];
          *wnd2 = WND_FROM_MAX_SIGMA0;
        }
        else {
          int ix1 = (w[0] - 1 >= 0) ? w[0] - 1 : 0;
          int ix2 = w[0];
          int ix3 = w[0] + 1;
          double fit1;
          double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1);
          *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sg0[ix2])))/2/f1[2];
          *wnd2 = WND_FROM_MAX_SIGMA0;
        }
        FREE(w);
      }
      break;
    case 1:
      {
        // Single solution
        int ix1 = ww;
        int ix2 = (ww+1) > npts - 1 ? npts - 1 : ww+1;
        int ix3 = (ww+2) > npts - 1 ? npts - 1 : ww+2;
        double fit1;
        double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1);
        *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sigma0)))/2/f1[2];
        *wnd2 = WND1_IS_ONLY_SOLUTION;
      }
      break;
    case 2:
      {
        // Two solutions (usually lowest answer of the two is best answer)
        int ix1 = ww;
        int ix2 = (ww+1) > npts - 1 ? npts - 1 : ww+1;
        int ix3 = (ww+2) > npts - 1 ? npts - 1 : ww+2;
        int ix4 = ww2;
        int ix5 = (ww2+1) > npts - 1 ? npts - 1 : ww2+1;
        int ix6 = (ww2+2) > npts - 1 ? npts - 1 : ww2+2;
        double fit1, fit2;
        double *f1 = poly_fit(wd, sg0, ix1, ix2, ix3, 2, &fit1);
        double *f2 = poly_fit(wd, sg0, ix4, ix5, ix6, 2, &fit2);
        *wnd1 = (f1[1]+sqrt(f1[1]*f1[1]-4.0*f1[2]*(f1[0]-sigma0)))/2/f1[2];
        *wnd2 = (f2[1]+sqrt(f2[1]*f2[1]-4.0*f2[2]*(f2[0]-sigma0)))/2/f2[2];
      }
      break;
    default:
      *wnd1 = WND_FROM_MAX_SIGMA0;
      *wnd2 = WND_FROM_MAX_SIGMA0;
      break;
  }

  FREE(s);
  FREE(wd);
  FREE(sg0);

  return 0;
}
Example #5
0
int main(int narg,char **arg)
{
  if(narg<2)
    {
      fprintf(stderr,"Error, use: %s file\n",arg[0]);
      exit(1);
    }
  
  grace out("fit_xmax.xmg");
  FILE *fin=open_file(arg[1],"r");
  const char color[3][1024]={"blue","green","red"};
  int nmu;
  read_formatted_from_file_expecting((char*)&nmu,fin,"%d","nmu");

  double muI[nmu],muI2[nmu];
  bvec xmax[3];xmax[0]=xmax[1]=xmax[2]=bvec(nmu,99,2);
  for(int imu=0;imu<nmu;imu++)
    {
      char path[1024];
      read_formatted_from_file((char*)&(muI[imu]),fin,"%lg","path");
      read_formatted_from_file(path,fin,"%s","path");
      for(int det=0;det<3;det++) xmax[det][imu]=get_xmax(path,det);
      muI2[imu]=sqr(muI[imu]);
      if(muI[imu]<0) muI2[imu]*=-1;
    }
  
  for(int det=0;det<3;det++)
    {
      bvec par_fit4=poly_fit(muI2,xmax[det],2);
      bvec par_fit6=poly_fit(muI2,xmax[det],3);
      bvec par_fitR=rat21_fit(par_fit4,muI2,xmax[det]);
      
      cout<<chi2_pol(par_fit4,muI2,xmax[det])/(nmu-3)<<endl;
      cout<<chi2_pol(par_fit6,muI2,xmax[det])/(nmu-4)<<endl;
      {
	double p[4]={par_fitR[0][nboot],par_fitR[1][nboot],par_fitR[2][nboot],par_fitR[3][nboot]};
	cout<<chi2_rat21(p)/(nmu-4)<<endl;
      }
      
      int nfit=300;
      double mu2F[nfit+1],mu2F_min=-0.5,mu2F_max=muI2[nmu-1];
      
      bvec xmaxF4(nfit+1,99,2);
      bvec xmaxF6(nfit+1,99,2);
      bvec xmaxFR(nfit+1,99,2);
      for(int ifit=0;ifit<=nfit;ifit++)
	{
	  double x=mu2F[ifit]=mu2F_min+(mu2F_max-mu2F_min)/nfit*ifit;
	  xmaxF4[ifit]=pol(par_fit4,x);
	  xmaxF6[ifit]=pol(par_fit6,x);
	  for(int iboot=0;iboot<=nboot;iboot++)
	    {
	      double p[4]={par_fitR[0][iboot],par_fitR[1][iboot],par_fitR[2][iboot],par_fitR[3][iboot]};
	      xmaxFR[ifit].data[iboot]=ratfun21(x,p);
	    }
	}
      
      out.set(2,"none","square");
      out.print_graph(muI2,xmax[det]);
      out.new_set();
      out.set(1,color[det]);
      out.polygon(mu2F,xmaxF4);
      out.new_set();
      out.set(1,color[det]);
      out.polygon(mu2F,xmaxF6);
      out.new_set();
      out.set(1,color[det]);
      out.polygon(mu2F,xmaxFR);
      out.new_set();
      
      cout<<par_fit4[1]<<endl;
      cout<<par_fit6[1]<<endl;
      cout<<par_fitR[1]-par_fitR[3]*par_fitR[0]<<endl;
    }
  
  return 0;
}