Changeset 40622 for trunk/Ohana/src/opihi/mana/deimos_commands.c
- Timestamp:
- Feb 8, 2019, 8:20:03 PM (7 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/mana/deimos_commands.c (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/mana/deimos_commands.c
r40617 r40622 2 2 3 3 int deimos_mkslit (int argc, char **argv) { 4 OHANA_UNUSED_PARAM(argv);5 if (argc != 5) {6 gprint (GP_ERR, "USAGE: deimos mkslit (profile) (trace) (flux) (buffer)\n");7 return FALSE;8 }9 4 10 5 // generate model observed flux given a uniformly illuminated slit … … 16 11 17 12 Vector *profile = NULL; 18 Vector *flux = NULL; 19 Spline *trace = NULL; 20 Buffer *buff = NULL; 13 Vector *flux = NULL; 14 Vector *sky = NULL; 15 Spline *trace = NULL; 16 Buffer *buff = NULL; 17 18 // user-specified flux value (otherwise assumed to be 1) 19 if ((N = get_argument (argc, argv, "-flux"))) { 20 remove_argument (N, &argc, argv); 21 if ((flux = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE); 22 remove_argument (N, &argc, argv); 23 } 24 25 // user-specified sky value (otherwise assumed to be 0) 26 if ((N = get_argument (argc, argv, "-sky"))) { 27 remove_argument (N, &argc, argv); 28 if ((sky = SelectVector (argv[N], OLDVECTOR, TRUE)) == NULL) return (FALSE); 29 remove_argument (N, &argc, argv); 30 } 31 32 // either flux or fluxbins must be specified to define output size 33 int fluxbins = 0; 34 if ((N = get_argument (argc, argv, "-fluxbins"))) { 35 remove_argument (N, &argc, argv); 36 Nrows = atoi (argv[N]); 37 remove_argument (N, &argc, argv); 38 } 39 40 if (argc != 4) { 41 gprint (GP_ERR, "USAGE: deimos mkslit (profile) (trace) (buffer) [-flux vector] [-fluxbins N] [-sky vector]\n"); 42 return FALSE; 43 } 44 45 if (!flux && !fluxbins) { 46 gprint (GP_ERR, "either flux or fluxbins must be specified to define output size\n"); 47 return FALSE; 48 } 21 49 22 50 // XXX I probably should rename FindSpline as SelectSpline and give it the same behavior 23 51 if ((profile = SelectVector (argv[1], OLDVECTOR, TRUE)) == NULL) return (FALSE); 24 52 if ((trace = FindSpline (argv[2])) == NULL) return (FALSE); 25 if ((flux = SelectVector (argv[3], OLDVECTOR, TRUE)) == NULL) return (FALSE); 26 if ((buff = SelectBuffer (argv[4], ANYBUFFER, TRUE)) == NULL) return (FALSE); 27 53 if ((buff = SelectBuffer (argv[3], ANYBUFFER, TRUE)) == NULL) return (FALSE); 54 28 55 // define the output window 29 56 int Nx = 2*profile[0].Nelements; 30 int Ny = flux [0].Nelements;57 int Ny = flux ? flux[0].Nelements : fluxbins; 31 58 32 59 ResetBuffer (buff, Nx, Ny, -32, 0.0, 1.0); 33 60 61 // the profile is registered to the midpoint of the vector : (int) N / 2 62 // the output window is registered to the midpoint of the window : (int) Nx / 2 63 64 int NxMidProfile = profile->Nelements / 2; 65 int NxMidWindow = Nx / 2; 66 67 float *out = (float *) buff[0].matrix.buffer; 34 68 35 69 // loop over the y positions 36 for (i y = 0; iy < flux->Nelements; iy++) {70 for (int iy = 0; iy < Ny; iy++) { 37 71 38 // evaluate the trace spline at this y-coord to find the x-coord of the profile center39 opihi_flt dx = spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy);72 // evaluate the trace spline at this y-coord to find the x-coord offset of the profile center 73 float dx = spline_apply_dbl (trace->xk, trace->yk, trace->y2, trace->Nknots, iy); 40 74 41 // interpolate the profile with offset of dx 42 for (ix = 0; ix < profile->Nelements; ix++) { 43 // interpolate from profile->elements.Flt[ix], interpolate from profile->elements.Flt[ix+1] to ix+dx 75 // extract the integer pixel offset and the fractional offset 76 int dxi = floor(dx); // -1.7 -> -2, -0.5 -> -1, +0.5 -> 0, +1.7 -> 1 77 float dxf = dx - dxi; // -1.7 -> +0.3, -0.5 -> +0.5, +0.5 ->+0.5, +1.7 -> +0.7 78 79 // starting point in output window is : 80 // XXX handle case if profile is wider than window 81 int Sx = (int)(NxMidWindow - NxMidProfile) + dxi; 82 83 // if fractional offset is small, do not interpolate 84 int doInterp = fabs(dxf) < 1e-5 ? FALSE : TRUE; 85 86 // loop over the relevant pixels in the window: 87 for (int ix = 0; ix < Nx; ix++) { 88 89 // equivalent coord in the profile: 90 int px = ix - Sx; 91 if (px < 0) continue; 92 if (px >= profile->Nelements) continue; 93 94 float vout = NAN; 95 96 if (doInterp) { 97 if ((px > 0) && (px < profile->Nelements - 1)) { 98 // if ((px == 5) && (iy % 50 == 0)) { 99 // fprintf (stderr, "%d : %d %d : %d, %f\n", iy, Sx, px, dxi, dxf); 100 // } 101 // XXX something is not quite right in my math: I think (1-dx), dx are reversed 102 // but if I use what I expect the interpolation is backwards... 103 vout = profile->elements.Flt[px]*(1 - dxf) + profile->elements.Flt[px-1]*dxf; 104 } 105 if (px == 0) { 106 vout = profile->elements.Flt[px]*dxf; 107 } 108 if (px == profile->Nelements - 1) { 109 vout = profile->elements.Flt[profile->Nelements - 1]*(1.0 - dxf); 110 } 111 } else { 112 vout = profile->elements.Flt[px]; 113 } 114 115 if (flux) vout *= flux->elements.Flt[iy]; 116 if (sky) vout += sky->elements.Flt[iy]; 117 118 out[ix + iy*Nx] = vout; 44 119 } 45 46 120 } 47 121
Note:
See TracChangeset
for help on using the changeset viewer.
