Changeset 41341 for trunk/Ohana/src/opihi/cmd.data/cut.c
- Timestamp:
- Apr 16, 2020, 2:04:27 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
r41340 r41341 1 1 # include "data.h" 2 2 3 enum {SUM, MEAN, MEDIAN}; 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 } 4 65 5 66 int cut (int argc, char **argv) { 6 67 7 68 int i, j, N, Nx, Ny, Mode; 8 float *Vin, *Vbuf , value;69 float *Vin, *Vbuf; 9 70 int sx, sy, nx, ny; 10 71 Vector *xvec, *yvec; … … 12 73 13 74 Mode = SUM; 75 if ((N = get_argument (argc, argv, "-sum"))) { 76 remove_argument (N, &argc, argv); 77 Mode = SUM; 78 } 14 79 if ((N = get_argument (argc, argv, "-median"))) { 15 80 remove_argument (N, &argc, argv); … … 19 84 remove_argument (N, &argc, argv); 20 85 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; 21 94 } 22 95 … … 36 109 Ny = buf[0].matrix.Naxis[1]; 37 110 38 if ((sx < 0) || (sy < 0) || (sx+nx > Nx) || (sy+ny > Ny)) { 39 gprint (GP_ERR, "region out of range\n"); 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); 40 114 return (FALSE); 41 115 } … … 57 131 58 132 for (i = 0; i < nx; i++) { 133 // for out-of-range areas, set the output pixels to NAN 134 if (i + sx < 0) { 135 yvec[0].elements.Flt[i] = NAN; 136 continue; 137 } 138 if (i + sx >= Nx) { 139 yvec[0].elements.Flt[i] = NAN; 140 continue; 141 } 142 59 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 60 152 Vin = (float *)(buf[0].matrix.buffer) + sy*Nx + sx + i; 153 int Npix = 0; 61 154 for (j = 0; j < ny; j++, Vin += Nx) { 62 Vbuf[j] = *Vin; 63 } 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; } 74 } 75 yvec[0].elements.Flt[i] = value; 155 if (!isfinite(*Vin)) continue; 156 Vbuf[Npix] = *Vin; 157 Npix ++; 158 } 159 yvec[0].elements.Flt[i] = cutstat (Vbuf, Npix, Mode); 76 160 } 77 161 free (Vbuf); … … 89 173 90 174 for (i = 0; i < ny; i++) { 175 // for out-of-range areas, set the output pixels to NAN 176 if (i + sy < 0) { 177 yvec[0].elements.Flt[i] = NAN; 178 continue; 179 } 180 if (i + sy >= Ny) { 181 yvec[0].elements.Flt[i] = NAN; 182 continue; 183 } 184 91 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 92 194 Vin = (float *)(buf[0].matrix.buffer) + (sy + i)*Nx + sx; 195 int Npix = 0; 93 196 for (j = 0; j < nx; j++, Vin ++) { 94 Vbuf[j] = *Vin; 95 } 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; } 106 } 107 yvec[0].elements.Flt[i] = value; 197 if (!isfinite(*Vin)) continue; 198 Vbuf[Npix] = *Vin; 199 Npix ++; 200 } 201 yvec[0].elements.Flt[i] = cutstat (Vbuf, Npix, Mode); 108 202 } 109 203 free (Vbuf);
Note:
See TracChangeset
for help on using the changeset viewer.
