Changeset 41340 for trunk/Ohana/src/opihi/cmd.data/cut.c
- Timestamp:
- Apr 16, 2020, 1:54:47 PM (6 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/cmd.data/cut.c (modified) (6 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/cmd.data/cut.c
r41164 r41340 1 1 # include "data.h" 2 2 3 enum {SUM, MEAN, MEDIAN, INNER, NGOOD}; 4 5 double cutstat (float *value, int Nvalue, int mode) { 6 7 double output = 0.0; 8 9 if (Nvalue == 0) return NAN; 10 11 if (mode == MEDIAN) { 12 fsort (value, Nvalue); 13 if (Nvalue % 2) { 14 int Ncenter = Nvalue / 2; 15 myAssert ((Ncenter >= 0) && (Ncenter < Nvalue), "cutstat"); 16 output = value[Ncenter]; 17 } else { 18 int Ncenter = Nvalue / 2 - 1; 19 myAssert ((Ncenter >= 0) && (Ncenter < Nvalue - 1), "cutstat"); 20 output = 0.5*(value[Ncenter] + value[Ncenter + 1]); 21 } 22 return output; 23 } 24 if (mode == INNER) { 25 fsort (value, Nvalue); 26 27 int Ns = 0, Ne = 0; 28 if (Nvalue % 2) { 29 // for an odd number of points take the same number below 30 // and above the center value 31 int Ncenter = Nvalue / 2; 32 int Nquarter = 0.25*Nvalue; 33 Ns = Ncenter - Nquarter; 34 Ne = Ncenter + Nquarter; 35 } else { 36 // for an even number, the middle lies between two points 37 // take the same number below as above 38 int Ncenter = (int)(Nvalue / 2) - 1; 39 int Nquarter = 0.25*Nvalue; 40 Ns = Ncenter - Nquarter; 41 Ne = Ncenter + 1 + Nquarter; 42 } 43 int Nv = 0; 44 for (int i = Ns; i <= Ne; i++) { 45 myAssert ((i >= 0) && (i < Nvalue), "cutstat"); 46 output += value[i]; 47 Nv ++; 48 } 49 output /= Nv; 50 return output; 51 } 52 if (mode == NGOOD) { 53 return Nvalue; 54 } 55 if ((mode == MEAN) || (mode == SUM)) { 56 for (int i = 0; i < Nvalue; i++) { 57 myAssert ((i >= 0) && (i < Nvalue), "cutstat"); 58 output += value[i]; 59 } 60 if (mode == MEAN) { output /= Nvalue; } 61 return output; 62 } 63 return NAN; 64 } 3 enum {SUM, MEAN, MEDIAN}; 65 4 66 5 int cut (int argc, char **argv) { 67 6 68 7 int i, j, N, Nx, Ny, Mode; 69 float *Vin, *Vbuf ;8 float *Vin, *Vbuf, value; 70 9 int sx, sy, nx, ny; 71 10 Vector *xvec, *yvec; … … 73 12 74 13 Mode = SUM; 75 if ((N = get_argument (argc, argv, "-sum"))) {76 remove_argument (N, &argc, argv);77 Mode = SUM;78 }79 14 if ((N = get_argument (argc, argv, "-median"))) { 80 15 remove_argument (N, &argc, argv); … … 84 19 remove_argument (N, &argc, argv); 85 20 Mode = MEAN; 86 }87 if ((N = get_argument (argc, argv, "-inner"))) {88 remove_argument (N, &argc, argv);89 Mode = INNER;90 }91 if ((N = get_argument (argc, argv, "-ngood"))) {92 remove_argument (N, &argc, argv);93 Mode = NGOOD;94 21 } 95 22 … … 109 36 Ny = buf[0].matrix.Naxis[1]; 110 37 111 // ny & nx do not need to be constrained by the buffer, but they do need to be sensible 112 if ((nx < 0) || (ny < 0) || (nx > 1e8) || (ny > 1e8)) { 113 gprint (GP_ERR, "warning : extraction size is crazy: %d,%d\n", nx, ny); 38 if ((sx < 0) || (sy < 0) || (sx+nx > Nx) || (sy+ny > Ny)) { 39 gprint (GP_ERR, "region out of range\n"); 114 40 return (FALSE); 115 41 } … … 131 57 132 58 for (i = 0; i < nx; i++) { 133 / / for out-of-range areas, set the output pixels to NAN134 if (i + sx < 0) {135 yvec[0].elements.Flt[i] = NAN; 136 continue;59 /* accumulate values */ 60 Vin = (float *)(buf[0].matrix.buffer) + sy*Nx + sx + i; 61 for (j = 0; j < ny; j++, Vin += Nx) { 62 Vbuf[j] = *Vin; 137 63 } 138 if (i + sx >= Nx) { 139 yvec[0].elements.Flt[i] = NAN; 140 continue; 64 /* apply stat of choice */ 65 if (Mode == MEDIAN) { 66 fsort (Vbuf, ny); 67 value = Vbuf[(int)(0.5*ny)]; 68 } else { 69 value = 0; 70 for (j = 0; j < ny; j++) { 71 value += Vbuf[j]; 72 } 73 if (Mode == MEAN) { value /= ny; } 141 74 } 142 143 /* accumulate values */ 144 // skip out-of-range areas in y 145 if (sy < 0) { 146 ny += sy; 147 sy = 0; 148 } 149 if (sy > Ny) sy = Ny; 150 if (sy + ny >= Ny) ny = Ny - sy; 151 152 Vin = (float *)(buf[0].matrix.buffer) + sy*Nx + sx + i; 153 int Npix = 0; 154 for (j = 0; j < ny; j++, Vin += Nx) { 155 if (!isfinite(*Vin)) continue; 156 Vbuf[Npix] = *Vin; 157 Npix ++; 158 } 159 yvec[0].elements.Flt[i] = cutstat (Vbuf, Npix, Mode); 75 yvec[0].elements.Flt[i] = value; 160 76 } 161 77 free (Vbuf); … … 173 89 174 90 for (i = 0; i < ny; i++) { 175 / / for out-of-range areas, set the output pixels to NAN176 if (i + sy < 0) {177 yvec[0].elements.Flt[i] = NAN; 178 continue;91 /* accumulate values */ 92 Vin = (float *)(buf[0].matrix.buffer) + (sy + i)*Nx + sx; 93 for (j = 0; j < nx; j++, Vin ++) { 94 Vbuf[j] = *Vin; 179 95 } 180 if (i + sy >= Ny) { 181 yvec[0].elements.Flt[i] = NAN; 182 continue; 96 /* apply stat of choice */ 97 if (Mode == MEDIAN) { 98 fsort (Vbuf, nx); 99 value = Vbuf[(int)(0.5*nx)]; 100 } else { 101 value = 0; 102 for (j = 0; j < nx; j++) { 103 value += Vbuf[j]; 104 } 105 if (Mode == MEAN) { value /= nx; } 183 106 } 184 185 /* accumulate values */ 186 // skip out-of-range areas in x 187 if (sx < 0) { 188 nx += sx; 189 sx = 0; 190 } 191 if (sx > Nx) sx = Nx; 192 if (sx + nx >= Nx) nx = Nx - sx; 193 194 Vin = (float *)(buf[0].matrix.buffer) + (sy + i)*Nx + sx; 195 int Npix = 0; 196 for (j = 0; j < nx; j++, Vin ++) { 197 if (!isfinite(*Vin)) continue; 198 Vbuf[Npix] = *Vin; 199 Npix ++; 200 } 201 yvec[0].elements.Flt[i] = cutstat (Vbuf, Npix, Mode); 107 yvec[0].elements.Flt[i] = value; 202 108 } 203 109 free (Vbuf);
Note:
See TracChangeset
for help on using the changeset viewer.
