IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 30, 2019, 6:05:51 AM (7 years ago)
Author:
eugene
Message:

update medimage to return the variance, finish irls in medimage, add mgaussdev

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/eam_branches/ohana.20190329/src/opihi/cmd.data/medimage_commands.c

    r40755 r40758  
    11# 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-4
    72
    83int medimage_list (int argc, char **argv) {
     
    8580  return TRUE;
    8681}
    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 mean
    197   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 mean
    212     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-max
    233 //       FWHM        = 2sqrt(2ln(2))
    234 
    235 // R2 = (X / 2.385)^2 = (X^2 / 2.385^2)
    236 
    237 # define CAUCY_FACTOR 1.0
    238 
    239 float weight_cauchy_square_flt (float x2) {
    240   float r2 = x2 / CAUCY_FACTOR;
    241   return (1.0 / (1.0 + r2));
    242 }
    243 
    24482
    24583/*
Note: See TracChangeset for help on using the changeset viewer.