Changeset 40779
- Timestamp:
- Jun 2, 2019, 5:38:05 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitslit.c
r40773 r40779 1 1 # include "data.h" 2 # define IRLS_TOLERANCE 1e-4 3 4 float weight_cauchy_square_flt (float x2); 5 static void fitflux (float *Fwind, float *Fprof, float *weight, int Nx, double *flux, double *sky); 2 6 3 7 int deimos_fitslit (int argc, char **argv) { 4 8 5 // fitslit (window) (slit) (flux) (sky) 6 7 // int N; 9 // fitslit (window) (vari) (slit) (flux) (sky) 8 10 9 11 Vector *flux = NULL; … … 11 13 12 14 Buffer *wind = NULL; 15 Buffer *vari = NULL; 13 16 Buffer *slit = NULL; 14 17 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"); 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"); 18 36 gprint (GP_ERR, " outputs: flux (best-fit 1D flux), sky (best-fit 1D background)\n"); 19 37 return FALSE; … … 22 40 // XXX I probably should rename FindSpline as SelectSpline and give it the same behavior 23 41 if ((wind = SelectBuffer (argv[1], OLDBUFFER, 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 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); 29 46 30 47 // define the output window … … 32 49 int Ny = wind[0].matrix.Naxis[1]; 33 50 51 // confirm wind, vari, slit have same dimensions 34 52 if (Nx != slit[0].matrix.Naxis[0]) { gprint (GP_ERR, "size mismatch in fitslit for window and slit\n"); return FALSE; } 35 53 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; } 36 56 37 57 ResetVector (flux, OPIHI_FLT, Ny); 38 58 ResetVector (sky, OPIHI_FLT, Ny); 39 59 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 40 64 float *Fwind = (float *) wind[0].matrix.buffer; 65 float *Fvari = (float *) vari[0].matrix.buffer; 41 66 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); 42 71 43 72 // loop over the rows 44 73 for (int iy = 0; iy < Ny; iy++) { 45 74 46 // calculate elements of the chi-square for this row:75 double F = 0.0, S = 0.0; 47 76 48 double R = 0.0, P = 0.0, P2 = 0.0, f = 0.0, fp = 0.0; 49 double wt = 1.0; 50 77 // set weight based on the variance 51 78 for (int ix = 0; ix < Nx; ix++) { 52 53 // skip NAN / Inf pixels in either window or slit 54 if (!isfinite(Fwind[ix + iy*Nx])) continue; 55 if (!isfinite(Fprof[ix + iy*Nx])) continue; 56 57 float fxy = Fwind[ix + iy*Nx]; 58 float pxy = Fprof[ix + iy*Nx]; 59 60 R += wt; 61 P += pxy*wt; 62 P2 += pxy*pxy*wt; 63 f += fxy*wt; 64 fp += fxy*pxy*wt; 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]; 65 82 } 66 83 67 double det = R*P2 - P*P; 68 double S = (P2*f - P*fp) / det; 69 double F = (R*fp - P*f) / det; 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 } 70 128 71 129 flux->elements.Flt[iy] = F; 72 130 sky->elements.Flt[iy] = S; 73 131 } 74 75 132 return TRUE; 76 133 } 77 134 78 void fitflux () { 79 // calculate elements of the chi-square for this row: 135 // weight is 1 / variance 136 // Fwind, Fprof are pointers to the start of a single row 137 // Fwind is the observed flux in the window 138 // Fprof is the slit profile 139 void fitflux (float *Fwind, float *Fprof, float *weight, int Nx, double *flux, double *sky) { 80 140 81 double R = 0.0, P = 0.0, P2 = 0.0, f = 0.0, fp = 0.0; 82 double wt = 1.0; 141 // calculate elements of the chi-square fit for this row: 83 142 84 for (int ix = 0; ix < Nx; ix++) { 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++) { 85 146 86 // skip NAN / Inf pixels in either window or slit 87 if (!isfinite(Fwind[ix + iy*Nx])) continue; 88 if (!isfinite(Fprof[ix + iy*Nx])) continue; 147 double fxy = Fwind[ix]; 148 double pxy = Fprof[ix]; 89 149 90 float fxy = Fwind[ix + iy*Nx]; 91 float pxy = Fprof[ix + iy*Nx]; 150 // skip NAN / Inf pixels in either window or slit 151 if (!isfinite(fxy)) continue; 152 if (!isfinite(pxy)) continue; 92 153 93 R += wt; 94 P += pxy*wt; 95 P2 += pxy*pxy*wt; 96 f += fxy*wt; 97 fp += fxy*pxy*wt; 98 } 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 } 99 161 100 double det = R*P2 - P*P;101 double S= (P2*f - P*fp) / det;102 double F= (R*fp - P*f) / det;162 double det = R*P2 - P*P; 163 *sky = (P2*f - P*fp) / det; 164 *flux = (R*fp - P*f) / det; 103 165 }
Note:
See TracChangeset
for help on using the changeset viewer.
