gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master bd6d361: ImageCrop only checks center when cro


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master bd6d361: ImageCrop only checks center when crop is defined by its center
Date: Sun, 22 Jan 2017 02:26:37 +0000 (UTC)

branch: master
commit bd6d3614f1f14d7aa66937dbc12e652250139728
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    ImageCrop only checks center when crop is defined by its center
    
    Until now, ImageCrop would check if the center of a crop is blank or not in
    any case. This check makes sense when the crop is defined by its center
    (for example from a catalog), but when the crop isn't defined by its center
    (for example with the `--section', or `--polygon' options) this behavior
    can be annoying and cause unexpected behavior.
    
    Also, until now, you could only confirm if the crop's center was filled or
    not (and thus the file was created or not) from the `0' or `1' value in the
    third column of the log file or on stdout. The log file does have comments,
    but on stdout, this was rather cryptic and not intuitively understood. As
    suggested by Mosè in task #14318 this could also cause confusions.
    
    Also, until now `--checkcenter' would only take values `>=3', so, to
    disable checking we needed another option (`--keepblankcenter'). But now,
    `--checkcenter=0' means that no center checking will be done. Therefore the
    old `--keepblankcenter' option is no longer needed and was removed. Infact,
    the default value of `--checkcenter' was set to `0' so by default no center
    checking will be done. Only if the user explicitly gives it a larger value
    on the command-line or in their configuration files will it be
    activated. This is done based on the principle of least astonishment: for a
    new user, not having an output is a strange behavior (even it is is
    beneficial for them). After they learn about it, they can use it.
    
    Finally, the appropriate sections of the book were reviewed to reflect this
    new behavior. Most of these sections had not been changed from the time
    they were created and were outdated (even before this commit). This has
    been corrected now.
    
    Other corrections that were done as part of this task are:
    
     - The `iscenterfilled' function of `crop.c' would go on trying to find
       blank values in the central region. However, CFITSIO already outputs the
       `anynul' variable for the same purpose. To be fair, until now we would
       check if ALL the central region was blank, not just that it had a single
       blank value. The reason this was changed is that the user can now ask
       for a one pixel central region if they want to.
    
     - In ImageCrop's `reportcrop' function, the message string is now allocated
       with `asprintf' to avoid any memory issues with static allocation.
    
     - A new code in ImageCrop's log file was created to show cases where the
       center wasn't checked.
    
     - ImageCrop did its own writing of WCS header keywords, so the recently
       added `gal_wcs_decompose_pc_cdelt' was implemented in it.
    
    This finishes task #14318.
---
 bin/imgcrop/args.h             |   17 +-
 bin/imgcrop/astimgcrop.conf    |    2 +-
 bin/imgcrop/crop.c             |  125 +++++--------
 bin/imgcrop/crop.h             |    3 +-
 bin/imgcrop/imgcrop.c          |   42 +++--
 bin/imgcrop/main.h             |    1 +
 bin/imgcrop/ui.c               |   23 ++-
 bin/imgcrop/wcsmode.c          |    9 +-
 doc/gnuastro.texi              |  383 ++++++++++++++++++++++------------------
 tests/imgcrop/imgoutpolygon.sh |    2 +-
 10 files changed, 309 insertions(+), 298 deletions(-)

diff --git a/bin/imgcrop/args.h b/bin/imgcrop/args.h
index cb670e3..1f75a1e 100644
--- a/bin/imgcrop/args.h
+++ b/bin/imgcrop/args.h
@@ -73,7 +73,7 @@ const char doc[] =
 
 /* Available letters for short options:
 
-   e m n t u v
+   e k m n t u v
    A B C E F G H J L M O Q R T U X Y Z
 
    Number keys used<=502
@@ -150,14 +150,6 @@ static struct argp_option options[] =
       2
     },
     {
-      "keepblankcenter",
-      'k',
-      0,
-      0,
-      "Keep crop if the central parts are not filled.",
-      2
-    },
-    {
       "checkcenter",
       'c',
       "INT",
@@ -374,12 +366,9 @@ parse_opt(int key, char *arg, struct argp_state *state)
     case 'b':
       p->noblank=1;
       break;
-    case 'k':
-      p->keepblankcenter=1;
-      break;
     case 'c':
-      gal_checkset_sizet_l_zero(arg, &p->checkcenter, "checkcenter",
-                                key, SPACK, NULL, 0);
+      gal_checkset_sizet_el_zero(arg, &p->checkcenter, "checkcenter",
+                                 key, SPACK, NULL, 0);
       p->up.checkcenterset=1;
       break;
     case 'p':
diff --git a/bin/imgcrop/astimgcrop.conf b/bin/imgcrop/astimgcrop.conf
index e0e129f..c2fb09b 100644
--- a/bin/imgcrop/astimgcrop.conf
+++ b/bin/imgcrop/astimgcrop.conf
@@ -33,5 +33,5 @@
  hendwcs        0
 
 # Output parameters:
- checkcenter    3
+ checkcenter    0
  suffix        _cropped.fits
diff --git a/bin/imgcrop/crop.c b/bin/imgcrop/crop.c
index 57c9014..48e9d26 100644
--- a/bin/imgcrop/crop.c
+++ b/bin/imgcrop/crop.c
@@ -71,20 +71,24 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Read the section string and set the starting and ending pixels
    based on that. */
 void
-sectionparser(char *section, long *naxes, long *fpixel, long *lpixel)
+sectionparser(struct imgcropparams *p, long *naxes,
+              long *fpixel, long *lpixel)
 {
   int add;
   long read;
   size_t dim=0;
   char *tailptr;
-  char forl='f', *pt=section;
+  char forl='f', *pt=p->section;
+
+  /* If control reached here, then the cropped region is not defined by its
+     center. So it makes no sense to check if the center is blank. */
+  p->checkcenter=0;
 
   /* Initialize the fpixel and lpixel arrays: */
   lpixel[0]=naxes[0];
   lpixel[1]=naxes[1];
   fpixel[0]=fpixel[1]=1;
 
-
   /* Parse the string. */
   while(*pt!='\0')
     {
@@ -94,7 +98,7 @@ sectionparser(char *section, long *naxes, long *fpixel, long 
*lpixel)
         case ',':
           ++dim;
           if(dim==2)
-            error(EXIT_FAILURE, 0, "Extra `,` in `%s`", section);
+            error(EXIT_FAILURE, 0, "Extra `,` in `%s`", p->section);
           forl='f';
           ++pt;
           break;
@@ -105,8 +109,7 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
         case '.':
           error(EXIT_FAILURE, 0, "the numbers in the argument to "
                 "`--section` (`-s') have to be integers. You input "
-                "includes a float number: %s",
-                section);
+                "includes a float number: %s", p->section);
           break;
         case ' ': case '\t':
           ++pt;
@@ -151,12 +154,13 @@ sectionparser(char *section, long *naxes, long *fpixel, 
long *lpixel)
       */
     }
 
+  /* Make sure the first pixel is located before/below the last pixel. */
   if(fpixel[0]>lpixel[0] || fpixel[1]>lpixel[1])
     error(EXIT_FAILURE, 0, "the bottom left corner coordinates "
           "cannot be larger or equal to the top right's! Your section "
           "string (%s) has been read as: bottom left coordinate "
           "(%ld, %ld) to top right coordinate (%ld, %ld)",
-          section, fpixel[0], fpixel[1], lpixel[0], lpixel[1]);
+          p->section, fpixel[0], fpixel[1], lpixel[0], lpixel[1]);
 
   /*
   printf("\n%s\nfpixel=(%ld, %ld), lpixel=(%ld, %ld)\n\n", section,
@@ -179,6 +183,10 @@ polygonparser(struct imgcropparams *p)
   struct gal_linkedlist_tdll *gal_linkedlist_tdll=NULL;
   char *pt=p->up.polygon;
 
+  /* If control reached here, then the cropped region is not defined by its
+     center. So it makes no sense to check if the center is blank. */
+  p->checkcenter=0;
+
   /* Parse the string. */
   while(*pt!='\0')
     {
@@ -527,7 +535,7 @@ cropflpixel(struct cropparams *crp)
       else if(p->up.xcset)
         gal_box_border_from_center(p->xc, p->yc, p->iwidth, fpixel, lpixel);
       else if(p->up.sectionset)
-        sectionparser(p->section, naxes, fpixel, lpixel);
+        sectionparser(p, naxes, fpixel, lpixel);
       else if(p->up.polygonset)
         {
           if(p->outpolygon==0)
@@ -814,24 +822,18 @@ iscenterfilled(struct cropparams *crp)
 {
   struct imgcropparams *p=crp->p;
 
+  size_t size;
   void *array;
-  int bitpix=p->bitpix;
-  size_t size, nulcount;
   fitsfile *ofp=crp->outfits;
-  int status=0, maxdim=10, anynul;
   long checkcenter=p->checkcenter;
+  int status=0, anynul=0, tmp_bitpix;
   long naxes[2], fpixel[2], lpixel[2], inc[2]={1,1};
 
-  uint8_t *b, *fb, *nb;
-  int16_t *s, *fs, *ns;
-  int32_t *l, *fl, *nl;
-  int64_t *L, *fL, *nL;
-  float   *f, *ff; /* isnan will check. */
-  double  *d, *fd; /* isnan will check */
+  /* If checkcenter is zero, then don't check. */
+  if(checkcenter==0) return CENTER_NOT_CHECKED;
 
   /* Get the final size of the output image. */
-  if( fits_get_img_size(ofp, maxdim, naxes, &status) )
-    gal_fits_io_error(status, NULL);
+  gal_fits_img_bitpix_size(ofp, &tmp_bitpix, naxes);
 
   /* Get the size and range of the central region to check. The +1 is
      because in FITS, counting begins from 1, not zero. It might happen
@@ -845,61 +847,23 @@ iscenterfilled(struct cropparams *crp)
   lpixel[0] = naxes[0]>checkcenter ? (naxes[0]/2+1)+checkcenter/2 : naxes[0];
   lpixel[1] = naxes[1]>checkcenter ? (naxes[1]/2+1)+checkcenter/2 : naxes[1];
 
+  /* For a check:
+  printf("naxes: %ld, %ld\nfpixel: (%ld, %ld)\nlpixel: (%ld, %ld)\n"
+         "size: %zu\n", naxes[0], naxes[1], fpixel[0], fpixel[1],
+         lpixel[0], lpixel[1], size);
+  */
+
   /* Allocate the array and read in the pixels. */
-  array=gal_fits_datatype_alloc(size, gal_fits_bitpix_to_datatype(bitpix) );
+  array=gal_fits_datatype_alloc(size, gal_fits_bitpix_to_datatype(p->bitpix));
   if( fits_read_subset(ofp, p->datatype, fpixel, lpixel, inc,
                        p->bitnul, array, &anynul, &status) )
     gal_fits_io_error(status, NULL);
-
-  /* Depending on bitpix, check the central pixels of the image. */
-  nulcount=0;
-  switch(bitpix)
-    {
-    case BYTE_IMG:
-      nb=p->bitnul;
-      fb=(b=array)+size;
-      do if(*b==*nb) ++nulcount; while(++b<fb);
-      break;
-
-    case SHORT_IMG:
-      ns=p->bitnul;
-      fs=(s=array)+size;
-      do if(*s==*ns) ++nulcount; while(++s<fs);
-      break;
-
-    case LONG_IMG:
-      nl=p->bitnul;
-      fl=(l=array)+size;
-      do if(*l==*nl) ++nulcount; while(++l<fl);
-      break;
-
-    case LONGLONG_IMG:
-      nL=p->bitnul;
-      fL=(L=array)+size;
-      do if(*L==*nL) ++nulcount; while(++L<fL);
-      break;
-
-    case FLOAT_IMG:
-      ff=(f=array)+size;
-      do if(isnan(*f)) ++nulcount; while(++f<ff);
-      break;
-
-    case DOUBLE_IMG:
-      fd=(d=array)+size;
-      do if(isnan(*d)) ++nulcount; while(++d<fd);
-      break;
-
-    default:
-      error(EXIT_FAILURE, 0, "in iscenterfilled, the bitbix is not "
-            "recognized! This is not possible by the user, so it is a "
-            "a bug. Please contact us so we can correct it");
-    }
   free(array);
 
-  if(nulcount==size)
-    return 0;
-  else
-    return 1;
+  /* CFITSIO already checks if there are any blank pixels. If there are,
+     then `anynul' will be 1, if there aren't it will be 0. So the output
+     of this function is just the inverse of that number. */
+  return !anynul;
 }
 
 
@@ -928,8 +892,8 @@ printlog(struct imgcropparams *p)
 {
   size_t i;
   FILE *logfile;
-  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
   struct imgcroplog *log=p->log;
+  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
   size_t numfiles=0, numcentfilled=0, numstitched=0;
 
   /* Only for a catalog are these statistics worth it! */
@@ -937,7 +901,7 @@ printlog(struct imgcropparams *p)
     for(i=0;log[i].name;++i)
       if(log[i].numimg)
         {
-          if(log[i].centerfilled || p->keepblankcenter)
+          if(log[i].centerfilled)
             {
               ++numfiles;
               if(log[i].numimg>1)
@@ -963,16 +927,19 @@ printlog(struct imgcropparams *p)
               "# "SPACK_STRING" log file.\n"
               "# "SPACK_NAME" was run on %s#\n",
               ctime(&p->rawtime));
-      if(p->keepblankcenter==0)
-        fprintf(logfile, "# NOTE: by default images with a blank "
-                "center are deleted.\n# To keep such images, run again "
-                "with `--keepblankcenter`.\n#\n");
+      if(p->checkcenter)
+        fprintf(logfile,
+                "# The central %zu pixels were checked for blank values.\n"
+                "# NOTE: by default when the crops are defined by "
+                "their center,\n"
+                "# crops with a blank center are deleted.\n"
+                "# To keep such images, run again with `--checkcenter=0`.\n"
+                "#\n", p->checkcenter);
       fprintf(logfile,
-              "# Column numbers below start from zero.\n"
-              "# 0: Output file name.\n"
-              "# 1: Number of images used in this cropped image.\n"
-              "# 2: Are the central %zu pixels filled? (1: yes, 0: no)\n",
-              p->checkcenter);
+              "# Column 1: Output file name.\n"
+              "# Column 2: Number of images used in this cropped image.\n"
+              "# Column 3: Are the central pixels filled? (1: yes, 0: no, "
+              "%d: not checked)\n", CENTER_NOT_CHECKED);
 
       /* Then print each output's information. */
       for(i=0;log[i].name;++i)
diff --git a/bin/imgcrop/crop.h b/bin/imgcrop/crop.h
index 29c3fb6..908e87c 100644
--- a/bin/imgcrop/crop.h
+++ b/bin/imgcrop/crop.h
@@ -59,7 +59,8 @@ void
 polygonparser(struct imgcropparams *p);
 
 void
-sectionparser(char *section, long *naxes, long *fpixel, long *lpixel);
+sectionparser(struct imgcropparams *p, long *naxes,
+              long *fpixel, long *lpixel);
 
 void
 cropname(struct cropparams *crp);
diff --git a/bin/imgcrop/imgcrop.c b/bin/imgcrop/imgcrop.c
index ea358a8..61055d3 100644
--- a/bin/imgcrop/imgcrop.c
+++ b/bin/imgcrop/imgcrop.c
@@ -55,18 +55,26 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 void
 reportcrop(struct imgcroplog *log)
 {
+  char *filestatus, *msg;
   size_t outnamelen=strlen(log->name);;
-  char msg[GAL_TIMING_VERB_MSG_LENGTH_V];
+
+  /* Human readable values. */
+  filestatus = ( log->centerfilled==0
+                 ? "not created (blank center)" : "created");
 
   /* Define the output string based on the length of the output file. */
   if ( outnamelen > FILENAME_BUFFER_IN_VERB )
-    sprintf(msg, "...%s %zu %d",
+    asprintf(&msg, "...%s %s from %zu input%s.",
             &log->name[ outnamelen - FILENAME_BUFFER_IN_VERB + 3 ],
-            log->numimg, log->centerfilled);
+            filestatus, log->numimg, log->numimg > 1 ? "s" : "");
   else
-    sprintf(msg, "%-" MACROSTR(FILENAME_BUFFER_IN_VERB) "s %zu %d",
-            log->name, log->numimg, log->centerfilled);
+    asprintf(&msg, "%-" MACROSTR(FILENAME_BUFFER_IN_VERB) "s %s from %zu "
+             "input%s.", log->name, filestatus, log->numimg,
+             log->numimg > 1 ? "s" : "");
+
+  /* Print the results. */
   gal_timing_report(NULL, msg, 2);
+  free(msg);
 }
 
 
@@ -120,7 +128,7 @@ imgmodecrop(void *inparam)
                                    "the opened file");
 
           /* Remove the output image if its center was not filled. */
-          if(log->centerfilled==0 && p->keepblankcenter==0)
+          if(log->centerfilled==0)
             {
               errno=0;
               if(unlink(log->name))
@@ -207,7 +215,7 @@ wcsmodecrop(void *inparam)
             gal_fits_io_error(status, "CFITSIO could not close the "
                                      "opened file");
 
-          if(log->centerfilled==0 && p->keepblankcenter==0)
+          if(log->centerfilled==0)
             {
               errno=0;
               if(unlink(log->name))
@@ -230,11 +238,9 @@ wcsmodecrop(void *inparam)
       if(p->cp.verb) reportcrop(log);
     }
 
-  /* Wait until all other threads finish. */
+  /* Wait until all other threads finish, then return. */
   if(p->cp.numthreads>1)
     pthread_barrier_wait(crp->b);
-
-
   return NULL;
 }
 
@@ -286,8 +292,8 @@ imgcrop(struct imgcropparams *p)
           "neither the imgmode is on or the wcsmode! Please contact us "
           "so we can fix it, thanks");
 
-  /* Allocate the arrays to keep the thread and parameters for each
-     thread. */
+  /* Allocate the array of structures to keep the thread and parameters for
+     each thread. */
   errno=0;
   crp=malloc(nt*sizeof *crp);
   if(crp==NULL)
@@ -303,10 +309,9 @@ imgcrop(struct imgcropparams *p)
 
   /* Distribute the indexs into the threads (this is needed even if we
      only have one object where p->cs0 is not defined): */
-  if(p->up.catset)
-    gal_threads_dist_in_threads(p->cs0, nt, &indexs, &thrdcols);
-  else
-    gal_threads_dist_in_threads(1, nt, &indexs, &thrdcols);
+  gal_threads_dist_in_threads(p->up.catset ? p->cs0 : 1, nt,
+                              &indexs, &thrdcols);
+
 
   /* Run the job, if there is only one thread, don't go through the
      trouble of spinning off a thread! */
@@ -345,10 +350,13 @@ imgcrop(struct imgcropparams *p)
       pthread_barrier_destroy(&b);
     }
 
+
   /* Print the log file: */
-  if(p->cp.nolog==0)
+  if(!p->cp.nolog)
     printlog(p);
 
+
+  /* Clean up. */
   free(crp);
   free(indexs);
 }
diff --git a/bin/imgcrop/main.h b/bin/imgcrop/main.h
index 1096bbd..8e92004 100644
--- a/bin/imgcrop/main.h
+++ b/bin/imgcrop/main.h
@@ -51,6 +51,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #define STRINGIFY(x) #x
 #define MACROSTR(x) STRINGIFY(x)
 #define FILENAME_BUFFER_IN_VERB 30
+#define CENTER_NOT_CHECKED      -1
 
 
 
diff --git a/bin/imgcrop/ui.c b/bin/imgcrop/ui.c
index 5379942..475bbf2 100644
--- a/bin/imgcrop/ui.c
+++ b/bin/imgcrop/ui.c
@@ -29,6 +29,7 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 #include <string.h>
 #include <fitsio.h>
 
+#include <gnuastro/wcs.h>
 #include <gnuastro/fits.h>
 #include <gnuastro/txtarray.h>
 
@@ -362,23 +363,17 @@ sanitycheck(struct imgcropparams *p)
   struct gal_commonparams *cp=&p->cp;
 
 
-
-  /* checkcenter is odd: */
-  if(p->checkcenter%2==0)
-    p->checkcenter+=1;
-
-
-
   /* Width and checkcenter are odd */
   if(p->iwidth[0]<3)
     error(EXIT_FAILURE, 0, "--iwidth has to be 3 or more pixels");
   else if(p->iwidth[0]%2==0)
-      p->iwidth[0]+=1;
+    error(EXIT_FAILURE, 0, "the given value to `iwidth' (%ld) has to "
+          "be an odd number (the pixel corresponding to the desired "
+          "coordinate to be in the center)", p->iwidth[0]);
   p->iwidth[1]=p->iwidth[0];
-  if(p->checkcenter<3)
-    error(EXIT_FAILURE, 0, "--checkcenter has to be 3 or more pixels");
-  else if(p->checkcenter%2==0)
-    p->checkcenter+=1;
+  if(p->checkcenter && p->checkcenter%2==0)
+    error(EXIT_FAILURE, 0, "`checkcenter' has to be an odd number. The "
+          "current value is %zu", p->checkcenter);
 
 
 
@@ -614,6 +609,7 @@ preparearrays(struct imgcropparams *p)
                                      p->hstartwcs, p->hendwcs);
       if(img->wcs)
         {
+          gal_wcs_decompose_pc_cdelt(img->wcs);
           status=wcshdo(0, img->wcs, &img->nwcskeys, &img->wcstxt);
           if(status)
             error(EXIT_FAILURE, 0, "wcshdo ERROR %d: %s", status,
@@ -665,7 +661,8 @@ preparearrays(struct imgcropparams *p)
   /* Report timing: */
   if(p->cp.verb)
     {
-      sprintf(msg, "Read metadata of %zu images.", p->numimg);
+      sprintf(msg, "Read metadata of %zu image%s.", p->numimg,
+              p->numimg>1 ? "s" : "");
       gal_timing_report(&t1, msg, 1);
     }
 }
diff --git a/bin/imgcrop/wcsmode.c b/bin/imgcrop/wcsmode.c
index 0072d9a..d572e2a 100644
--- a/bin/imgcrop/wcsmode.c
+++ b/bin/imgcrop/wcsmode.c
@@ -465,12 +465,13 @@ radecoverlap(struct cropparams *crp)
 {
   double *d, *fd;
   double *i, *s, *c;                /* for clear viewing. */
+  struct imgcropparams *p=crp->p;
 
   /* First check if the four sides of the crop box are in the image.*/
   fd=(d=crp->corners)+8;
-  s=crp->p->imgs[crp->imgindex].sized;
-  i=crp->p->imgs[crp->imgindex].corners;
-  c=crp->p->imgs[crp->imgindex].equatorcorr;
+  s=p->imgs[crp->imgindex].sized;
+  i=p->imgs[crp->imgindex].corners;
+  c=p->imgs[crp->imgindex].equatorcorr;
   do
     {
       if( radecinimg(d, i, s, c) ) return 1;
@@ -483,7 +484,7 @@ radecoverlap(struct cropparams *crp)
   s=crp->sized;
   i=crp->corners;
   c=crp->equatorcorr;
-  fd=(d=crp->p->imgs[crp->imgindex].corners)+8;
+  fd=(d=p->imgs[crp->imgindex].corners)+8;
   do
     {
       if( radecinimg(d, i, s, c) ) return 1;
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 4186a72..f9de680 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -6437,104 +6437,120 @@ image processing, see @ref{Crop section syntax}.
 
 @node ImageCrop modes, Crop section syntax, ImageCrop, ImageCrop
 @subsection ImageCrop modes
-In order to be as comprehensive as possible, ImageCrop has two major
-modes of operation listed below.
+In order to be as comprehensive as possible, ImageCrop has two major modes
+of operation, using pixel coordinates, or the world coordinate system (WCS)
+coordinates. In each mode, there are multiple ways to define the crop(s):
+by center, or from vertices. Here, the options that define each specific
+mode are also mentioned as part of each class. For the full list of
+options, please see @ref{Invoking astimgcrop}.
+
+In all cases except the @option{--section} option, the values/coordinates
+are read as floating point numbers (not integers). When the crop is defined
+by its center, the respective (integer) central pixel position will be
+found internally according to the FITS standard (where the center of a
+pixel is defined to be an integer). To have this pixel positioned in the
+center of the cropped region, the final cropped region must have (in Image
+mode), or will have (in WCS mode) an add number of pixels.
 
 @table @asis
 @item Image
-The image mode uses the pixel coordinates. Depending on your command
-line options, this mode consists of three sub-modes. In image mode,
-only one image may be input.
address@hidden
-
address@hidden
-Catalog (multiple crops). Coordinates are read from a text file. The
address@hidden and @option{--ycol} columns in the catalog are
-interpreted as the center of a square crop box whose width is
-specified with the @option{--iwidth} option in pixels. Since the given
-pixel has to be on the center, the width has to be an odd number, so
-if you give an even number for the width, it will be added by one. If
-a catalog file name is provided (with @option{--imagemode} activated
-of course) this mode will be used.
-
address@hidden
-Center (one crop). The box center is given on the command-line with
-the @option{--xc} and @option{--yc} parameters. The image width is
-similar to above.
-
address@hidden
-Section (one crop). You can specify the section of pixels along each
-axis in the image which you want to be cropped with the
address@hidden option. See @ref{Crop section syntax} for a full
-explanation on the syntax of specifying the desired region.
address@hidden itemize
+In image mode, ImageCrop uses the pixel coordinates/positions (instead of
+world coordinates). In image mode, only one image may be input. The crop(s)
+can be defined in multiple ways as listed below.
 
-The latter two cases will only have one crop box. In both cases,
-ImageCrop will go into the image mode, irrespective of calling
address@hidden or the default mode. In the first two cases, since
-you specify a central pixel, the crop box will be a square with an odd
-number of pixels on the side, so your desired pixel sits right in the
-center, see @ref{Blank pixels} on how to disable this for cases when
-the box exceeds the image size.
address@hidden @asis
address@hidden Center of multiple crops (in a catalog)
+The center of (possibly multiple) crops are read from a text file. A
+catalog can also contain WCS coordinates, so @option{--imgmode} has to be
+called/activated. The @option{--xcol} and @option{--ycol} columns in the
+catalog are interpreted as the center of a square crop with a width of
address@hidden pixels (an odd number). The columns can contain any
+floating point value.
+
address@hidden Center of a single crop (on the command-line)
+The center of the crop is given on the command-line with the @option{--xc}
+and @option{--yc} options. The crop width is specified by the
address@hidden option. The given coordinates can be any floating point
+and the width has to be an odd integer, see the explanations above.
+
address@hidden Vertices of a single crop
+In Image mode there are two options to define the vertices of a region to
+crop: @option{--section} and @option{--polygon}. The former is lower-level
+(doesn't accept floating point vertices, and only a rectangular region can
+be defined), it is also only available in Image mode. Please see @ref{Crop
+section syntax} for a full description of this method.
+
+The latter option (@option{--polygon}) is a higher-level method to define
+any convex polygon (with any number of vertices) with floating point
+values. Please see the description of this option in @ref{Invoking
+astimgcrop} for its syntax. It is available in both Image and WCS modes,
+hence, to read the vertices as pixel coordinates, @option{--imgmode} has to
+be called/activated.
address@hidden table
 
 @item WCS
-The Right ascension (RA) and Declination (Dec) of the objects in a
-catalog is used to define the central position of each postage
-stamp. In this mode, the width (@option{--wwidth}) is read in units of
-arc seconds and multiple images (tiles in a survey) can be input. If
-the objects are closer to the edge of the image than half the required
-width, other tiles (if they are present in the input files) are used
-to fill the empty space. The square output cropped box will have an
-odd number of pixels on the side.
-
-In this mode, the input images do not necessarily have to be the same
-size, each individual tile can even be smaller than the final crop. In
-any case, any part of any of the input images which overlaps with the
-desired region will be used in the crop. Note that if there is an over
-lap, the pixels from the last input image read are going to be
-used. The input images all just have to be aligned with the celestial
-coordinates, see the caution note below.
-
-Similar to the image mode, there are two sub-modes:
-
address@hidden
-
address@hidden
-Catalog (multiple crops). Similar to catalog mode in image mode. The
-RA and Dec column should be specified in the catalog (@option{--racol}
-and @option{--deccol}).
+Use the World Coordinate System (WCS) information to define the crop, not
+pixel coordinates. In this mode, the width (@option{--wwidth}) is read in
+units of arc-seconds and multiple images (tiles in a survey) can be
+input. When the cropped region (defined by center or vertices) lies
+overlaps with multiple of the input images/tiles, the overlapping regions
+will be taken from the respective input (they will be stitched in the
+crop).
+
+In this mode, the input images do not necessarily have to be the same size,
+they just need to have the same orientation and pixel resolution. Currently
+only orientation along the celestial coordinates is accepted, if your input
+has a different orientation you can use ImageWarp's @option{--align} option
+to align the image before cropping it (see @ref{ImageWarp}).
+
+Each individual input image/tile can even be smaller than the final
+crop. In any case, any part of any of the input images which overlaps with
+the desired region will be used in the crop. Note that if there is an over
+lap in the input images/tiles, the pixels from the last input image read
+are going to be used for the overlap (ImageCrop will not change pixel
+values, so it assumes your tiles have the same depth for example). There
+are multiple ways to define your cropped region as listed below.
 
address@hidden
-Center (one crop). You can specify the center of only one crop box (no
-matter how many input images there are) with the options @option{--ra}
-and @option{--dec}. If it exists in the input images, it will be
-cropped similar to the catalog mode. If automatic output is triggered
-(you don't specify a file name for @option{--output}) and several of
-the input images are used to stitch and crop the region around the
-central point, the name of the first input will be used in automatic
-output, see @ref{Automatic output}.
address@hidden @asis
 
address@hidden itemize
address@hidden Center of multiple crops (in a catalog)
+Similar to catalog mode in image mode, but @option{--wcsmode} has to be
+activated. The central RA and Dec value for each crop will be read from the
address@hidden and @option{--deccol} columns of the input catalog. The
+square cropped box will have an odd number of pixels.
+
address@hidden Center of a single crop (on the command-line)
+You can specify the center of only one crop box with the @option{--ra} and
address@hidden options. If it exists in the input images, it will be
+cropped similar to the catalog mode.
+
address@hidden Vertices of a single crop
+The @option{--polygon} option is a high-level method to define any convex
+polygon (with any number of vertices). Please see the description of this
+option in @ref{Invoking astimgcrop} for its syntax. It is available in both
+Image and WCS modes, hence, to read the vertices as RA and Dec coordinates,
address@hidden has to be called/activated.
address@hidden table
 
 @cartouche
 @noindent
 @strong{CAUTION:} In WCS mode, the image has to be aligned with the
-celestial coordinates, such that the first FITS axis is parallel
-(opposite direction) to the Right Ascension (RA) while the second FITS
-axis is parallel to the declination. If these conditions aren't met
-for an image, ImageCrop will warn you and abort. You have to use other
-tools to transform the image to the correct directions.
+celestial coordinates, such that the first FITS axis is parallel (opposite
+direction) to the Right Ascension (RA) and the second FITS axis is parallel
+to the declination. If these conditions aren't met for an image, ImageCrop
+will warn you and abort. You can use ImageWarp's @option{--align} option to
+align the input image with these coordinates, see @ref{ImageWarp}.
 @end cartouche
 
 @end table
 
-In short, if you don't specify a catalog, you have to specify box
-coordinates manually on the command-line. When you do specify a
-catalog, ImageCrop has to be in one of the two major modes
-(@option{--imgmode} or @option{--wcsmode}). Note that the single crop
-box parameters specified in the sub-modes will not be written to or
-read from the configuration file, they have to be specified on each
-execution.
+As a summary, if you don't specify a catalog, you have to define the
+cropped region manually on the command-line. Other than the
address@hidden option, the other methods to define a single crop are
+uniqe to each mode, so the mode options (@option{--imgmode} or
address@hidden) will be ignored. When using a catalog, or
address@hidden, the modes have to be specified to correctly interpret
+the values.
 
 
 @node Crop section syntax, Blank pixels, ImageCrop modes, ImageCrop
@@ -6652,7 +6668,7 @@ $ astimgcrop -I catalog.txt image.fits
 $ astimgcrop -W catalog.txt /mnt/data/COSMOS/*_drz.fits
 $ astimgcrop --section=10:*-10,10:*-10 --hdu=2 image.fits
 $ astimgcrop --ra=189.16704 --dec=62.218203 goodsnorth.fits
-$ astimgcrop --xc=568.342 --yc=2091.719 --iwidth=200 image.fits
+$ astimgcrop --xc=568.342 --yc=2091.719 --iwidth=201 image.fits
 @end example
 
 @noindent
@@ -6661,11 +6677,10 @@ shown above with @file{ASTRdata ...}. You can use shell 
expansions, for
 example @command{*} for this if you have lots of images in WCS mode. If the
 crop box centers are in a catalog, you also have to provide the catalog
 name as an argument. Alternatively, you have to provide the crop box
-parameters with command-line options. As in all Gnuastro programs, when an
-output is not explicitly set with the @option{--output} option, the output
-filename will be set automatically, see @ref{Automatic output}. For the
-full list of general options to all Gnuastro programs (including
-ImageCrop), please see @ref{Common options}.
+parameters with command-line options. See @ref{ImageCrop output} for how
+the output file name(s) can be specified. For the full list of general
+options to all Gnuastro programs (including ImageCrop), please see
address@hidden options}.
 
 Floating point numbers can be used to specify the crop region (except the
 @option{--section} option, see @ref{Crop section syntax}). In such cases,
@@ -6681,6 +6696,13 @@ a pixel is at integer multiples of @mymath{0.5}). So you 
should run
 ImageWarp with @option{--translate=-0.482,0} and then crop the warped image
 with @option{--section=13:81}.
 
+There are two ways to define the cropped region: with its center or its
+vertices. See @ref{ImageCrop modes} for a full description. In the former
+case, ImageCrop can check if the central region of the cropped image is
+indeed filled with data or is blank (see @ref{Blank pixels}), and not
+produce any output when the center is blank, see the description under
address@hidden for more.
+
 @cindex Asynchronous thread allocation
 When in catalog mode, ImageCrop will run in parallel unless you set
 @option{--numthreads=1}, see @ref{Threads in Gnuastro}. Note that when
@@ -6766,27 +6788,30 @@ the syntax required for this input.
 
 @item -l
 @itemx --polygon
-(@option{=STR}) String of crop polygon vertices. Note that currently
-only convex polygons should be used. In the future we will make it
-work for all kinds of polygons. Convex polygons are polygons that do
-not have an internal angle more than 180 degrees. This option can be
-used both in the image and WCS modes. The rectangular region that
-completely encompasses the polygon will be kept and all the pixels
-that are outside of it will be removed.
-
-The syntax for the polygon vertices is similar to and simpler than
-that for @option{--section}. In short, the dimensions of each
-coordinate are separated by a comma (@key{,}) and each vertice is
-separated by a colon (@key{:}). You can define as many vertices as you
-like. If you would like to use space characters between the dimensions
-and vertices to make them more human-readable, then you have to put
-the value to this option in double quotation marks.
-
-For example let's assume you want to work on the deepest part of the
+(@option{=STR}) String of crop polygon vertices. Note that currently only
+convex polygons should be used. In the future we will make it work for all
+kinds of polygons. Convex polygons are polygons that do not have an
+internal angle more than 180 degrees. This option can be used both in the
+image and WCS modes, see @ref{ImageCrop modes}. The cropped image will be
+the size of the rectangular region that completely encompasses the
+polygon. By default all the pixels that are outside of the polygon will be
+set as blank values (see @ref{Blank pixels}). However, if
address@hidden is called all pixels interal to the vertices will be
+set to blank.
+
+The syntax for the polygon vertices is similar to, and simpler than, that
+for @option{--section}. In short, the dimensions of each coordinate are
+separated by a comma (@key{,}) and each vertice is separated by a colon
+(@key{:}). You can define as many vertices as you like. If you would like
+to use space characters between the dimensions and vertices to make them
+more human-readable, then you have to put the value to this option in
+double quotation marks.
+
+For example, let's assume you want to work on the deepest part of the
 WFC3/IR images of Hubble Space Telescope eXtreme Deep Field
-(HST-XDF). @url{https://archive.stsci.edu/prepds/xdf/, According to
-the address@hidden@url{https://archive.stsci.edu/prepds/xdf/}} the
-deepest part is contained within the coordinates:
+(HST-XDF). @url{https://archive.stsci.edu/prepds/xdf/, According to the
address@hidden@url{https://archive.stsci.edu/prepds/xdf/}} the deepest
+part is contained within the coordinates:
 
 @example
 [ (53.187414,-27.779152), (53.159507,-27.759633),
@@ -6794,14 +6819,14 @@ deepest part is contained within the coordinates:
 @end example
 
 They have provided mask images with only these pixels in the WFC3/IR
-images, but what if you also need to work on the same region in the
-full resolution ACS images? Also what if you want to use the CANDELS
-data for the shallow region? Running ImageCrop with @option{--polygon}
-will easily pull out this region of the image for you irrespective of
-the resolution (if you have set the operating mode to WCS mode in your
-nearest configuration file, there is no need for @option{--wcsmode},
-you may also provide many FITS image or tiles and ImageCrop will
-stitch them all):
+images, but what if you also need to work on the same region in the full
+resolution ACS images? Also what if you want to use the CANDELS data for
+the shallow region? Running ImageCrop with @option{--polygon} will easily
+pull out this region of the image for you irrespective of the
+resolution. If you have set the operating mode to WCS mode in your nearest
+configuration file (see @ref{Configuration files}), there is no need to
+call @option{--wcsmode} on the command line. You may also provide many FITS
+images/tiles and ImageCrop will stitch them to produce this cropped region:
 
 @example
 $ astimgcrop --wcsmode desired-filter-image(s).fits        \
@@ -6844,13 +6869,13 @@ the vertical axis.
 
 @item -a
 @itemx --iwidth
-(@option{=INT}) Width the square box to crop in image mode in units of
-pixels. In order for the chosen central pixel to be in the center of
-the cropped image, the final width has to be an odd number, therefore
-if the value to this option is an even number, the final crop width
-will be one pixel larger in each dimension. If you want an even sided
-crop box, use the @option{--section} option to specify the boundaries
-of the box, see @ref{Crop section syntax}.
+(@option{=INT}) Width of the cropped region in units of pixels when the
+crop is defined by its center in Image mode (see @ref{ImageCrop modes}). In
+order for the chosen central pixel to be in the center of the cropped
+image, this option only accepts an odd number (an error will be given if
+its even). If you want an even sided crop, you can run ImageCrop afterwards
+with @option{--section=":*-1,:*-1"} or @option{--section=2:,2:} (depending
+on which side you don't need), see @ref{Crop section syntax}.
 
 @item -f
 @itemx --racol
@@ -6876,18 +6901,26 @@ Output options:
 @item -c
 @itemx --checkcenter
 @cindex Check center of crop
-(@option{=INT}) Box size of region in the center of the image to check
-in units of pixels. This is only used in WCS mode. Because surveys
-don't often have a clean square or rectangle shape, some of the pixels
-on the sides of the surveys don't have any data and are commonly
-filled with zero valued pixels.
-
-If the RA and Dec of any of the targets specified in the catalog fall
-in such regions, that cropped image will be useless! Therefore with
-this option, you can specify a width of a small box (3 pixels is often
-good enough) around the central pixel of the cropped image. If all the
-pixels in this small box have the value of zero, no cropped image will
-be created and this object will be flagged in the final log file.
+(@option{=INT}) Box width (odd number of pixels) of region in the center of
+the image to check for blank values. If the value to this option is zero,
+no checking is done. This option is only relevant when the cropped
+region(s) are defined by their center (not by the vertices, see
address@hidden modes}). If any of the pixels in this central region of a
+crop (defined by its center) are blank, then it will not be created.
+
+Because survey regions don't often have a clean square or rectangle shape,
+some of the pixels on the sides of the survey FITS image don't commonly
+have any data and are blank (see @ref{Blank pixels}). So when the catalog
+was not generated from the input image, it often happens that the image
+does not have data over some of the points.
+
+When the given center of a crop falls in such regions and this option has a
+non-zero, odd value, no crop will be created. Therefore with this option,
+you can specify a width of a small box (3 pixels is often good enough)
+around the central pixel of the cropped image. You can check which crops
+were created and which weren't from the command-line (if @option{--quiet}
+was not called, see @ref{Operating modes}), or in ImageCrop's log file (see
address@hidden output}).
 
 @item -p
 @itemx --suffix
@@ -6937,32 +6970,43 @@ Operate in WCS mode. See explanations for 
@option{--imgmode}.
 
 @node ImageCrop output,  , ImageCrop options, Invoking astimgcrop
 @subsubsection ImageCrop output
-When a catalog is given, the value of @option{--output} (see
address@hidden options}) will be seen as the directory to store the
-output cropped images. In such cases, the outputs will consist of two
-parts: a variable part (the row number of each target starting from 1)
-along with a fixed string which you can set with the @option{--suffix}
-option. Note that in catalog mode, only one image can be input.
-
-When the crop box is specified on the command-line, the value to
address@hidden will be used as a file name. If no output is
-specified or if it is a directory, the output file name will follow
-the automatic output names of Gnuastro, see @ref{Automatic output}
-for the input image.
-
-The header of each output cropped image will contain the names of the
-input image(s) it was cut from. If a name is longer than the 70
-character space that the FITS standard allows for header keyword
-values, the name will be cut into several keywords from the nearest
-slash (@key{/}). The keywords have the following format:
address@hidden Where @command{n} is the number of the image used in
-this crop and @command{m} is the part of the name. Following the name
-is another keyword named @command{ICFnPIX} which shows the pixel range
-from that input image in the same syntax as @ref{Crop section syntax}.
+
+The value given to @option{--output} option will depend on how many crops
+were created, see @ref{ImageCrop modes}:
+
address@hidden
address@hidden
+When a catalog is given, the value of the @option{--output} (see
address@hidden options}) will be read as the directory to store the output
+cropped images. Hence if it doesn't alread exist, ImageCrop will abort with
+an error of a ``No such file or directory'' error. The crop file names will
+consist of two parts: a variable part (the row number of each target
+starting from 1) along with a fixed string which you can set with the
address@hidden option.
+
address@hidden
+When only one crop is desired, the value to @option{--output} will be read
+as a file name. If no output is specified or if it is a directory, the
+output file name will follow the automatic output names of Gnuastro, see
address@hidden output}: The string given to @option{--suffix} will be
+replaced with the @file{.fits} suffix of the input.
address@hidden itemize
+
+The header of each output cropped image will contain the names of the input
+image(s) it was cut from. If a name is longer than the 70 character space
+that the FITS standard allows for header keyword values, the name will be
+cut into several keywords from the nearest slash (@key{/}). The keywords
+have the following format: @command{ICFn_m} (for ImageCrop File). Where
address@hidden is the number of the image used in this crop and @command{m} is
+the part of the name (it can be broken into multiple keywords). Following
+the name is another keyword named @command{ICFnPIX} which shows the pixel
+range from that input image in the same syntax as @ref{Crop section
+syntax}. So this string can be directly given to the @option{--section}
+option later.
 
 Once done, a log file will be created in the current directory named
address@hidden For each input row, this file will have three
-columns:
address@hidden This file will have three columns and the same
+number of rows as the number of cropped images.
 
 @enumerate
 @item
@@ -6970,17 +7014,20 @@ The cropped image file name for that row.
 @item
 The number of input images that were used to create that image.
 @item
-A @code{0} if the central few pixels (value to the
address@hidden option) are blank and @code{1} otherwise.
+A @code{0} if the central few pixels (value to the @option{--checkcenter}
+option) are blank and @code{1} if they aren't. When the crop was not
+defined by its center (see @ref{ImageCrop modes}), or
address@hidden was given a value of 0 (see @ref{Invoking
+astimgcrop}), the center will not be checked and this column will be given
+a value of @code{-1}.
 @end enumerate
 
-There are also comments on the top explaining basic information about
-the run. If the log file cannot be created (for example you don't have
-write permission in the directory you are running ImageCrop in) or you
-have specifically asked for no log file (with the @option{--nolog}
-option), then a log file will not be created (unless
address@hidden is called). The same columns will be printed in
-verbose mode on the command-line for each row.
+There are also comments on the top of the log file explaining basic
+information about the run and descriptions for the columns. If the log file
+cannot be created (for example you don't have write permission in the
+directory you are running ImageCrop in) or you have specifically asked for
+no log file (with the @option{--nolog} option), then a log file will not be
+created (unless @option{--individual} is called).
 
 
 
diff --git a/tests/imgcrop/imgoutpolygon.sh b/tests/imgcrop/imgoutpolygon.sh
index edda747..a0e3668 100755
--- a/tests/imgcrop/imgoutpolygon.sh
+++ b/tests/imgcrop/imgoutpolygon.sh
@@ -52,6 +52,6 @@ if [ ! -f $execname ] || [ ! -f $img ]; then exit 77; fi
 # The number of threads is one so if CFITSIO does is not configured to
 # enable multithreaded access to files, the tests pass. It is the
 # users choice to enable this feature.
-$execname $img $cat --imgmode --zeroisnotblank --outpolygon --keepblankcenter \
+$execname $img $cat --imgmode --zeroisnotblank --outpolygon                   \
           --polygon=209,50:436.76,151:475.64,438.2:210.6,454.04:121.4,289.88  \
           --output=imgoutpolygon.fits



reply via email to

[Prev in Thread] Current Thread [Next in Thread]