Changeset 38986 for trunk/Ohana/src/opihi/cmd.astro
- Timestamp:
- Oct 27, 2015, 4:49:06 PM (11 years ago)
- Location:
- trunk/Ohana
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
src/opihi/cmd.astro/fitplx.c (modified) (9 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana
-
Property svn:mergeinfo
set to
/branches/eam_branches/ipp-20150625/Ohana merged eligible
-
Property svn:mergeinfo
set to
-
trunk/Ohana/src/opihi/cmd.astro/fitplx.c
r37807 r38986 7 7 8 8 typedef struct { 9 double *X; 10 double *Y; 11 double *t; 12 double *pX; 13 double *pY; 14 double *dX; 15 double *dY; 16 int *index; 17 int Npts; 18 } PlxFitData; 19 20 typedef struct { 9 21 double Ro, dRo; 10 22 double Do, dDo; … … 17 29 double chisq; 18 30 int Nfit; 31 int getChisq; 19 32 } PlxFit; 33 34 int VectorRobustStats (Vector *vector, double *median, double *sigma); 35 double VectorFractionInterpolate (double *values, float fraction, int Npts); 36 37 int PlxSetMeanEpoch (double *R, double *D, double *T, double *Rmean, double *Dmean, double *Tmean, int *mask, int Ntotal); 38 int PlxSetEpochPosition (PlxFitData *fitdata, double *R, double *D, double *dR, double *dD, double *T, int *mask, int Ntotal, Coords *coords, double Tmean); 39 int PlxOutlierClip (PlxFitData *fitdata, int *mask, int Noutlier, float dPsigMax, Vector *dPvec, int VERBOSE); 40 41 int PlxFitDataAlloc (PlxFitData *data, int N); 42 void PlxFitDataFree (PlxFitData *data); 43 int PlxBootstrapResample (PlxFitData *src, PlxFitData *tgt); 20 44 21 45 int FitPMandPar (PlxFit *fit, double *X, double *dX, double *Y, double *dY, double *T, double *pR, double *pD, int Npts, int VERBOSE); … … 47 71 } 48 72 73 int Noutlier = 0; 74 float dPsigMax = FLT_MAX; 75 if ((N = get_argument (argc, argv, "-outlier-tests"))) { 76 remove_argument (N, &argc, argv); 77 Noutlier = atoi(argv[N]); 78 remove_argument (N, &argc, argv); 79 dPsigMax = atof(argv[N]); 80 remove_argument (N, &argc, argv); 81 } 82 83 int Nresample = 0; 84 if ((N = get_argument (argc, argv, "-bootstrap-resample"))) { 85 remove_argument (N, &argc, argv); 86 Nresample = atoi(argv[N]); 87 remove_argument (N, &argc, argv); 88 } 89 90 Vector *dPvec = NULL; 91 if ((N = get_argument (argc, argv, "-dPsig"))) { 92 if (!Noutlier) { gprint (GP_ERR, "-dPsig requires -outlier-tests to be non-zero\n"); return FALSE; } 93 remove_argument (N, &argc, argv); 94 if (!(dPvec = SelectVector (argv[N], ANYVECTOR, TRUE))) return FALSE; 95 remove_argument (N, &argc, argv); 96 } 97 49 98 if (argc != 6) { 50 gprint (GP_ERR, "USAGE: fitplx (ra) (dR) (dec) (dD) (mjd) [-mask mask]\n"); 51 // what about the errors? 99 gprint (GP_ERR, "USAGE: fitplx (ra) (dR) (dec) (dD) (mjd) [-mask mask] [-v] [-vv]\n"); 100 gprint (GP_ERR, " -outlier-tests Nsamples dPsigMax : run Nsample bootstrap-resamples to define the path deviations and reject based on dPsigMax\n"); 101 gprint (GP_ERR, " -dPsig vec : save path deviations in vec\n"); 52 102 return (FALSE); 53 103 } … … 77 127 } 78 128 79 N = tvec->Nelements; // XXX check other lengths 80 81 // find mean values to remove 82 double Npts = 0; 83 double Tmean = 0; 84 double Rmean = 0; 85 double Dmean = 0; 86 double Tmin = +1000000; 87 double Tmax = -1000000; 88 for (i = 0; i < N; i++) { 89 if (mask && !mask[i]) continue; 90 Rmean += R[i]; 91 Dmean += D[i]; 92 Tmean += T[i]; 93 Tmin = MIN(Tmin, T[i]); 94 Tmax = MAX(Tmax, T[i]); 95 Npts += 1.0; 96 } 97 Rmean /= Npts; 98 Dmean /= Npts; 99 Tmean /= Npts; 100 101 float Trange = Tmax - Tmin; 102 // fprintf (stderr, "R,D : %f,%f, T: %f, Trange: %f, Tmin: %f, Tmax: %f\n", Rmean, Dmean, Tmean, Trange, Tmin, Tmax); 129 // Ntotal : all points supplied by user 130 // Nsubset : unmasked points 131 int Ntotal = tvec->Nelements; // XXX check other lengths 132 if (dPvec) ResetVector (dPvec, OPIHI_FLT, Ntotal); 133 134 double Rmean, Dmean, Tmean; 135 PlxSetMeanEpoch (R, D, T, &Rmean, &Dmean, &Tmean, mask, Ntotal); 103 136 104 137 /* project coordinates to a plane centered on the object with units of arcsec */ … … 109 142 coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0; 110 143 111 double *X, *Y, *t, *pX, *pY, *dX, *dY; 112 ALLOCATE (X, double, N); 113 ALLOCATE (Y, double, N); 114 ALLOCATE (dX, double, N); 115 ALLOCATE (dY, double, N); 116 ALLOCATE (t, double, N); 117 ALLOCATE (pX, double, N); 118 ALLOCATE (pY, double, N); 119 120 float pXmin = +2.0; 121 float pXmax = -2.0; 122 float pYmin = +2.0; 123 float pYmax = -2.0; 124 125 int n = 0; 126 for (i = 0; i < N; i++) { 127 if (mask && !mask[i]) continue; 128 RD_to_XY (&X[n], &Y[n], R[i], D[i], &coords); 129 dX[n] = dR[i]; 130 dY[n] = dD[i]; 131 t[n] = (T[i] - Tmean) / 365.25; 132 ParFactor (&pX[n], &pY[n], R[i], D[i], T[i]); 133 pXmin = MIN (pXmin, pX[n]); 134 pXmax = MAX (pXmax, pX[n]); 135 pYmin = MIN (pYmin, pY[n]); 136 pYmax = MAX (pYmax, pY[n]); 137 n++; 138 } 139 float dXRange = pXmax - pXmin; 140 float dYRange = pYmax - pYmin; 141 float parRange = hypot (dXRange, dYRange); 142 143 // fprintf (stderr, "par factor range: %f\n", parRange); 144 145 PlxFit fit; 146 if (!FitPMandPar (&fit, X, dX, Y, dY, t, pX, pY, n, VERBOSE)) { 144 PlxFitData fitdata; 145 PlxFitDataAlloc (&fitdata, Ntotal); 146 PlxSetEpochPosition (&fitdata, R, D, dR, dD, T, mask, Ntotal, &coords, Tmean); 147 148 PlxFit fit; memset (&fit, 0, sizeof(PlxFit)); 149 150 // determine dPsig for detections based on Noutlier attempts 151 if (Noutlier) { 152 int clipRetry = TRUE; 153 for (i = 0; clipRetry && (i < 3); i++) { 154 clipRetry = !PlxOutlierClip (&fitdata, mask, Noutlier, dPsigMax, dPvec, VERBOSE); 155 156 // using the new mask values, reset fitdata 157 PlxSetMeanEpoch (R, D, T, &Rmean, &Dmean, &Tmean, mask, Ntotal); 158 PlxSetEpochPosition (&fitdata, R, D, dR, dD, T, mask, Ntotal, &coords, Tmean); 159 if (VERBOSE) fprintf (stderr, "keep %d of %d\n", fitdata.Npts, Ntotal); 160 } 161 } 162 163 for (i = 0; (VERBOSE == 2) && (i < fitdata.Npts); i++) { 164 int n = fitdata.index[i]; 165 int maskValue = mask ? mask[n] : 0; 166 fprintf (stderr, "%f %f : %f %d : %f %f %f\n", R[n], D[n], T[n], maskValue, fitdata.t[i], fitdata.X[i], fitdata.Y[i]); 167 } 168 169 fit.getChisq = TRUE; 170 if (!FitPMandPar (&fit, 171 fitdata.X, fitdata.dX, 172 fitdata.Y, fitdata.dY, 173 fitdata.t, fitdata.pX, fitdata.pY, fitdata.Npts, VERBOSE)) { 147 174 return FALSE; 148 175 } 176 177 if (Nresample){ 178 PlxFitData sample; 179 PlxFitDataAlloc (&sample, fitdata.Npts); 180 181 PlxFit *testfit = NULL; 182 ALLOCATE (testfit, PlxFit, Nresample); 183 184 int Ngood = 0; 185 for (i = 0; i < Nresample; i++) { 186 PlxBootstrapResample (&fitdata, &sample); 187 188 if (i % 100000 == 99999) fprintf (stderr, "."); 189 190 // fit the sample 191 testfit[Ngood].getChisq = FALSE; 192 if (!FitPMandPar (&testfit[Ngood], 193 sample.X, sample.dX, 194 sample.Y, sample.dY, sample.t, 195 sample.pX, sample.pY, sample.Npts, VERBOSE)) continue; 196 Ngood ++; 197 } 198 199 Vector *pvec, *uRvec, *uDvec, *Rvec, *Dvec; 200 201 // save the Nresample histograms 202 if ((pvec = SelectVector ("plxVector", ANYVECTOR, TRUE)) == NULL) ESCAPE ("missing vector %s\n", "plxVector"); 203 if ((uRvec = SelectVector ("uRVector", ANYVECTOR, TRUE)) == NULL) ESCAPE ("missing vector %s\n", "uDVector"); 204 if ((uDvec = SelectVector ("uDVector", ANYVECTOR, TRUE)) == NULL) ESCAPE ("missing vector %s\n", "uRVector"); 205 if ((Rvec = SelectVector ("RoVector", ANYVECTOR, TRUE)) == NULL) ESCAPE ("missing vector %s\n", "RoVector"); 206 if ((Dvec = SelectVector ("DoVector", ANYVECTOR, TRUE)) == NULL) ESCAPE ("missing vector %s\n", "DoVector"); 207 208 ResetVector ( pvec, OPIHI_FLT, Ngood); 209 ResetVector (uRvec, OPIHI_FLT, Ngood); 210 ResetVector (uDvec, OPIHI_FLT, Ngood); 211 ResetVector ( Rvec, OPIHI_FLT, Ngood); 212 ResetVector ( Dvec, OPIHI_FLT, Ngood); 213 214 for (i = 0; i < Ngood; i++) { 215 pvec->elements.Flt[i] = testfit[i].p; 216 uRvec->elements.Flt[i] = testfit[i].uR; 217 uDvec->elements.Flt[i] = testfit[i].uD; 218 Rvec->elements.Flt[i] = testfit[i].Ro; 219 Dvec->elements.Flt[i] = testfit[i].Do; 220 } 221 222 // now calculate median and sigma for each vector 223 VectorRobustStats (pvec, &fit.p, &fit.dp); 224 VectorRobustStats (uRvec, &fit.uR, &fit.duR); 225 VectorRobustStats (uDvec, &fit.uD, &fit.duD); 226 VectorRobustStats (Rvec, &fit.Ro, &fit.dRo); 227 VectorRobustStats (Dvec, &fit.Do, &fit.dDo); 228 } 229 230 // fprintf (stderr, "%f +/- %f | %f %f\n", fit.p, fit.dp, fit.uR, fit.uD); 231 232 /* 233 FILE *f = fopen ("test.pf.dat", "w"); 234 for (i = 0; i < Ntotal; i++) { 235 double Xf = fit.Ro + fit.uR*fitdata.t[i] + fit.p*fitdata.pX[i]; 236 double Yf = fit.Do + fit.uD*fitdata.t[i] + fit.p*fitdata.pY[i]; 237 fprintf (f, "%f : %f %f : %f %f : %f : %f %f : %f %f\n", T[i], R[i], D[i], Xf, Yf, fitdata.t[i], fitdata.X[i], fitdata.Y[i], fitdata.pX[i], fitdata.pY[i]); 238 } 239 fclose (f); 240 */ 149 241 150 242 // fprintf (stderr, "Roff, Doff: %f, %f; dRo, dDo: %f, %f\n", fit.Ro, fit.Do, fit.dRo, fit.dDo); … … 152 244 XY_to_RD (&Rmean, &Dmean, fit.Ro, fit.Do, &coords); 153 245 if (VERBOSE) { 154 fprintf (stderr, "Ro, Do: %f, %f +/- %f, %f \n", Rmean, Dmean, fit.dRo, fit.dDo);246 fprintf (stderr, "Ro, Do: %f, %f +/- %f, %f (%f, %f)\n", Rmean, Dmean, fit.dRo, fit.dDo, fit.Ro, fit.Do); 155 247 fprintf (stderr, "uR, uD: %f, %f; duR, duD: %f, %f\n", fit.uR, fit.uD, fit.duR, fit.duD); 156 248 fprintf (stderr, "par: %f +/- %f\n", fit.p, fit.dp); … … 164 256 set_variable ("uR", fit.uR); 165 257 set_variable ("uD", fit.uD); 166 set_variable ("duR", fit.duR);167 set_variable ("duD", fit.duD);258 set_variable ("duR", fit.duR); 259 set_variable ("duD", fit.duD); 168 260 set_variable ("plx", fit.p); 169 261 set_variable ("dplx", fit.dp); 170 262 171 263 set_variable ("Tmean", Tmean); 172 set_variable ("Trange", Trange);173 set_variable ("Prange", parRange);174 264 175 265 set_variable ("chisq", fit.chisq); … … 293 383 fit[0].dp = sqrt(A[4][4]); 294 384 295 // add up the chi square for the fit 296 chisq = 0.0; 297 for (i = 0; i < Npts; i++) { 298 Xf = fit[0].Ro + fit[0].uR*T[i] + fit[0].p*pR[i]; 299 Yf = fit[0].Do + fit[0].uD*T[i] + fit[0].p*pD[i]; 300 wx = (fabs(dX[i]) < 0.0001) ? 1.0 : 1.0 / SQ(dX[i]); 301 wy = (fabs(dY[i]) < 0.0001) ? 1.0 : 1.0 / SQ(dY[i]); 302 chisq += SQ(X[i] - Xf) * wx; 303 chisq += SQ(Y[i] - Yf) * wy; 304 // if (VERBOSE) fprintf (stderr, "chisq contrib : %f %f : %f %f : %f %f : %f %f : %f\n", Xf, Yf, X[i] - Xf, Y[i] - Yf, dX[i], dY[i], (X[i] - Xf) / dX[i], (Y[i] - Yf) / dY[i], chisq); 305 } 385 // (optionally) add up the chi square for the fit 386 if (fit->getChisq) { 387 chisq = 0.0; 388 for (i = 0; i < Npts; i++) { 389 Xf = fit[0].Ro + fit[0].uR*T[i] + fit[0].p*pR[i]; 390 Yf = fit[0].Do + fit[0].uD*T[i] + fit[0].p*pD[i]; 391 wx = (fabs(dX[i]) < 0.0001) ? 1.0 : 1.0 / SQ(dX[i]); 392 wy = (fabs(dY[i]) < 0.0001) ? 1.0 : 1.0 / SQ(dY[i]); 393 chisq += SQ(X[i] - Xf) * wx; 394 chisq += SQ(Y[i] - Yf) * wy; 395 // if (VERBOSE) fprintf (stderr, "chisq contrib : %f %f : %f %f : %f %f : %f %f : %f\n", Xf, Yf, X[i] - Xf, Y[i] - Yf, dX[i], dY[i], (X[i] - Xf) / dX[i], (Y[i] - Yf) / dY[i], chisq); 396 } 397 // the reduced chisq is divided by (Ndof = 2*Npts - 5) 398 fit[0].chisq = chisq / (2.0*Npts - 5.0); 399 } 400 306 401 fit[0].Nfit = Npts; 307 308 // the reduced chisq is divided by (Ndof = 2*Npts - 5)309 fit[0].chisq = chisq / (2.0*Npts - 5.0);310 402 return (TRUE); 311 403 } … … 349 441 return TRUE; 350 442 } 443 444 // allocate arrays but not the container 445 int PlxFitDataAlloc (PlxFitData *data, int N) { 446 447 data->Npts = N; 448 ALLOCATE (data->X, double, N); 449 ALLOCATE (data->Y, double, N); 450 ALLOCATE (data->dX, double, N); 451 ALLOCATE (data->dY, double, N); 452 ALLOCATE (data->t, double, N); 453 ALLOCATE (data->pX, double, N); 454 ALLOCATE (data->pY, double, N); 455 ALLOCATE (data->index, int, N); 456 return TRUE; 457 } 458 459 void PlxFitDataFree (PlxFitData *data) { 460 FREE (data->X); 461 FREE (data->Y); 462 FREE (data->dX); 463 FREE (data->dY); 464 FREE (data->t); 465 FREE (data->pX); 466 FREE (data->pY); 467 FREE (data->index); 468 } 469 470 int PlxBootstrapResample (PlxFitData *src, PlxFitData *tgt) { 471 int i; 472 tgt->Npts = src->Npts; 473 for (i = 0; i < src->Npts; i++) { 474 int N = tgt->Npts * drand48(); 475 // int N = i; 476 tgt->X [i] = src->X [N]; 477 tgt->Y [i] = src->Y [N]; 478 tgt->dX[i] = src->dX[N]; 479 tgt->dY[i] = src->dY[N]; 480 tgt->t [i] = src->t [N]; 481 tgt->pX[i] = src->pX[N]; 482 tgt->pY[i] = src->pY[N]; 483 } 484 return TRUE; 485 } 486 487 int PlxSetMeanEpoch (double *R, double *D, double *T, double *Rmean, double *Dmean, double *Tmean, int *mask, int Ntotal) { 488 489 int i; 490 491 // find mean values to remove 492 double Nmean = 0; 493 *Tmean = 0; 494 *Rmean = 0; 495 *Dmean = 0; 496 double Tmin = +1000000; 497 double Tmax = -1000000; 498 for (i = 0; i < Ntotal; i++) { 499 if (mask && !mask[i]) continue; 500 *Rmean += R[i]; 501 *Dmean += D[i]; 502 *Tmean += T[i]; 503 Tmin = MIN(Tmin, T[i]); 504 Tmax = MAX(Tmax, T[i]); 505 Nmean += 1.0; 506 } 507 *Rmean /= Nmean; 508 *Dmean /= Nmean; 509 *Tmean /= Nmean; 510 511 double Trange = Tmax - Tmin; 512 513 // fprintf (stderr, "R,D : %f,%f, T: %f, Trange: %f, Tmin: %f, Tmax: %f\n", *Rmean, *Dmean, *Tmean, Trange, Tmin, Tmax); 514 515 set_variable ("Trange", Trange); 516 return TRUE; 517 } 518 519 // generate the fit values (projected X,Y; parallax factors; 520 int PlxSetEpochPosition (PlxFitData *fitdata, double *R, double *D, double *dR, double *dD, double *T, int *mask, int Ntotal, Coords *coords, double Tmean) { 521 522 int i; 523 524 float pXmin = +2.0; 525 float pXmax = -2.0; 526 float pYmin = +2.0; 527 float pYmax = -2.0; 528 529 int Nsubset = 0; 530 for (i = 0; i < Ntotal; i++) { 531 if (mask && !mask[i]) continue; 532 RD_to_XY (&fitdata->X[Nsubset], &fitdata->Y[Nsubset], R[i], D[i], coords); 533 fitdata->dX[Nsubset] = dR[i]; 534 fitdata->dY[Nsubset] = dD[i]; 535 fitdata->t[Nsubset] = (T[i] - Tmean) / 365.25; 536 ParFactor (&fitdata->pX[Nsubset], &fitdata->pY[Nsubset], R[i], D[i], T[i]); 537 pXmin = MIN (pXmin, fitdata->pX[Nsubset]); 538 pXmax = MAX (pXmax, fitdata->pX[Nsubset]); 539 pYmin = MIN (pYmin, fitdata->pY[Nsubset]); 540 pYmax = MAX (pYmax, fitdata->pY[Nsubset]); 541 fitdata->index[Nsubset] = i; 542 Nsubset++; 543 } 544 fitdata->Npts = Nsubset; 545 float dXRange = pXmax - pXmin; 546 float dYRange = pYmax - pYmin; 547 float parRange = hypot (dXRange, dYRange); 548 549 set_variable ("Prange", parRange); 550 // fprintf (stderr, "par factor range: %f\n", parRange); 551 552 return TRUE; 553 } 554 555 /* Outlier clipping based on bootstrap-resampling tests of the plx path 556 * generate Noutlier resampled datasets 557 * fit the Noutlier plx paths 558 * determine and save the distribution of dXsig and dYsig for each point 559 * sort the resulting distributions and find dPsig (median point) for each measurement 560 * find the 90% point of dPsig : if > dPsigMax, only clip the 10% most deviant points 561 * set the dPvec values if desired 562 * -- mask is modified, dPvec values are set 563 * -- fitdata is unchanged 564 */ 565 566 # define MAX_REJECT 0.1 567 568 int PlxOutlierClip (PlxFitData *fitdata, int *mask, int Noutlier, float dPsigMax, Vector *dPvec, int VERBOSE) { 569 570 int i, n; 571 572 PlxFit testfit; 573 testfit.getChisq = FALSE; 574 575 PlxFitData sample; 576 PlxFitDataAlloc (&sample, fitdata->Npts); 577 578 double **dXsig, **dYsig; 579 ALLOCATE (dXsig, double *, fitdata->Npts); 580 ALLOCATE (dYsig, double *, fitdata->Npts); 581 for (i = 0; i < fitdata->Npts; i++) { 582 ALLOCATE (dXsig[i], double, Noutlier); 583 ALLOCATE (dYsig[i], double, Noutlier); 584 } 585 586 int Nsamples = 0; 587 for (n = 0; n < Noutlier; n++) { 588 // bootstrap resample (fitdata -> sample) 589 PlxBootstrapResample (fitdata, &sample); 590 591 if (n % 100000 == 99999) fprintf (stderr, "."); 592 593 // fit the sample 594 if (!FitPMandPar (&testfit, 595 sample.X, sample.dX, 596 sample.Y, sample.dY, sample.t, 597 sample.pX, sample.pY, sample.Npts, VERBOSE)) continue; 598 599 // fprintf (stderr, "%f +/- %f | %f %f\n", testfit.p, testfit.dp, testfit.uR, testfit.uD); 600 601 // find the distances to the path 602 for (i = 0; i < fitdata->Npts; i++) { 603 double Xf = testfit.Ro + testfit.uR*fitdata->t[i] + testfit.p*fitdata->pX[i]; 604 double Yf = testfit.Do + testfit.uD*fitdata->t[i] + testfit.p*fitdata->pY[i]; 605 dXsig[i][Nsamples] = fabs(fitdata->X[i] - Xf) / fitdata->dX[i]; 606 dYsig[i][Nsamples] = fabs(fitdata->Y[i] - Yf) / fitdata->dY[i]; 607 // fprintf (stderr, "%f : %f %f : %f %f : %f %f : %f %f %f\n", T[i], Xf, Yf, fitdata->X[i], fitdata->Y[i], fitdata->dX[i], fitdata->dY[i], fitdata->t[i], fitdata->pX[i], fitdata->pY[i]); 608 } 609 Nsamples ++; 610 } 611 612 double *dPsig; 613 ALLOCATE (dPsig, double, fitdata->Npts); 614 615 for (i = 0; i < fitdata->Npts; i++) { 616 dsort (dXsig[i], Nsamples); 617 dsort (dYsig[i], Nsamples); 618 619 // choose the median values 620 double dXsigMedian, dYsigMedian; 621 if (Nsamples % 2) { 622 int Ncenter = Nsamples / 2; 623 dXsigMedian = dXsig[i][Ncenter]; 624 dYsigMedian = dYsig[i][Ncenter]; 625 } else { 626 int Ncenter = Nsamples / 2 - 1; 627 dXsigMedian = 0.5*(dXsig[i][Ncenter] + dXsig[i][Ncenter + 1]); 628 dYsigMedian = 0.5*(dYsig[i][Ncenter] + dYsig[i][Ncenter + 1]); 629 } 630 // XXX replace with hypotenuse? 631 dPsig[i] = 0.5*(dXsigMedian + dYsigMedian); 632 // fprintf (stderr, "%d %10.6f %10.6f %10.6f %f %f : %f\n", i, R[i], D[i], T[i], dXsig[i][Ncenter], dYsig[i][Ncenter], dPsig[i]); 633 } 634 635 // make a copy of dPsig[] and check if > 10% are > dPsigMax 636 double *dPsigSort; 637 ALLOCATE (dPsigSort, double, fitdata->Npts); 638 for (i = 0; i < fitdata->Npts; i++) { 639 dPsigSort[i] = dPsig[i]; 640 } 641 dsort (dPsigSort, fitdata->Npts); 642 int Nmax = (1.0 - MAX_REJECT)*fitdata->Npts; 643 644 int completeClip = TRUE; 645 if (dPsigSort[Nmax] > dPsigMax) { 646 if (VERBOSE) fprintf (stderr, "too many outliers: %f at 90\n", dPsigSort[Nmax]); 647 dPsigMax = dPsigSort[Nmax]; 648 completeClip = FALSE; 649 } 650 651 for (i = 0; i < fitdata->Npts; i++) { 652 if (dPsig[i] < dPsigMax) continue; 653 int n = fitdata->index[i]; 654 // fprintf (stderr, "clip %d: %f : %f\n", i, fitdata->t[i], dPsig[i]); 655 mask[n] = 0; // mask these points 656 } 657 658 // only set dPvec if we have completed the clipping? 659 if (dPvec) { 660 for (i = 0; i < dPvec->Nelements; i++) { 661 dPvec->elements.Flt[i] = NAN; 662 } 663 for (i = 0; i < fitdata->Npts; i++) { 664 int n = fitdata->index[i]; 665 dPvec->elements.Flt[n] = dPsig[i]; 666 } 667 } 668 669 free (dPsig); 670 free (dPsigSort); 671 672 for (i = 0; i < fitdata->Npts; i++) { 673 free (dXsig[i]); 674 free (dYsig[i]); 675 } 676 free (dXsig); 677 free (dYsig); 678 679 return completeClip; 680 } 681 682 int VectorRobustStats (Vector *vector, double *median, double *sigma) { 683 684 // warn if vector->Nelements > 1000? 10000?) 685 // warn if vector is not float 686 687 // we need to copy the vector to avoid changing the sort order 688 double *values = NULL; 689 ALLOCATE (values, double, vector->Nelements); 690 691 int i; 692 int Npts = 0; 693 for (i = 0; i < vector->Nelements; i++) { 694 if (!isfinite(vector->elements.Flt[i])) continue; 695 values[Npts] = vector->elements.Flt[i]; 696 Npts++; 697 } 698 699 dsort (values, Npts); 700 701 if (Npts % 2) { 702 int Ncenter = Npts / 2; 703 *median = values[Ncenter]; 704 } else { 705 int Ncenter = Npts / 2 - 1; 706 *median = 0.5*(values[Ncenter] + values[Ncenter + 1]); 707 } 708 709 double Slo = VectorFractionInterpolate (values, 0.158655, Npts); 710 double Shi = VectorFractionInterpolate (values, 0.841345, Npts); 711 712 *sigma = (Shi - Slo) / 2.0; 713 714 return TRUE; 715 } 716 717 double VectorFractionInterpolate (double *values, float fraction, int Npts) { 718 719 float F = fraction * Npts; 720 int N = fraction * Npts; 721 722 if (N < 0 ) return NAN; 723 if (N >= Npts - 2) return NAN; 724 725 // interpolate between N,N+1 726 727 double S = (F - N) * (values[N+1] - values[N]) + values[N]; 728 return S; 729 }
Note:
See TracChangeset
for help on using the changeset viewer.
