IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Apr 16, 2020, 2:04:27 PM (6 years ago)
Author:
tdeboer
Message:

quick undo

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Ohana/src/opihi/cmd.data/cut.c

    r41340 r41341  
    11# include "data.h"
    22
    3 enum {SUM, MEAN, MEDIAN};
     3enum {SUM, MEAN, MEDIAN, INNER, NGOOD};
     4
     5double 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}
    465
    566int cut (int argc, char **argv) {
    667 
    768  int i, j, N, Nx, Ny, Mode;
    8   float *Vin, *Vbuf, value;
     69  float *Vin, *Vbuf;
    970  int sx, sy, nx, ny;
    1071  Vector *xvec, *yvec;
     
    1273
    1374  Mode = SUM;
     75  if ((N = get_argument (argc, argv, "-sum"))) {
     76    remove_argument (N, &argc, argv);
     77    Mode = SUM;
     78  }
    1479  if ((N = get_argument (argc, argv, "-median"))) {
    1580    remove_argument (N, &argc, argv);
     
    1984    remove_argument (N, &argc, argv);
    2085    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;
    2194  }
    2295
     
    36109  Ny = buf[0].matrix.Naxis[1];
    37110
    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);
    40114    return (FALSE);
    41115  }
     
    57131
    58132    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
    59143      /* 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
    60152      Vin = (float *)(buf[0].matrix.buffer) + sy*Nx + sx + i;
     153      int Npix = 0;
    61154      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);
    76160    }
    77161    free (Vbuf);
     
    89173
    90174    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
    91185      /* 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
    92194      Vin = (float *)(buf[0].matrix.buffer) + (sy + i)*Nx + sx;
     195      int Npix = 0;
    93196      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);
    108202    }
    109203    free (Vbuf);
Note: See TracChangeset for help on using the changeset viewer.