- Timestamp:
- May 30, 2019, 6:05:51 AM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20190329/src/opihi/cmd.data/medimage_commands.c
r40755 r40758 1 1 # include "data.h" 2 3 float weight_cauchy_square_flt (float x2);4 float irls_mean (float *val, float *wgt, int N);5 6 # define IRLS_TOLERANCE 1e-47 2 8 3 int medimage_list (int argc, char **argv) { … … 85 80 return TRUE; 86 81 } 87 88 enum {CALC_MEDIAN, CALC_MEAN, CALC_IRLS, CALC_WTMEAN};89 int medimage_calc (int argc, char **argv) {90 91 int ix, iy, n, N;92 Buffer *output;93 94 int mode = CALC_MEDIAN;95 if ((N = get_argument (argc, argv, "-mean"))) {96 mode = CALC_MEAN;97 remove_argument (N, &argc, argv);98 }99 if ((N = get_argument (argc, argv, "-irls"))) {100 if (mode != CALC_MEDIAN) { gprint (GP_ERR, "supply only one of -mean, -irls, -wtmean\n"); return FALSE; }101 mode = CALC_IRLS;102 remove_argument (N, &argc, argv);103 }104 if ((N = get_argument (argc, argv, "-wtmean"))) {105 if (mode != CALC_MEDIAN) { gprint (GP_ERR, "supply only one of -mean, -irls, -wtmean\n"); return FALSE; }106 mode = CALC_WTMEAN;107 remove_argument (N, &argc, argv);108 }109 110 Buffer *variance = NULL;111 if ((N = get_argument (argc, argv, "-variance"))) {112 remove_argument (N, &argc, argv);113 if ((variance = SelectBuffer (argv[N], ANYBUFFER, TRUE)) == NULL) return (FALSE);114 remove_argument (N, &argc, argv);115 }116 117 if (argc != 3) {118 gprint (GP_ERR, "USAGE: medimage calc (name) (output) [-mean,-irls,-wtmean]\n");119 gprint (GP_ERR, " calculate the median image for the median image set\n");120 return FALSE;121 }122 123 MedImageType *median = FindMedImage (argv[1]);124 if (!median) {125 gprint (GP_ERR, "median image %s not found\n", argv[1]);126 return FALSE;127 }128 129 if ((output = SelectBuffer (argv[2], ANYBUFFER, TRUE)) == NULL) return (FALSE);130 131 int Ninput = median->Ninput;132 int Nx = median->Nx;133 int Ny = median->Ny;134 135 ALLOCATE_PTR (val, float, Ninput);136 ALLOCATE_PTR (wgt, float, Ninput);137 138 gfits_free_matrix (&output->matrix);139 gfits_free_header (&output->header);140 if (!CreateBuffer (output, Nx, Ny, -32, 0.0, 1.0)) return FALSE;141 142 float *outvalue = (float *) output->matrix.buffer;143 144 for (iy = 0; iy < Ny; iy++) {145 for (ix = 0; ix < Nx; ix++) {146 147 int N = 0;148 int Npix = ix + Nx*iy;149 for (n = 0; n < Ninput; n++) {150 float v = median->flx[n][Npix];151 if (!isfinite(v)) continue;152 val[N] = v;153 wgt[N] = 1.0;154 if (median->var[n]) {155 float s = median->var[n][Npix];156 if (!isfinite(s)) continue;157 if (fabs(s) < 2*FLT_MIN) s = 2*FLT_MIN;158 wgt[N] = 1.0 / s;159 }160 N++;161 }162 if (N == 0) continue;163 164 switch (mode) {165 case CALC_MEDIAN:166 fsort (val, N);167 outvalue[Npix] = val[(int)(0.5*N)];168 break;169 case CALC_MEAN: {170 float sum = 0.0;171 for (n = 0; n < N; n++) {172 sum += val[n];173 }174 outvalue[Npix] = sum / (float) N;175 break;176 }177 case CALC_WTMEAN: {178 float S1 = 0.0, S2 = 0.0;179 for (n = 0; n < N; n++) {180 S1 += wgt[n] * val[n];181 S2 += wgt[n];182 }183 outvalue[Npix] = S1 / S2;184 break;185 }186 case CALC_IRLS:187 outvalue[Npix] = irls_mean (val, wgt, N);188 }189 }190 }191 return TRUE;192 }193 194 float irls_mean (float *val, float *wgt, int N) {195 196 // calculate weighted mean197 float S1 = 0.0, S2 = 0.0;198 for (int n = 0; n < N; n++) {199 S1 += wgt[n] * val[n];200 S2 += wgt[n];201 }202 float Value = S1 / S2;203 204 int converged = FALSE;205 for (int i = 0; (i < 10) && !converged; i++) {206 float ValueLast = Value;207 208 float S1 = 0.0, S2 = 0.0;209 210 // calculate weight modification based on distances (squared).211 // use modifier to calculate new weighted mean212 for (int n = 0; n < N; n++) {213 float dV = (val[n] - Value);214 float d2 = SQ(dV) * wgt[n];215 216 float Mod = weight_cauchy_square_flt (d2);217 S1 += Mod * wgt[n] * val[n];218 S2 += Mod * wgt[n];219 }220 Value = S1 / S2;221 222 float delta = fabs(Value - ValueLast);223 if (delta < Value * IRLS_TOLERANCE) converged = TRUE;224 }225 return Value;226 }227 228 // exp(-(x^2/s^2)/2) = (1/2)229 // -(x^2/s^2)/2 = ln(1/2)230 // (x^2/s^2)/2 = ln(2)231 // (x^2/s^2) = 2ln(2)232 // (x /s) = sqrt(2ln(2)) : half-width at half-max233 // FWHM = 2sqrt(2ln(2))234 235 // R2 = (X / 2.385)^2 = (X^2 / 2.385^2)236 237 # define CAUCY_FACTOR 1.0238 239 float weight_cauchy_square_flt (float x2) {240 float r2 = x2 / CAUCY_FACTOR;241 return (1.0 / (1.0 + r2));242 }243 244 82 245 83 /*
Note:
See TracChangeset
for help on using the changeset viewer.
