Changeset 41340 for trunk/Ohana/src/opihi/mana/deimos_fitslit.c
- Timestamp:
- Apr 16, 2020, 1:54:47 PM (6 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/mana/deimos_fitslit.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/mana/deimos_fitslit.c
r41159 r41340 1 1 # include "data.h" 2 # define IRLS_TOLERANCE 1e-43 4 float weight_cauchy_square_flt (float x2);5 static void fitflux (float *Fwind, float *Fprof, float *weight, int Nx, double *flux, double *sky);6 2 7 3 int deimos_fitslit (int argc, char **argv) { 8 4 9 // fitslit (window) (vari) (slit) (flux) (sky) 5 // fitslit (window) (slit) (flux) (sky) 6 7 // int N; 10 8 11 9 Vector *flux = NULL; … … 13 11 14 12 Buffer *wind = NULL; 15 Buffer *vari = NULL;16 13 Buffer *slit = NULL; 17 14 18 int N; 19 int Niter = 10; 20 if ((N = get_argument (argc, argv, "-irls-iter"))) { 21 remove_argument (N, &argc, argv); 22 Niter = atoi (argv[N]); 23 remove_argument (N, &argc, argv); 24 } 25 26 Buffer *model = NULL; 27 if ((N = get_argument (argc, argv, "-model"))) { 28 remove_argument (N, &argc, argv); 29 if ((model = SelectBuffer (argv[N], ANYBUFFER, TRUE)) == NULL) return (FALSE); 30 remove_argument (N, &argc, argv); 31 } 32 33 if (argc != 6) { 34 gprint (GP_ERR, "USAGE: deimos fitslit (window) (variance) (slit) (flux) (sky)\n"); 35 gprint (GP_ERR, " inputs: window (observed 2D flux), variance (on 2D flux), slit (model 2D flux)\n"); 15 if (argc != 5) { 16 gprint (GP_ERR, "USAGE: deimos fitslit (window) (slit) (flux) (sky)\n"); 17 gprint (GP_ERR, " inputs: window (observed 2D flux), slit (model 2D flux)\n"); 36 18 gprint (GP_ERR, " outputs: flux (best-fit 1D flux), sky (best-fit 1D background)\n"); 37 19 return FALSE; … … 40 22 // XXX I probably should rename FindSpline as SelectSpline and give it the same behavior 41 23 if ((wind = SelectBuffer (argv[1], OLDBUFFER, TRUE)) == NULL) return (FALSE); 42 if ((vari = SelectBuffer (argv[2], OLDBUFFER, TRUE)) == NULL) return (FALSE); 43 if ((slit = SelectBuffer (argv[3], OLDBUFFER, TRUE)) == NULL) return (FALSE); 44 if ((flux = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE); 45 if ((sky = SelectVector (argv[5], ANYVECTOR, TRUE)) == NULL) return (FALSE); 24 if ((slit = SelectBuffer (argv[2], OLDBUFFER, TRUE)) == NULL) return (FALSE); 25 if ((flux = SelectVector (argv[3], ANYVECTOR, TRUE)) == NULL) return (FALSE); 26 if ((sky = SelectVector (argv[4], ANYVECTOR, TRUE)) == NULL) return (FALSE); 27 28 // XXX confirm slit and wind have same dimensions 46 29 47 30 // define the output window … … 49 32 int Ny = wind[0].matrix.Naxis[1]; 50 33 51 // confirm wind, vari, slit have same dimensions52 34 if (Nx != slit[0].matrix.Naxis[0]) { gprint (GP_ERR, "size mismatch in fitslit for window and slit\n"); return FALSE; } 53 35 if (Ny != slit[0].matrix.Naxis[1]) { gprint (GP_ERR, "size mismatch in fitslit for window and slit\n"); return FALSE; } 54 if (Nx != vari[0].matrix.Naxis[0]) { gprint (GP_ERR, "size mismatch in fitslit for window and variance\n"); return FALSE; }55 if (Ny != vari[0].matrix.Naxis[1]) { gprint (GP_ERR, "size mismatch in fitslit for window and variance\n"); return FALSE; }56 36 57 37 ResetVector (flux, OPIHI_FLT, Ny); 58 38 ResetVector (sky, OPIHI_FLT, Ny); 59 39 60 if (model) {61 if (!CreateBuffer (model, Nx, Ny, -32, 1.0, 0.0)) { gprint (GP_ERR, "error generating output model buffer\n"); return FALSE; }62 }63 64 40 float *Fwind = (float *) wind[0].matrix.buffer; 65 float *Fvari = (float *) vari[0].matrix.buffer;66 41 float *Fprof = (float *) slit[0].matrix.buffer; 67 float *FmodOut = model ? (float *) model[0].matrix.buffer : NULL;68 69 ALLOCATE_PTR (weight, float, Nx);70 ALLOCATE_PTR (rawwgt, float, Nx);71 42 72 43 // loop over the rows 73 44 for (int iy = 0; iy < Ny; iy++) { 74 45 75 double F = 0.0, S = 0.0;46 // calculate elements of the chi-square for this row: 76 47 77 // set weight based on the variance 48 double R = 0.0, P = 0.0, P2 = 0.0, f = 0.0, fp = 0.0; 49 double wt = 1.0; 50 78 51 for (int ix = 0; ix < Nx; ix++) { 79 float vari = Fvari[ix + iy*Nx]; 80 weight[ix] = !isfinite(vari) || (fabs(vari) < 1e-6) ? 1.0 : 1.0 / vari; 81 rawwgt[ix] = weight[ix]; 52 53 float fxy = Fwind[ix + iy*Nx]; 54 float pxy = Fprof[ix + iy*Nx]; 55 56 R += wt; 57 P += pxy*wt; 58 P2 += pxy*pxy*wt; 59 f += fxy*wt; 60 fp += fxy*pxy*wt; 82 61 } 83 62 84 // calculate elements of the chi-square for this row: 85 fitflux (&Fwind[iy*Nx], &Fprof[iy*Nx], weight, Nx, &F, &S); 86 87 // do an IRLS loop here to reject outliers 88 int converged = FALSE; 89 for (int iter = 0; (iter < Niter) && !converged; iter++) { 90 91 double Flast = F; 92 double Slast = S; 93 94 // calculate weight modification based on distances (squared). 95 // use modifier to calculate new weighted mean 96 for (int ix = 0; ix < Nx; ix++) { 97 98 // F & S are model parameters; compare the model and observed values for each pixel 99 float Fmodel = S + F*Fprof[ix + iy*Nx]; 100 float dV = (Fwind[ix + iy*Nx] - Fmodel); 101 float d2 = SQ(dV) * rawwgt[ix]; 102 103 float Mod = weight_cauchy_square_flt (d2); 104 weight[ix] = Mod * rawwgt[ix]; 105 } 106 fitflux (&Fwind[iy*Nx], &Fprof[iy*Nx], weight, Nx, &F, &S); 107 108 float dF = fabs(F - Flast); 109 float dS = fabs(S - Slast); 110 111 if ((dF < F * IRLS_TOLERANCE) && (dS < S * IRLS_TOLERANCE)) converged = TRUE; 112 } 113 114 if (FmodOut) { 115 for (int ix = 0; ix < Nx; ix++) { 116 // F & S are model parameters; compare the model and observed values for each pixel 117 float Fmodel = S + F*Fprof[ix + iy*Nx]; 118 float dV = (Fwind[ix + iy*Nx] - Fmodel); 119 float d2 = SQ(dV) * rawwgt[ix]; 120 float Mod = weight_cauchy_square_flt (d2); 121 if (Mod < 0.1) { 122 FmodOut[ix + iy*Nx] = NAN; 123 } else { 124 FmodOut[ix + iy*Nx] = Fmodel; 125 } 126 } 127 } 63 double det = R*P2 - P*P; 64 double S = (P2*f - P*fp) / det; 65 double F = (R*fp - P*f) / det; 128 66 129 67 flux->elements.Flt[iy] = F; 130 68 sky->elements.Flt[iy] = S; 131 69 } 70 132 71 return TRUE; 133 72 } 134 73 135 // weight is 1 / variance136 // Fwind, Fprof are pointers to the start of a single row137 // Fwind is the observed flux in the window138 // Fprof is the slit profile139 void fitflux (float *Fwind, float *Fprof, float *weight, int Nx, double *flux, double *sky) {140 141 // calculate elements of the chi-square fit for this row:142 143 double R = 0.0, P = 0.0, P2 = 0.0, f = 0.0, fp = 0.0;144 145 for (int ix = 0; ix < Nx; ix++) {146 147 double fxy = Fwind[ix];148 double pxy = Fprof[ix];149 150 // skip NAN / Inf pixels in either window or slit151 if (!isfinite(fxy)) continue;152 if (!isfinite(pxy)) continue;153 154 double wt = (weight == NULL) ? 1.0 : weight[ix];155 R += wt;156 P += pxy*wt;157 P2 += pxy*pxy*wt;158 f += fxy*wt;159 fp += fxy*pxy*wt;160 }161 162 double det = R*P2 - P*P;163 *sky = (P2*f - P*fp) / det;164 *flux = (R*fp - P*f) / det;165 }
Note:
See TracChangeset
for help on using the changeset viewer.
