- Timestamp:
- Nov 27, 2019, 11:04:51 AM (7 years ago)
- Location:
- trunk/Ohana/src/opihi/mana
- Files:
-
- 1 deleted
- 8 edited
- 7 copied
-
Makefile (modified) (1 diff)
-
deimos.c (modified) (1 diff)
-
deimos_arclines.c (modified) (2 diffs)
-
deimos_fitalt.c (deleted)
-
deimos_fitarc.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitarc.c )
-
deimos_fitobj.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitobj.c )
-
deimos_fitobj.v0.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitobj.v0.c )
-
deimos_fitprofile.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_fitprofile.c )
-
deimos_fitslit.c (modified) (4 diffs)
-
deimos_getobj.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_getobj.c )
-
deimos_getobj.v0.c (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/deimos_getobj.v0.c )
-
deimos_mkalt.c (modified) (2 diffs)
-
deimos_mkmodel.c (modified) (7 diffs)
-
deimos_mkobj.c (modified) (7 diffs)
-
deimos_mkslit.c (modified) (7 diffs)
-
test (copied) (copied from branches/eam_branches/ohana.20190329/src/opihi/mana/test )
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/mana/Makefile
r40655 r41159 26 26 $(SRC)/deimos_getobj.$(ARCH).o \ 27 27 $(SRC)/deimos_fitobj.$(ARCH).o \ 28 $(SRC)/deimos_fitalt.$(ARCH).o \29 $(SRC)/deimos_mkalt.$(ARCH).o \30 28 $(SRC)/deimos_mkmodel.$(ARCH).o \ 31 29 $(SRC)/deimos_arclines.$(ARCH).o \ 30 $(SRC)/deimos_fitarc.$(ARCH).o \ 31 $(SRC)/deimos_fitprofile.$(ARCH).o \ 32 32 $(SRC)/findrowpeaks.$(ARCH).o 33 33 -
trunk/Ohana/src/opihi/mana/deimos.c
r40655 r41159 4 4 int deimos_fitslit (int argc, char **argv); 5 5 int deimos_mkobj (int argc, char **argv); 6 int deimos_mkalt (int argc, char **argv);7 6 int deimos_getobj (int argc, char **argv); 7 // int deimos_getalt (int argc, char **argv); 8 8 int deimos_fitobj (int argc, char **argv); 9 int deimos_fitalt (int argc, char **argv);9 // int deimos_fitalt (int argc, char **argv); 10 10 int deimos_arclines (int argc, char **argv); 11 int deimos_fitarc (int argc, char **argv); 12 int deimos_fitprofile (int argc, char **argv); 11 13 12 14 static Command deimos_commands[] = { 13 {1, "fitobj", deimos_fitobj, "fit for object parameters"}, 14 {1, "fitalt", deimos_fitalt, "fit for object parameters using LMM"}, 15 {1, "getobj", deimos_getobj, "determine crude object parameters"}, 16 {1, "mkobj", deimos_mkobj, "make a full object image"}, 17 {1, "mkalt", deimos_mkalt, "make a full object image (uses deimos_make_object, for a test)"}, 18 {1, "mkslit", deimos_mkslit, "make a slit image"}, 19 {1, "fitslit", deimos_fitslit, "fit slit image to observed slit flux"}, 20 {1, "arclines", deimos_arclines, "detect arclines using LSF and STILT"}, 15 {1, "fitobj", deimos_fitobj, "fit for object parameters using LMM"}, 16 {1, "fitalt", deimos_fitobj, "fit for object parameters using LMM"}, 17 {1, "getobj", deimos_getobj, "determine crude object parameters"}, 18 {1, "getalt", deimos_getobj, "determine crude object parameters"}, 19 {1, "mkobj", deimos_mkobj, "make a full object image"}, 20 {1, "mkslit", deimos_mkslit, "make a slit image"}, 21 {1, "fitslit", deimos_fitslit, "fit slit image to observed slit flux"}, 22 {1, "arclines", deimos_arclines, "detect arclines using LSF and STILT"}, 23 {1, "fitarc", deimos_fitarc, "fit arclamp lines"}, 24 {1, "fitprofile", deimos_fitprofile, "fit slit profile"}, 21 25 }; 22 26 -
trunk/Ohana/src/opihi/mana/deimos_arclines.c
r40655 r41159 53 53 deimos_make_LSF_kernel (LSF, stilt, Nx); 54 54 55 // FILE *Fout = NULL; 56 55 57 // loop over the rows 56 58 for (int iy = 0; iy < Ny; iy++) { 57 59 float Fsum = 0; 60 float Ksum = 0; 61 62 // if (iy == 5802) Fout = fopen ("test.5802.dat", "w"); 63 // if (iy == 5815) Fout = fopen ("test.5815.dat", "w"); 64 58 65 // cross-correlation of buffer values and kernel values 59 66 for (int ix = 0; ix < Nx; ix++) { … … 62 69 if ((iy + ky) < 0) continue; 63 70 if ((iy + ky) >= Ny) continue; 71 if (!isfinite(Fin[ix + (iy + ky)*Nx])) continue; 72 if (!isfinite(kernel[ix + ko*Nx])) continue; 64 73 Fsum += Fin[ix + (iy + ky)*Nx] * kernel[ix + ko*Nx]; 74 Ksum += kernel[ix + ko*Nx]; 75 // if ((iy == 5815) || (iy == 5802)) { 76 // fprintf (Fout, "%d %d %d : %f %f\n", iy, ix, ky, Fin[ix + (iy + ky)*Nx], kernel[ix + ko*Nx]); 77 // } 65 78 } 66 79 } 80 81 // if ((iy == 5815) || (iy == 5802)) fclose (Fout); 82 67 83 coord->elements.Flt[iy] = iy; 68 84 flux->elements.Flt[iy] = Fsum; -
trunk/Ohana/src/opihi/mana/deimos_fitslit.c
r40659 r41159 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 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; 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]; 61 82 } 62 83 63 double det = R*P2 - P*P; 64 double S = (P2*f - P*fp) / det; 65 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 } 66 128 67 129 flux->elements.Flt[iy] = F; 68 130 sky->elements.Flt[iy] = S; 69 131 } 70 71 132 return TRUE; 72 133 } 73 134 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) { 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 slit 151 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 } -
trunk/Ohana/src/opihi/mana/deimos_mkalt.c
r40642 r41159 1 1 # include "data.h" 2 2 # include "deimos.h" 3 4 XXX: deprecated 3 5 4 6 // Use this to test the deimos_make_object function used by deimos_fitobj … … 92 94 93 95 // generate the model based on the test values 94 float *model = deimos_make_model (objV, skyV, bckV, psf, profile, trace, N x, Ny, 0);96 float *model = deimos_make_model (objV, skyV, bckV, psf, profile, trace, NULL, Nx, Ny, 0); 95 97 96 98 ResetBuffer (output, Nx, Ny, -32, 0.0, 1.0); -
trunk/Ohana/src/opihi/mana/deimos_mkmodel.c
r40659 r41159 86 86 // generate a subimage of the full model for the range row - row + Ny 87 87 // obj,sky,bck are subset vectors corresponding to the range row to row+Ny 88 float *deimos_make_model (opihi_flt *obj, opihi_flt *sky, opihi_flt *bck, Vector *psf, Vector *profile, Spline *trace, int Nx, int Ny, int row) { 89 90 float *raw = deimos_make_straight_image (obj, sky, psf, Nx, Ny, row); 88 // the slit_trace_* and psf_trace refer to the full image starting at row 89 float *deimos_make_model (opihi_flt *obj, opihi_flt *sky, opihi_flt *bck, Vector *psf, Vector *profile, Spline *slit_trace_red, Spline *slit_trace_blu, float redlimit, Spline *psf_trace, int Nx, int Ny, int row) { 90 91 float *raw = deimos_make_straight_image (obj, sky, psf, psf_trace, Nx, Ny, row); 91 92 float *new = deimos_apply_tilt (raw, Nx, Ny); 92 93 deimos_apply_profile (profile, new, Nx, Ny); 93 94 deimos_add_background (bck, new, Nx, Ny, row); 94 float *out = deimos_apply_trace ( trace, new, Nx, Ny, row);95 float *out = deimos_apply_trace (slit_trace_red, slit_trace_blu, redlimit, new, Nx, Ny, row); 95 96 96 97 free (raw); … … 104 105 // *** generate a raw image with no slit tilt and no trace offsets. apply the PSF to the 105 106 // object flux, add in the sky flux 106 float *deimos_make_straight_image (opihi_flt *obj, opihi_flt *sky, Vector *psf, int Nx, int Ny, int row) {107 float *deimos_make_straight_image (opihi_flt *obj, opihi_flt *sky, Vector *psf, Spline *psf_trace, int Nx, int Ny, int row) { 107 108 OHANA_UNUSED_PARAM(row); 108 109 … … 113 114 114 115 // Xref is a global supplied by the user (defaults to Nx/2 if < 0) 115 int Xoff = (int)(Xref - Npsf);116 int XoffRef = (int)(Xref - Npsf); 116 117 117 118 // Nx : width of output window … … 123 124 124 125 // we are generating the image for just the row range row to row+Ny 126 // note that obj & sky are subset vectors for just this range of pixels 125 127 opihi_flt objVy = obj[iy]; // if we shift to using the row offset: obj[iy + row] 126 128 opihi_flt skyVy = sky[iy]; // if we shift to using the row offset: sky[iy + row] 127 129 130 // integral and fractional pixel offsets of PSF (none, by default) 131 int dxi = 0; 132 float dxf = 0.0, dxr = 1.0; 133 int Xoff = XoffRef; 134 135 if (psf_trace) { 136 // the psf_trace is referenced against the full image, so we need to add row to iy: 137 float dx = spline_apply_dbl (psf_trace->xk, psf_trace->yk, psf_trace->y2, psf_trace->Nknots, iy + row); 138 dxi = floor(dx); 139 dxf = dx - dxi; // -1.7 -> +0.3, -0.5 -> +0.5, +0.5 ->+0.5, +1.7 -> +0.7 140 dxr = 1 - dxf; 141 Xoff += dxi; 142 // fprintf (stderr, "%d: %f : %d\n", iy + row, dx, Xoff); 143 } 144 145 // if fractional offset is small, do not interpolate 146 int doInterp = fabs(dxf) < 1e-5 ? FALSE : TRUE; 147 128 148 // flux = obj * PSF + sky 129 149 for (int ix = 0; ix < Nx; ix++) { … … 136 156 // only add in the flux if we are in range of the PSF 137 157 if ((n >= 0) && (n < NpsfFull)) { 138 value += objVy * psfV[n]; 158 if (doInterp) { 159 if ((n > 0) && (n < NpsfFull)) { 160 if (isfinite(psfV[n]) && isfinite(psfV[n-1])) { 161 value += objVy*psfV[n]*dxr + objVy*psfV[n-1]*dxf; 162 } 163 } 164 if (n == 0) { 165 if (isfinite(psfV[n])) { 166 value += objVy*psfV[n]*dxr; 167 } 168 } 169 } else { 170 if (isfinite(psfV[n])) { 171 value += objVy * psfV[n]; 172 } 173 } 139 174 } 140 175 out[ix + iy*Nx] = value; … … 219 254 220 255 // shift pixels in x based on the trace 221 float *deimos_apply_trace (Spline * trace, float *input, int Nx, int Ny, int row) {256 float *deimos_apply_trace (Spline *slit_trace_red, Spline *slit_trace_blu, float redlimit, float *input, int Nx, int Ny, int row) { 222 257 223 258 ALLOCATE_PTR (output, float, Nx*Ny); … … 227 262 // evaluate the trace spline at this y-coord to find the x-coord offset of the profile center 228 263 // NOTE: spline is evaluated at full dispersion coordinate 229 float dx = -spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy + row); 264 int iy_full = iy + row; 265 Spline *slit_trace = (iy_full < redlimit) ? slit_trace_red : slit_trace_blu; 266 float dx = -spline_apply_dbl (slit_trace->xk, slit_trace->yk, slit_trace->y2, slit_trace->Nknots, iy_full); 230 267 231 268 // extract the integer pixel offset and the fractional offset -
trunk/Ohana/src/opihi/mana/deimos_mkobj.c
r40659 r41159 6 6 7 7 // input parameters: 8 // * trace : spline fit of slit central x pos vs y-coord 9 // * profile : slit window profile (vector) 10 // * object : vector of object flux vs y-coord 11 // * sky : vector of local sky signal vs y-coord 12 // * background : vector of extra-slit background flux vs y-coord 13 // * PSF : point-spread function vector (flux normalized, x-dir) 14 // * LSF : sline-spread function vector (flux normalized, y-dir) 15 // * stilt : slit tilt response : 2D kernel? 8 // * slit_trace_red : spline fit of slit central x pos vs y-coord for red chip 9 // * slit_trace_blu : spline fit of slit central x pos vs y-coord for blu chip 10 // * psf_trace : spline fit of psf central x pos vs y-coord 11 // * profile : slit window profile (vector) 12 // * object : vector of object flux vs y-coord 13 // * sky : vector of local sky signal vs y-coord 14 // * backgnd : vector of extra-slit background flux vs y-coord 15 // * PSF : point-spread function vector (flux normalized, x-dir) 16 // * LSF : sline-spread function vector (flux normalized, y-dir) 17 // * stilt : slit tilt response : 2D kernel? 18 19 // * redlimit : pixel break between red and blu chips 20 // * Nwave : number of wavelength pixels in output image 16 21 17 22 int N; 18 23 19 24 // if any of these are not defined, they will have assumed identity values 20 Spline *trace = NULL; 21 Vector *profile = NULL; 22 Vector *object = NULL; 23 Vector *sky = NULL; 24 Vector *backgnd = NULL; 25 26 Vector *psf = NULL; 27 Vector *lsf = NULL; 25 Spline *slit_trace_red = NULL; 26 Spline *slit_trace_blu = NULL; 27 Spline *psf_trace = NULL; 28 Vector *profile = NULL; 29 Vector *object = NULL; 30 Vector *sky = NULL; 31 Vector *backgnd = NULL; 32 33 Vector *psf = NULL; 34 Vector *lsf = NULL; 28 35 // add tilt later 29 36 30 Buffer *output = NULL;37 Buffer *output = NULL; 31 38 32 39 float stilt = 0.0; // angle of the slit 33 40 34 if ((N = get_argument (argc, argv, "-trace"))) { 35 remove_argument (N, &argc, argv); 36 if ((trace = FindSpline (argv[N])) == NULL) return (FALSE); 41 // for a red vs blu spline, we need to specify the split point 42 // XXX this is REALLY ad-hoc for Deimos. not sure how to make 43 // this more generic (need to define the ranges somewhere) 44 int redlimit = 4096; 45 if ((N = get_argument (argc, argv, "-redlimit"))) { 46 remove_argument (N, &argc, argv); 47 redlimit = atoi (argv[N]); 48 remove_argument (N, &argc, argv); 49 } 50 51 if ((N = get_argument (argc, argv, "-slit-trace-red"))) { 52 remove_argument (N, &argc, argv); 53 if ((slit_trace_red = FindSpline (argv[N])) == NULL) return (FALSE); 54 remove_argument (N, &argc, argv); 55 } 56 if ((N = get_argument (argc, argv, "-slit-trace-blu"))) { 57 remove_argument (N, &argc, argv); 58 if ((slit_trace_blu = FindSpline (argv[N])) == NULL) return (FALSE); 59 remove_argument (N, &argc, argv); 60 } 61 if ((N = get_argument (argc, argv, "-psf-trace"))) { 62 remove_argument (N, &argc, argv); 63 if ((psf_trace = FindSpline (argv[N])) == NULL) return (FALSE); 37 64 remove_argument (N, &argc, argv); 38 65 } … … 81 108 } 82 109 110 int VERBOSE = FALSE; 111 if ((N = get_argument (argc, argv, "-v"))) { 112 remove_argument (N, &argc, argv); 113 VERBOSE = TRUE; 114 } 115 83 116 if (argc != 3) { 84 gprint (GP_ERR, "USAGE: deimos mkobj (buffer) (Ncross) [-Nwave N] [-object vector] [-sky vector] [-backgnd vector] [-trace spline] [-profile vector]\n"); 117 gprint (GP_ERR, "USAGE: deimos mkobj (buffer) (Ncross) [-object vector] [-sky vector] [-backgnd vector] [-slit-trace-red spline] [-slit-trace-blu spline] [-psf-trace spline] [-profile vector] [-psf vector] [-lsf vector] [-stilt angle] [-Nwave Npixel] [-redlimit pixel]\n"); 118 gprint (GP_ERR, " slit_trace_red : spline fit of slit central x pos vs y-coord for red chip\n"); 119 gprint (GP_ERR, " slit_trace_blu : spline fit of slit central x pos vs y-coord for blu chip\n"); 120 gprint (GP_ERR, " psf_trace : spline fit of psf central x pos vs y-coord\n"); 121 gprint (GP_ERR, " profile : slit window profile (vector)\n"); 122 gprint (GP_ERR, " object : vector of object flux vs y-coord \n"); 123 gprint (GP_ERR, " sky : vector of local sky signal vs y-coord\n"); 124 gprint (GP_ERR, " backgnd : vector of extra-slit background flux vs y-coord\n"); 125 gprint (GP_ERR, " PSF : point-spread function vector (flux normalized, x-dir)\n"); 126 gprint (GP_ERR, " LSF : sline-spread function vector (flux normalized, y-dir)\n"); 127 gprint (GP_ERR, " stilt : slit tilt response : 2D kernel? \n"); 128 gprint (GP_ERR, " redlimit : pixel break between red and blu chips\n"); 129 gprint (GP_ERR, " Nwave : number of wavelength pixels in output image\n"); 85 130 return FALSE; 86 131 } … … 123 168 // if we are appying a trace offset spline, we need to generate an output window which 124 169 // is Nx + the full swing of the trace, then window back down 125 if ( trace) {170 if (slit_trace_red && slit_trace_blu) { 126 171 float dXmin = +1000; 127 172 float dXmax = -1000; 128 173 for (int iy = 0; iy < Ny; iy++) { 129 174 // evaluate the trace spline at this y-coord to find the x-coord offset of the profile center 130 float dx = spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy); 175 Spline *slit_trace = (iy < redlimit) ? slit_trace_red : slit_trace_blu; 176 float dx = spline_apply_dbl (slit_trace->xk, slit_trace->yk, slit_trace->y2, slit_trace->Nknots, iy); 131 177 dXmin = MIN (dx, dXmin); 132 178 dXmax = MAX (dx, dXmax); … … 181 227 if (psf) Npof -= Npsf; 182 228 229 // integral and fractional pixel offsets of PSF (none, by default) 230 int dxi = 0; 231 float dxf = 0.0, dxr = 1.0; 232 233 if (psf_trace) { 234 float dx = spline_apply_dbl (psf_trace->xk, psf_trace->yk, psf_trace->y2, psf_trace->Nknots, iy); 235 dxi = floor(dx); 236 dxf = dx - dxi; // -1.7 -> +0.3, -0.5 -> +0.5, +0.5 ->+0.5, +1.7 -> +0.7 237 dxr = 1 - dxf; 238 Npof += dxi; 239 // fprintf (stderr, "%d: %f : %d\n", iy, dx, Npof); 240 if (VERBOSE && (iy % 200 == 0)) { gprint (GP_ERR, "%d : %f : %d : %f %f\n", iy, dx, dxi, dxf, dxr); } 241 } 242 243 // if fractional offset is small, do not interpolate 244 int doInterp = fabs(dxf) < 1e-5 ? FALSE : TRUE; 245 183 246 // flux = obj * PSF + sky 184 247 for (int ix = 0; ix < Nx; ix++) { … … 191 254 // only add in the flux if we are in range of the PSF 192 255 if ((n >= 0) && (n < NpsfFull)) { 193 value += objVy * psfV[n]; 256 if (doInterp) { 257 if ((n > 0) && (n < NpsfFull)) { 258 if (isfinite(psfV[n]) && isfinite(psfV[n-1])) { 259 value += objVy*psfV[n]*dxr + objVy*psfV[n-1]*dxf; 260 } 261 } 262 if (n == 0) { 263 if (isfinite(psfV[n])) { 264 value += objVy*psfV[n]*dxr; 265 } 266 } 267 } else { 268 if (isfinite(psfV[n])) { 269 value += objVy*psfV[n]; 270 } 271 } 194 272 } 195 273 } else { … … 329 407 330 408 // shift pixels in x based on the trace 331 if ( trace) {409 if (slit_trace_red && slit_trace_blu) { 332 410 ALLOCATE_PTR (outTraceBuffer, char, NxBase*Ny*sizeof(float)); 333 411 float *outTrace = (float *) outTraceBuffer; … … 337 415 338 416 // evaluate the trace spline at this y-coord to find the x-coord offset of the profile center 339 float dx = -spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy); 417 Spline *slit_trace = (iy < redlimit) ? slit_trace_red : slit_trace_blu; 418 float dx = -spline_apply_dbl (slit_trace->xk, slit_trace->yk, slit_trace->y2, slit_trace->Nknots, iy); 340 419 341 420 // extract the integer pixel offset and the fractional offset -
trunk/Ohana/src/opihi/mana/deimos_mkslit.c
r40659 r41159 7 7 // input parameters: 8 8 // slit profile response : vector of fractional flux vs x-coord 9 // trace : spline fit of slit central x pos vs y-coord 10 // flux : vector of input signal vs y-coord 9 // trace_ref,trace_blu : spline fit of slit central x pos vs y-coord 10 // flux (optional) : vector of input signal vs y-coord 11 // sky (optional) : vector of input signal vs y-coord 12 // fluxbins (optional) : size of output image in y-direction 13 // NOTE: one of flux, sky, or fluxbins must be defined 14 15 // output : buff (an image with Nx defined by profile and Ny defined 16 // by flux, sky, or fluxbins) 11 17 12 18 int N; 13 19 14 Vector *profile = NULL; 15 Vector *flux = NULL; 16 Vector *sky = NULL; 17 Spline *trace = NULL; 18 Buffer *buff = NULL; 20 Vector *profile = NULL; 21 Vector *flux = NULL; 22 Vector *sky = NULL; 23 Spline *trace_red = NULL; 24 Spline *trace_blu = NULL; 25 Buffer *buff = NULL; 19 26 20 27 // user-specified flux value (otherwise assumed to be 1) … … 40 47 } 41 48 42 if (argc != 4) { 43 gprint (GP_ERR, "USAGE: deimos mkslit (profile) (trace) (buffer) [-flux vector] [-fluxbins N] [-sky vector]\n"); 49 // either flux or fluxbins must be specified to define output size 50 int profilebins = 0; 51 if ((N = get_argument (argc, argv, "-profilebins"))) { 52 remove_argument (N, &argc, argv); 53 profilebins = atoi (argv[N]); 54 remove_argument (N, &argc, argv); 55 } 56 57 // for a red vs blu spline, we need to specify the split point 58 // XXX this is REALLY ad-hoc for Deimos. not sure how to make 59 // this more generic (need to define the ranges somewhere) 60 int redlimit = 4096; 61 if ((N = get_argument (argc, argv, "-redlimit"))) { 62 remove_argument (N, &argc, argv); 63 redlimit = atoi (argv[N]); 64 remove_argument (N, &argc, argv); 65 } 66 67 if (argc != 5) { 68 gprint (GP_ERR, "USAGE: deimos mkslit (profile) (trace_red) (trace_blu) (buffer) [-flux vector] [-fluxbins N] [-sky vector]\n"); 44 69 return FALSE; 45 70 } … … 51 76 52 77 // XXX I probably should rename FindSpline as SelectSpline and give it the same behavior 53 if ((profile = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 54 if ((trace = FindSpline (argv[2])) == NULL) return (FALSE); 55 if ((buff = SelectBuffer (argv[3], ANYBUFFER, TRUE)) == NULL) return (FALSE); 78 if ((profile = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 79 if ((trace_red = FindSpline (argv[2])) == NULL) return (FALSE); 80 if ((trace_blu = FindSpline (argv[3])) == NULL) return (FALSE); 81 if ((buff = SelectBuffer (argv[4], ANYBUFFER, TRUE)) == NULL) return (FALSE); 56 82 57 83 // define the output window 58 int Nx = 2*profile[0].Nelements + 1; 84 // if no profile half-width is specified, use supplied profile 85 int Nx = profilebins ? 2*profilebins + 1 : 2*profile[0].Nelements + 1; 59 86 int Ny = flux ? flux[0].Nelements : fluxbins; 60 87 … … 73 100 74 101 // evaluate the trace spline at this y-coord to find the x-coord offset of the profile center 102 Spline *trace = (iy < redlimit) ? trace_red : trace_blu; 75 103 float dx = spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy); 76 104 … … 90 118 91 119 // set the sky in the entire window 92 out[ix + iy*Nx] = sky ? sky->elements.Flt[iy] : 0.0;120 out[ix + iy*Nx] = NAN; 93 121 94 122 // equivalent coord in the profile: … … 98 126 99 127 // a default value: 128 float vsky = sky ? sky->elements.Flt[iy] : 0.0; 100 129 float vout = NAN; 101 130 … … 121 150 if (flux) vout *= flux->elements.Flt[iy]; 122 151 123 out[ix + iy*Nx] +=vout;152 out[ix + iy*Nx] = vsky + vout; 124 153 } 125 154 }
Note:
See TracChangeset
for help on using the changeset viewer.
