Changeset 38574
- Timestamp:
- Jul 6, 2015, 8:11:18 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ipp-20150625/Ohana/src/opihi/cmd.astro/fitplx.c
r38568 r38574 14 14 double *dX; 15 15 double *dY; 16 int *index; 16 17 int Npts; 17 18 } PlxFitData; … … 31 32 } PlxFit; 32 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 33 41 int PlxFitDataAlloc (PlxFitData *data, int N); 34 42 void PlxFitDataFree (PlxFitData *data); … … 70 78 remove_argument (N, &argc, argv); 71 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]); 72 87 remove_argument (N, &argc, argv); 73 88 } … … 112 127 } 113 128 114 int Ntotal = tvec->Nelements; // XXX check other lengths115 116 // find mean values to remove117 double Nmean = 0;118 double Tmean = 0;119 double Rmean = 0;120 double Dmean = 0;121 double Tmin = +1000000;122 double Tmax = -1000000;123 for (i = 0; i < Ntotal; i++) {124 if (mask && !mask[i]) continue;125 Rmean += R[i];126 Dmean += D[i];127 Tmean += T[i];128 Tmin = MIN(Tmin, T[i]);129 Tmax = MAX(Tmax, T[i]);130 Nmean += 1.0;131 }132 Rmean /= Nmean;133 Dmean /= Nmean;134 Tmean /= Nmean;135 136 129 // Ntotal : all points supplied by user 137 130 // Nsubset : unmasked points 138 // Nmean : unmasked points (a double only used above) 139 140 float Trange = Tmax - Tmin; 141 // fprintf (stderr, "R,D : %f,%f, T: %f, Trange: %f, Tmin: %f, Tmax: %f\n", Rmean, Dmean, Tmean, Trange, Tmin, Tmax); 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); 142 136 143 137 /* project coordinates to a plane centered on the object with units of arcsec */ … … 148 142 coords.cdelt1 = coords.cdelt2 = 1.0 / 3600.0; 149 143 150 float pXmin = +2.0;151 float pXmax = -2.0;152 float pYmin = +2.0;153 float pYmax = -2.0;154 155 PlxFit fit; memset (&fit, 0, sizeof(PlxFit));156 144 PlxFitData fitdata; 157 145 PlxFitDataAlloc (&fitdata, Ntotal); 158 159 // generate the fit values (projected X,Y; parallax factors; 160 161 // save an index so we can supplied dPsig for the unmasked points 162 int *index; 163 ALLOCATE (index, int, Ntotal); 164 165 int Nsubset = 0; 166 for (i = 0; i < Ntotal; i++) { 167 if (mask && !mask[i]) continue; 168 RD_to_XY (&fitdata.X[Nsubset], &fitdata.Y[Nsubset], R[i], D[i], &coords); 169 fitdata.dX[Nsubset] = dR[i]; 170 fitdata.dY[Nsubset] = dD[i]; 171 fitdata.t[Nsubset] = (T[i] - Tmean) / 365.25; 172 ParFactor (&fitdata.pX[Nsubset], &fitdata.pY[Nsubset], R[i], D[i], T[i]); 173 pXmin = MIN (pXmin, fitdata.pX[Nsubset]); 174 pXmax = MAX (pXmax, fitdata.pX[Nsubset]); 175 pYmin = MIN (pYmin, fitdata.pY[Nsubset]); 176 pYmax = MAX (pYmax, fitdata.pY[Nsubset]); 177 index[Nsubset] = i; 178 Nsubset++; 179 } 180 fitdata.Npts = Nsubset; 181 float dXRange = pXmax - pXmin; 182 float dYRange = pYmax - pYmin; 183 float parRange = hypot (dXRange, dYRange); 184 185 // fprintf (stderr, "par factor range: %f\n", parRange); 146 PlxSetEpochPosition (&fitdata, R, D, dR, dD, T, mask, Ntotal, &coords, Tmean); 147 148 PlxFit fit; memset (&fit, 0, sizeof(PlxFit)); 186 149 187 150 // determine dPsig for detections based on Noutlier attempts 188 151 if (Noutlier) { 189 PlxFit testfit; 190 PlxFitData sample; 191 PlxFitDataAlloc (&sample, fitdata.Npts); 192 193 double **dXsig, **dYsig; 194 ALLOCATE (dXsig, double *, fitdata.Npts); 195 ALLOCATE (dYsig, double *, fitdata.Npts); 196 for (i = 0; i < fitdata.Npts; i++) { 197 ALLOCATE (dXsig[i], double, Noutlier); 198 ALLOCATE (dYsig[i], double, Noutlier); 199 } 200 201 testfit.getChisq = FALSE; 202 203 int n; 204 int Nsamples = 0; 205 for (n = 0; n < Noutlier; n++) { 206 // bootstrap resample (fitdata -> sample) 207 PlxBootstrapResample (&fitdata, &sample); 208 209 if (n % 1000 == 999) fprintf (stderr, "."); 210 211 // fit the sample 212 if (!FitPMandPar (&testfit, 213 sample.X, sample.dX, 214 sample.Y, sample.dY, sample.t, 215 sample.pX, sample.pY, sample.Npts, VERBOSE)) continue; 216 217 // fprintf (stderr, "%f +/- %f | %f %f\n", testfit.p, testfit.dp, testfit.uR, testfit.uD); 218 219 // find the distances to the path 220 for (i = 0; i < fitdata.Npts; i++) { 221 double Xf = testfit.Ro + testfit.uR*fitdata.t[i] + testfit.p*fitdata.pX[i]; 222 double Yf = testfit.Do + testfit.uD*fitdata.t[i] + testfit.p*fitdata.pY[i]; 223 dXsig[i][Nsamples] = fabs(fitdata.X[i] - Xf) / fitdata.dX[i]; 224 dYsig[i][Nsamples] = fabs(fitdata.Y[i] - Yf) / fitdata.dY[i]; 225 // 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]); 226 } 227 Nsamples ++; 228 } 229 230 double *dPsig; 231 ALLOCATE (dPsig, double, fitdata.Npts); 232 233 for (i = 0; i < fitdata.Npts; i++) { 234 dsort (dXsig[i], Nsamples); 235 dsort (dYsig[i], Nsamples); 236 237 // choose the median values 238 double dXsigMedian, dYsigMedian; 239 if (Nsamples % 2) { 240 int Ncenter = Nsamples / 2; 241 dXsigMedian = dXsig[i][Ncenter]; 242 dYsigMedian = dYsig[i][Ncenter]; 243 } else { 244 int Ncenter = Nsamples / 2 - 1; 245 dXsigMedian = 0.5*(dXsig[i][Ncenter] + dXsig[i][Ncenter + 1]); 246 dYsigMedian = 0.5*(dYsig[i][Ncenter] + dYsig[i][Ncenter + 1]); 247 } 248 // XXX replace with hypotenuse? 249 dPsig[i] = 0.5*(dXsigMedian + dYsigMedian); 250 // 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]); 251 } 252 253 int Nout = 0; 254 for (i = 0; i < fitdata.Npts; i++) { 255 if (dPsig[i] > dPsigMax) { 256 fprintf (stderr, "clip %d: %f : %f\n", i, fitdata.t[i], dPsig[i]); 257 continue; 258 } 259 sample.X [Nout] = fitdata.X [i]; 260 sample.Y [Nout] = fitdata.Y [i]; 261 sample.dX[Nout] = fitdata.dX[i]; 262 sample.dY[Nout] = fitdata.dY[i]; 263 sample.t [Nout] = fitdata.t [i]; 264 sample.pX[Nout] = fitdata.pX[i]; 265 sample.pY[Nout] = fitdata.pY[i]; 266 Nout ++; 267 } 268 sample.Npts = Nout; 269 fprintf (stderr, "keep %d of %d\n", sample.Npts, fitdata.Npts); 270 271 if (dPvec) { 272 ResetVector (dPvec, OPIHI_FLT, Ntotal); 273 for (i = 0; i < Ntotal; i++) { 274 dPvec->elements.Flt[i] = NAN; 275 } 276 for (i = 0; i < fitdata.Npts; i++) { 277 int n = index[i]; 278 dPvec->elements.Flt[n] = dPsig[i]; 279 } 280 dPvec->Nelements = Ntotal; 281 } 282 free (dPsig); 283 284 fitdata = sample; 285 } 286 287 for (i = 0; VERBOSE && (i < fitdata.Npts); i++) { 288 int n = index[i]; 289 fprintf (stderr, "%f %f : %f %d : %f %f %f\n", R[n], D[n], T[n], mask[n], fitdata.t[i], fitdata.X[i], fitdata.Y[i]); 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]); 290 167 } 291 168 … … 298 175 } 299 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 300 230 // fprintf (stderr, "%f +/- %f | %f %f\n", fit.p, fit.dp, fit.uR, fit.uD); 301 231 … … 326 256 set_variable ("uR", fit.uR); 327 257 set_variable ("uD", fit.uD); 328 set_variable ("duR", fit.duR);329 set_variable ("duD", fit.duD);258 set_variable ("duR", fit.duR); 259 set_variable ("duD", fit.duD); 330 260 set_variable ("plx", fit.p); 331 261 set_variable ("dplx", fit.dp); 332 262 333 263 set_variable ("Tmean", Tmean); 334 set_variable ("Trange", Trange);335 set_variable ("Prange", parRange);336 264 337 265 set_variable ("chisq", fit.chisq); … … 525 453 ALLOCATE (data->pX, double, N); 526 454 ALLOCATE (data->pY, double, N); 455 ALLOCATE (data->index, int, N); 527 456 return TRUE; 528 457 } … … 536 465 FREE (data->pX); 537 466 FREE (data->pY); 467 FREE (data->index); 538 468 } 539 469 … … 555 485 } 556 486 557 # if (0) 558 int PlxSetMeanEpoch () { 487 int PlxSetMeanEpoch (double *R, double *D, double *T, double *Rmean, double *Dmean, double *Tmean, int *mask, int Ntotal) { 488 489 int i; 559 490 560 491 // find mean values to remove 561 492 double Nmean = 0; 562 doubleTmean = 0;563 doubleRmean = 0;564 doubleDmean = 0;493 *Tmean = 0; 494 *Rmean = 0; 495 *Dmean = 0; 565 496 double Tmin = +1000000; 566 497 double Tmax = -1000000; 567 498 for (i = 0; i < Ntotal; i++) { 568 499 if (mask && !mask[i]) continue; 569 Rmean += R[i];570 Dmean += D[i];571 Tmean += T[i];500 *Rmean += R[i]; 501 *Dmean += D[i]; 502 *Tmean += T[i]; 572 503 Tmin = MIN(Tmin, T[i]); 573 504 Tmax = MAX(Tmax, T[i]); 574 505 Nmean += 1.0; 575 506 } 576 Rmean /= Nmean; 577 Dmean /= Nmean; 578 Tmean /= Nmean; 579 580 float Trange = Tmax - Tmin; 581 582 } 583 # endif 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.
