gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master fd3ffac6: Warp: implemented --width and --widt


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master fd3ffac6: Warp: implemented --width and --widthinpix options like Crop
Date: Fri, 7 Oct 2022 11:48:12 -0400 (EDT)

branch: master
commit fd3ffac607e8bb639302a1a31a4b375fb20d2675
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Warp: implemented --width and --widthinpix options like Crop
    
    Until now, in Warp, we only had the '--widthinpix' option which would
    accept values in pixels. However, in some cases, the users may want to
    specify the width in units of degrees, arcminutes or arcseconds. Also,
    because Gnuastro users are already use to Crop's definitions of '--width',
    this behavior of Warp was confusing.
    
    With this commit, Warp now accepts the main width of the output through the
    '--width' option (similar to Crop), but also accepts '--widthinpix' for
    cases when the user wants to give the width in pixels (again, similar to
    Crop).
    
    This was suggested by Raul Infante-Sainz.
---
 NEWS                            |   3 +-
 bin/crop/ui.c                   |  27 +---
 bin/warp/args.h                 |  31 ++--
 bin/warp/main.h                 |   5 +-
 bin/warp/ui.c                   | 316 ++++++++++++++++++++++++----------------
 bin/warp/ui.h                   |   3 +-
 bin/warp/warp.c                 |   5 +-
 doc/gnuastro.texi               |  26 +++-
 lib/gnuastro-internal/options.h |   6 +-
 lib/options.c                   |  17 +++
 10 files changed, 271 insertions(+), 168 deletions(-)

diff --git a/NEWS b/NEWS
index 6e2a8544..9fbdebe6 100644
--- a/NEWS
+++ b/NEWS
@@ -112,7 +112,8 @@ See the end of the file for license conditions.
     options. See the "Invoking Warp" section of the book for more. This
     feature has been written by Pedram Ashofteh Ardakani.
     --center: RA, DEC of the center of the central pixel of output.
-    --widthinpix: Width of output in pixels.
+    --width: Width of output in degrees or pixels (see '--widthinpix').
+    --widthinpix: interpret values of '--width' as pixels.
     --cdelt: Pixel scale of output ('CDELTi' keywords in FITS).
     --ctype: Coordinates and projection algorithm. Default: RA/Dec and
       Gnomonic or 'TAN').
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 72038335..d053b9e4 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -528,23 +528,6 @@ ui_check_options_and_arguments(struct cropparams *p)
 /**************************************************************/
 /***************       Preparations         *******************/
 /**************************************************************/
-#define UI_WIDTH_TOO_LARGE_SIZE 50000
-static void
-ui_warning_width_is_too_large(double width, size_t dim_num,
-                              double pixwidth, double pixscale)
-{
-  error(EXIT_SUCCESS, 0, "WARNING: value %g (requested WCS-based "
-        "width along dimension %zu) translates to %.0f pixels on "
-        "this dataset! This is most probably not what you wanted! "
-        "Note that the dataset's pixel size in this dimension is "
-        "%g. If you intended this number to show the width in "
-        "pixels, please add the '--widthinpix' option", width,
-        dim_num, pixwidth, pixscale);
-}
-
-
-
-
 
 /* When the crop is defined by its center, the final width that we need
    must be in actual number of pixels (an integer). But the user's values
@@ -598,8 +581,8 @@ ui_set_img_sizes(struct cropparams *p)
           {
             /* Calculate the pixel width. */
             pwidth = warray[i]/p->pixscale[i];
-            if(pwidth<1 || pwidth>UI_WIDTH_TOO_LARGE_SIZE)
-              ui_warning_width_is_too_large(warray[i], i+1, pwidth,
+            if(pwidth<1 || pwidth>GAL_OPTIONS_WIDTH_TOO_LARGE_SIZE)
+              gal_options_width_too_large(warray[i], i+1, pwidth,
                                           p->pixscale[i]);
 
             /* Write the single valued width in WCS and the image width for
@@ -936,9 +919,9 @@ ui_preparations_to_img_mode(struct cropparams *p)
           for(i=0;i<p->width->size;++i)
             {
               pixwidth = darr[i] / pixscale[i];
-              if(pixwidth>UI_WIDTH_TOO_LARGE_SIZE)
-                ui_warning_width_is_too_large(darr[i], i+1, pixwidth,
-                                              pixscale[i]);
+              if(pixwidth>GAL_OPTIONS_WIDTH_TOO_LARGE_SIZE)
+                gal_options_width_too_large(darr[i], i+1, pixwidth,
+                                            pixscale[i]);
               darr[i]=pixwidth;
             }
           free(pixscale);
diff --git a/bin/warp/args.h b/bin/warp/args.h
index 47b90f61..bfc17bd1 100644
--- a/bin/warp/args.h
+++ b/bin/warp/args.h
@@ -117,19 +117,32 @@ struct argp_option program_options[] =
       gal_options_parse_csv_float64
     },
     {
-      "widthinpix",
-      UI_KEY_WIDTHINPIX,
+      "width",
+      UI_KEY_WIDTH,
       "INT,INT",
       0,
-      "Output image width and height in pixels.",
+      "Output image size in both dimensions.",
       UI_GROUP_ALIGN,
-      &p->wa.widthinpix,
-      GAL_TYPE_STRING,
-      GAL_OPTIONS_RANGE_GT_0_ODD,
+      &p->width,
+      GAL_TYPE_FLOAT64,
+      GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
       gal_options_parse_csv_float64
     },
+    {
+      "widthinpix",
+      UI_KEY_WIDTHINPIX,
+      0,
+      0,
+      "--width is in pixels, not in WCS coordinates.",
+      UI_GROUP_ALIGN,
+      &p->widthinpix,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
     {
       "ctype",
       UI_KEY_CTYPE,
@@ -151,9 +164,9 @@ struct argp_option program_options[] =
       0,
       "Pixel scale of output (usually degrees/pixel).",
       UI_GROUP_ALIGN,
-      &p->cdelt,
-      GAL_TYPE_STRING,
-      GAL_OPTIONS_RANGE_GT_0,
+      &p->wa.cdelt,
+      GAL_TYPE_FLOAT64,
+      GAL_OPTIONS_RANGE_ANY,
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET,
       gal_options_parse_csv_float64
diff --git a/bin/warp/main.h b/bin/warp/main.h
index d2d82ff5..db2d5195 100644
--- a/bin/warp/main.h
+++ b/bin/warp/main.h
@@ -51,7 +51,8 @@ struct warpparams
   uint8_t         keepwcs;  /* Wrap the warped/transfomed pixels.        */
   uint8_t  centeroncorner;  /* Shift center by 0.5 before and after.     */
   double      coveredfrac;  /* Acceptable fraction of output covered.    */
-  gal_data_t       *cdelt;  /* Pixel scale of the output image.          */
+  gal_data_t       *width;  /* Width of final image.                     */
+  uint8_t      widthinpix;  /* If the given width is in units of pixels. */
   char           *gridhdu;  /* Extension to use for output's WCS.        */
   char          *gridfile;  /* File to use for output's WCS.             */
 
@@ -67,7 +68,7 @@ struct warpparams
   size_t       extinds[4];  /* Indexs of the minimum and maximum values. */
   double    outfpixval[2];  /* Pixel value of first output pixel.        */
   double         opixarea;  /* Area of output pix in units of input pix. */
-  uint8_t   nonlinearmode;  /* If warp must work in nonlinear mode.      */
+  uint8_t        wcsalign;  /* If warp must work in WCS-align mode.      */
   uint8_t  distortiontype;  /* Store distortion type in nonlinear mode.  */
 };
 
diff --git a/bin/warp/ui.c b/bin/warp/ui.c
index 5b11d2fb..319b68aa 100644
--- a/bin/warp/ui.c
+++ b/bin/warp/ui.c
@@ -354,13 +354,13 @@ ui_check_gridfile(struct warpparams *p)
           "contain 2 dimensions, but warp detected %zu dimensions",
           p->gridfile, p->gridhdu, ndim);
 
-  /* If '--widthinpix' has already been given, inform the user that it will
-     be ignored (because '--gridfile' has been given). */
-  if(wa->widthinpix)
+  /* If '--width' has already been given, inform the user that it will be
+     ignored (because '--gridfile' has been given). */
+  if(p->width)
     {
-      error(EXIT_SUCCESS, 0, "WARNING: '--widthinpix' will be ignored "
+      error(EXIT_SUCCESS, 0, "WARNING: '--width' will be ignored "
             "because '--gridfile' takes precedence");
-      gal_data_free(wa->widthinpix);
+      gal_data_free(p->width);
     }
 
   /* We don't need to free the input 'dsize' array since it will be freed
@@ -393,11 +393,185 @@ ui_check_gridfile(struct warpparams *p)
 
 
 
+static void
+ui_check_wcsalign_cdelt(struct warpparams *p)
+{
+  size_t two=2, i;
+  gal_data_t *olddata=NULL;
+  double *tmp=NULL, *cdelt=NULL;
+  gal_warp_wcsalign_t *wa=&p->wa;
+
+  /* '--cdelt' isn't given. */
+  if(!wa->cdelt)
+    {
+      /* CDELT is not given, try to deduce from WCS */
+      cdelt=gal_wcs_pixel_scale(p->input->wcs);
+      if(!cdelt)
+        error(EXIT_FAILURE, 0, "%s (hdu %s): the pixel scale couldn't "
+              "be deduced from the WCS.", p->inputname, p->cp.hdu);
+
+      /* Set CDELT to the maximum value of the dimensions. */
+      cdelt[0] = ( cdelt[0] > cdelt[1] ? cdelt[0] : cdelt[1] );
+      cdelt[1] = cdelt[0];
+      wa->cdelt=gal_data_alloc(cdelt, GAL_TYPE_FLOAT64, 1, &two, NULL, 0,
+                               p->cp.minmapsize, p->cp.quietmmap, NULL, NULL,
+                               NULL);
+    }
+
+  /* --cdelt is given. */
+  else
+    {
+      /* CDELT is given, make sure there are no more than two values */
+      if(wa->cdelt->size > 2)
+        error(EXIT_FAILURE, 0, "%zu values given to '--cdelt', "
+              "however this option takes no more than 2 values",
+              wa->cdelt->size);
+
+      /* If only one value given to CDELT, use it for both dimensions. */
+      if(wa->cdelt->size == 1)
+        {
+          olddata=wa->cdelt; tmp=olddata->array;
+          wa->cdelt=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1,
+                                   &two, NULL, 0,
+                                   p->cp.minmapsize,
+                                   p->cp.quietmmap, NULL, NULL,
+                                   NULL);
+          cdelt=p->wa.cdelt->array;
+          cdelt[0]=cdelt[1]=tmp[0];
+          gal_data_free(olddata);
+        }
+
+      /* Check if the CDELT is in a reasonable range of degrees (in case
+         '--widthinpix' wasn't given). */
+      if(p->widthinpix==0)
+        {
+          cdelt=wa->cdelt->array;
+          for(i=wa->cdelt->size; i--;)
+            if(cdelt[i]>0.01)
+              error(EXIT_SUCCESS, 0, "WARNING: CDELT on dimension %zu has "
+                    "the unusual value of %f degrees. If you meant to define "
+                    "CDELT in arcseconds please use: '--cdelt=%g/3600'", i,
+                    cdelt[i], cdelt[i]);
+        }
+    }
+}
+
+
+
+
+
+static void
+ui_check_wcsalign_width(struct warpparams *p)
+{
+  /* Low-level variable (used in other variable definitions). */
+  gal_warp_wcsalign_t *wa=&p->wa;
+
+  /* High-level variables. */
+  gal_data_t *tmpw;
+  size_t i, two=2, stemp, *sarray=NULL;
+  double *cdelt=wa->cdelt->array, *darray, *tdarray;
+
+  /* Make sure only two values are given. */
+  if( p->width->size > 2 )
+    error(EXIT_FAILURE, 0, "%zu value(s) given to '--width', however "
+          "this option takes 1 or two values on a 2D image: the output "
+          "image width and height in WCS units (if you want to enter "
+          "the width in pixels, please also call '--widthinpix'). If a "
+          "single value is given the size will be a square", p->width->size);
+
+  /* If a single value is given, use it for both dimensions. */
+  if(p->width->size==1)
+    {
+      /* Allocate a new one and add the values. */
+      tmpw=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1, &two, NULL, 0,
+                          p->cp.minmapsize, p->cp.quietmmap,
+                          NULL, NULL, NULL);
+
+      /* Put the values in. */
+      tdarray=tmpw->array;
+      darray=p->width->array;
+      tdarray[0]=tdarray[1]=darray[0];
+
+      /* Clean up and set the new pointer. */
+      gal_data_free(p->width);
+      p->width=tmpw;
+    }
+
+
+  /* When '--widthinpix' is called we can directly use the values. */
+  darray=p->width->array;
+  if(p->widthinpix)
+    {
+      /* Make sure they are integers. */
+      if( darray[0]!=ceil(darray[0]) || darray[1]!=ceil(darray[1]) )
+        error(EXIT_FAILURE, 0, "value to '--width' must be integers, "
+              "but they are: %g, %g", darray[0], darray[1]);
+      p->width=gal_data_copy_to_new_type(p->width, GAL_TYPE_SIZE_T);
+    }
+  else
+    {
+      /* Allocate the size_t array to keep the final values. */
+      tmpw=gal_data_alloc(NULL, GAL_TYPE_SIZE_T, 1, &two, NULL, 0,
+                          p->cp.minmapsize, p->cp.quietmmap,
+                          NULL, NULL, NULL);
+
+      /* Convert the given values to pixels using the pixel scale
+         information, and make sure they are reasonable. */
+      sarray=tmpw->array;
+      for(i=0;i<p->width->size;++i)
+        {
+          sarray[i] = darray[i]/cdelt[i];
+          if(sarray[i]>GAL_OPTIONS_WIDTH_TOO_LARGE_SIZE)
+            gal_options_width_too_large(darray[i], i+1, sarray[i],
+                                        cdelt[i]);
+        }
+
+      /* Free the old dataset and use the new one. */
+      gal_data_free(p->width);
+      p->width=tmpw;
+    }
+
+  /* Image size must be ODD */
+  sarray=p->width->array;
+  if( sarray[0]%2==0 || sarray[1]%2==0 )
+    {
+      /* Let the user know that we are updating the output size (only
+         relevant if the user directly requested pixel coordinates). */
+      if(p->widthinpix)
+        error(EXIT_SUCCESS, 0, "WARNING: '--widthinpix' must be odd: "
+              "updating %zux%zu to %zux%zu", sarray[0], sarray[1],
+              sarray[0]%2 ? sarray[0] : sarray[0]+1,
+              sarray[1]%2 ? sarray[1] : sarray[1]+1);
+
+      /* Keep the final values. */
+      if(sarray[0]%2==0) sarray[0]+=1;
+      if(sarray[1]%2==0) sarray[1]+=1;
+    }
+
+  /* To keep the later steps consistent with the C ordering of
+     dimensions, we'll swap the fast and slow axis from FITS (which has
+     the same convention as FORTRAN), because the user sees a FITS
+     file. In an aligned image, sarray[0] is the horizontal axis and
+     sarray[1] the vertical one.
+
+     NAXIS1 -> dsize[1] -> horizontal axis
+     NAXIS2 -> dsize[0] -> vertical axis        */
+  stemp=sarray[0]; sarray[0]=sarray[1]; sarray[1]=stemp;
+
+  /* Put the final widthinpix dataset into the warpalign structure. */
+  p->wa.widthinpix=p->width;
+  p->width=NULL;
+}
+
+
+
+
+
 static void *
 ui_check_options_and_arguments_wcsalign(struct warpparams *p)
 {
+  size_t two=2, indim=0;
   gal_warp_wcsalign_t *wa=&p->wa;
-  size_t two=2, *sarray=NULL, stemp, indim=0;
   double *icenter=NULL, *iwidth=NULL, *imin=NULL, *imax=NULL, *tmp=NULL;
 
   /* Copy necessary parameters for the nonlinear warp (independent of
@@ -415,9 +589,6 @@ ui_check_options_and_arguments_wcsalign(struct warpparams 
*p)
       return NULL;
     }
 
-  /* Not using a WCS file, so put cdelt into the non-linear structure. */
-  p->wa.cdelt=p->cdelt;
-
   /* Sanity check user's possibly given '--center'. */
   if(wa->center)
     {
@@ -455,50 +626,11 @@ ui_check_options_and_arguments_wcsalign(struct warpparams 
*p)
       free(iwidth);
     }
 
-  /* If the output width is given, make sure it has exactly two
-     values for width and height. */
-  if(wa->widthinpix)
-    {
-      if( wa->widthinpix->size != 2 )
-        error(EXIT_FAILURE, 0, "%zu value(s) given to '--widthinpix', "
-              "however this option takes exactly 2 values as the "
-              "output image width and height in pixels",
-              wa->widthinpix->size);
-
-      /* Image size must be of type size_t, but first we should make sure
-         the user didn't give a floating-point value. */
-      tmp=wa->widthinpix->array;
-      if( tmp[0]!=ceil(tmp[0]) || tmp[1]!=ceil(tmp[1]) )
-        error(EXIT_FAILURE, 0, "value to '--widthinpix' must be "
-              "integers, but they are: %g, %g", tmp[0], tmp[1]);
-      wa->widthinpix=gal_data_copy_to_new_type(wa->widthinpix,
-                                               GAL_TYPE_SIZE_T);
-
-      /* Image size must be ODD */
-      sarray=wa->widthinpix->array;
-      if( sarray[0]%2==0 || sarray[1]%2==0 )
-        {
-          /* Let the user know that we are updating the output size. */
-          error(EXIT_SUCCESS, 0, "WARNING: '--widthinpix' must be odd: "
-                "updating %zux%zu to %zux%zu", sarray[0], sarray[1],
-                sarray[0]%2 ? sarray[0] : sarray[0]+1,
-                sarray[1]%2 ? sarray[1] : sarray[1]+1);
-
-          /* Keep the final values. */
-          if(sarray[0]%2==0) sarray[0]+=1;
-          if(sarray[1]%2==0) sarray[1]+=1;
-        }
-
-      /* To keep the later steps consistent with the C ordering of
-         dimensions, we'll swap the fast and slow axis from FITS (which has
-         the same convention as FORTRAN), because the user sees a FITS
-         file. In an aligned image, sarray[0] is the horizontal axis and
-         sarray[1] the vertical one.
-
-         NAXIS1 -> dsize[1] -> horizontal axis
-         NAXIS2 -> dsize[0] -> vertical axis        */
-      stemp=sarray[0]; sarray[0]=sarray[1]; sarray[1]=stemp;
-    }
+  /* Prepare the output pixel scale and width. Note that the pixel scale
+     should be checked before the width because the width may need the
+     pixel scale. */
+  ui_check_wcsalign_cdelt(p);
+  if(p->width) ui_check_wcsalign_width(p);
 
   /* Check CTYPE */
   if(!wa->ctype)
@@ -516,65 +648,6 @@ ui_check_options_and_arguments_wcsalign(struct warpparams 
*p)
 
 
 
-static void
-ui_check_cdelt(struct warpparams *p)
-{
-  size_t two=2, i;
-  gal_data_t *olddata=NULL;
-  double *tmp=NULL, *cdelt=NULL;
-
-  if(!p->cdelt)
-    {
-      /* CDELT is not given, try to deduce from WCS */
-      cdelt=gal_wcs_pixel_scale(p->input->wcs);
-      if(!cdelt)
-        error(EXIT_FAILURE, 0, "%s (hdu %s): the pixel scale couldn't "
-              "be deduced from the WCS.", p->inputname, p->cp.hdu);
-
-      /* Set CDELT to the maximum value */
-      cdelt[0] = ( cdelt[0] > cdelt[1] ? cdelt[0] : cdelt[1] );
-      cdelt[1] = cdelt[0];
-      p->cdelt=gal_data_alloc(cdelt, GAL_TYPE_FLOAT64, 1, &two, NULL, 0,
-                              p->cp.minmapsize, p->cp.quietmmap, NULL, NULL,
-                              NULL);
-    }
-  else
-    {
-      /* CDELT is given, make sure there are no more than two values */
-      if(p->cdelt->size > 2)
-        error(EXIT_FAILURE, 0, "%zu values given to '--cdelt', "
-              "however this option takes no more than 2 values",
-              p->cdelt->size);
-
-      /* If only one value given to CDELT */
-      if(p->cdelt->size == 1)
-        {
-          olddata=p->cdelt; tmp=olddata->array;
-          p->cdelt=gal_data_alloc(NULL, GAL_TYPE_FLOAT64, 1,
-                                  &two, NULL, 0,
-                                  p->cp.minmapsize,
-                                  p->cp.quietmmap, NULL, NULL,
-                                  NULL);
-          cdelt=p->cdelt->array;
-          cdelt[0]=cdelt[1]=tmp[0];
-          gal_data_free(olddata);
-        }
-
-      /* Check if the CDELT is in a reasonable range of degrees */
-      cdelt=p->cdelt->array;
-      for(i=p->cdelt->size; i--;)
-        if(cdelt[i]>0.01)
-          error(EXIT_SUCCESS, 0, "WARNING: CDELT on dimension %zu has "
-                "the unusual value of %f degrees. If you meant to "
-                "define CDELT in arcseconds please use: "
-                "'--cdelt=%g/3600'", i, cdelt[i], cdelt[i]);
-    }
-}
-
-
-
-
-
 static void
 ui_check_options_and_arguments(struct warpparams *p)
 {
@@ -592,7 +665,7 @@ ui_check_options_and_arguments(struct warpparams *p)
   /* Make sure mandatory options are provided. */
   if(p->modularll==NULL && p->matrix==NULL)
     {
-      p->nonlinearmode=1;
+      p->wcsalign=1;
       if(p->wa.edgesampling==GAL_BLANK_SIZE_T)
         error(EXIT_FAILURE, 0, "no '--edgesampling' provided");
     }
@@ -622,13 +695,10 @@ ui_check_options_and_arguments(struct warpparams *p)
 
   /* Get basic WCS information. */
   if(p->input->wcs)
-    {
-      ui_check_cdelt(p);
-      p->inwcsmatrix=gal_wcs_warp_matrix(p->input->wcs);
-    }
+    p->inwcsmatrix=gal_wcs_warp_matrix(p->input->wcs);
 
   /* Do all the distortion correction sanity-checks.*/
-  if(p->nonlinearmode)
+  if(p->wcsalign)
     ui_check_options_and_arguments_wcsalign(p);
 }
 
@@ -992,7 +1062,7 @@ ui_set_suffix(struct warpparams *p)
 {
   /* Return the suffix as soon as nonlinear mode is detected. Just
      ignore the rest. */
-  if(p->nonlinearmode) return "_aligned.fits";
+  if(p->wcsalign) return "_aligned.fits";
 
   /* A small independent sanity check: we either need a matrix or at least
      one modular warping. */
@@ -1049,7 +1119,7 @@ ui_preparations(struct warpparams *p)
                                                ui_set_suffix(p));
 
   /* Prepare the final warping matrix if in linear mode. */
-  if(p->nonlinearmode == 0) ui_matrix_finalize(p);
+  if(p->wcsalign == 0) ui_matrix_finalize(p);
 }
 
 
@@ -1136,7 +1206,7 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
warpparams *p)
       printf(" Input: %s (hdu: %s)\n", p->inputname, p->cp.hdu);
       if(p->gridfile)
         printf(" Pixel grid: %s (hdu %s)\n", p->gridfile, p->gridhdu);
-      if(p->nonlinearmode)
+      if(p->wcsalign)
         {
           disttype=gal_wcs_distortion_identify(p->input->wcs);
           if(disttype!=GAL_WCS_DISTORTION_INVALID)
@@ -1183,11 +1253,9 @@ void
 ui_free_report(struct warpparams *p, struct timeval *t1)
 {
   /* Free the allocated arrays: */
-  if(p->wa.cdelt) p->wa.cdelt=NULL;
-  if(p->cdelt) gal_data_free(p->cdelt);
-
   if(p->inverse) free(p->inverse);
   if(p->gridhdu) free(p->gridhdu);
+  if(p->wa.cdelt) p->wa.cdelt=NULL;
   if(p->gridfile) free(p->gridfile);
   if(p->matrix) gal_data_free(p->matrix);
   if(p->inwcsmatrix) free(p->inwcsmatrix);
diff --git a/bin/warp/ui.h b/bin/warp/ui.h
index b976039c..89f08fd0 100644
--- a/bin/warp/ui.h
+++ b/bin/warp/ui.h
@@ -62,7 +62,7 @@ enum option_keys_enum
   UI_KEY_CDELT           = 'x',
   UI_KEY_INTERPSAMPLING  = 'y',
   UI_KEY_CENTER          = 'c',
-  UI_KEY_WIDTHINPIX      = 'w',
+  UI_KEY_WIDTH           = 'w',
   UI_KEY_GRIDFILE        = 'G',
   UI_KEY_GRIDHDU         = 'H',
 
@@ -70,6 +70,7 @@ enum option_keys_enum
      automatically). */
   UI_KEY_CENTERONCORNER = 1000,
   UI_KEY_EDGESAMPLING,
+  UI_KEY_WIDTHINPIX,
   UI_KEY_HSTARTWCS,
   UI_KEY_HENDWCS,
   UI_KEY_CTYPE,
diff --git a/bin/warp/warp.c b/bin/warp/warp.c
index 1c0ad5a2..896af1ed 100644
--- a/bin/warp/warp.c
+++ b/bin/warp/warp.c
@@ -439,9 +439,9 @@ warp_write_to_file(struct warpparams *p, int hasmatrix)
 void
 warp_write_wcs_linear(struct warpparams *p)
 {
+  double tcrpix[3], *ps;
   double *m=p->matrix->array, diff;
   struct wcsprm *wcs=p->output->wcs;
-  double tcrpix[3], *ps=p->cdelt->array;
   double *crpix=wcs?wcs->crpix:NULL, *w=p->inwcsmatrix;
 
   /* 'tinv' is the 2 by 2 inverse matrix. Recall that 'p->inverse' is 3 by
@@ -482,6 +482,7 @@ warp_write_wcs_linear(struct warpparams *p)
          is because the signs are usually different.*/
       if( fabs(wcs->pc[1])<ABSOLUTEFLTERROR ) wcs->pc[1]=0.0f;
       if( fabs(wcs->pc[2])<ABSOLUTEFLTERROR ) wcs->pc[2]=0.0f;
+      ps=gal_wcs_pixel_scale(wcs);
       diff=fabs(wcs->pc[0])-fabs(wcs->pc[3]);
       if( fabs(diff/ps[0])<RELATIVEFLTERROR )
         wcs->pc[3]=( (wcs->pc[3] < 0.0f ? -1.0f : 1.0f)
@@ -526,7 +527,7 @@ warp(struct warpparams *p)
   gal_warp_wcsalign_t *wa=&p->wa;
 
   /* Do the preparations and set the pointers to the functions to use. */
-  if( p->nonlinearmode )
+  if( p->wcsalign )
     {
       /* Calculate and allocate the output image size and WCS */
       if(!p->cp.quiet)
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 4180cea4..521838b3 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -19573,21 +19573,35 @@ See the description of @option{--gridfile} below for 
more.
 @cindex CRVALi
 @cindex Aligning an image
 WCS coordinates of the center of the central pixel of the output image.
+Since a central pixel is only defined with an odd number of pixels along both 
dimensions, the output will always have an odd number of pixels.
 When @option{--center} or @option{--gridfile} aren't given, the output will 
have have the same central WCS coordinate as the input.
 
 Usually, the WCS coordinates are Right Ascension and Declination (when the 
first three characters of @code{CTYPE1} and @code{CTYPE2} are respectively 
@code{RA-} and @code{DEC}).
 For more on the @code{CTYPEi} keyword values, see @code{--ctype}.
 
-@item -w INT,INT
-@itemx --widthinpix=INT,INT
-Pixel width and height of the output image.
-When @option{--widthinpix} or @option{--gridfile} aren't given, Warp will 
calculate the necessary size of the output pixel grid to fully contain the 
input image.
-
-This option should be given two @emph{odd} integers that are greater than 1, 
so that the output image can have a @emph{central} pixel.
+@item -w INT[,INT]
+@itemx --width=INT[,INT]
+Width and height of the output image in units of WCS (usually degrees).
+If you want the values to be read as pixels, also call the 
@option{--widthinpix} option with @option{--width}.
+If a single value is given, Warp will use the same value for the second 
dimension (creating a square output).
+When @option{--width} or @option{--gridfile} aren't given, Warp will calculate 
the necessary size of the output pixel grid to fully contain the input image.
+
+Usually the WCS coordinates are in untis of degrees (defined by the 
@code{CUNITi} keywords of the FITS standard).
+But entering a certain number of arcseconds or arcminutes for the width can be 
annoying (you will usually need to go to the calculator!).
+To simplify such situations, this option also accepts division.
+For example @option{--width=1/60,2/60} will make an aligned warp that is 1 
arcmin along Right Ascension and 2 arcminutes along the Declination.
+
+With the @option{--widthinpix} option the values will be interpretted as 
numbers of pixels.
+In this scenario, this option should be given @emph{odd} integer(s) that are 
greater than 1.
+This ensures that the output image can have a @emph{central} pixel.
 Recall that through the @option{--center} option, you specify the WCS 
coordinate of the center of the central pixel.
 The central coordinate of an image with an even number of pixels will be on 
the edge of two pixels, so a ``central'' pixel is not well defined.
 If any of the given values are even, Warp will automatically add a single 
pixel (to make it an odd integer) and print a warning message.
 
+@item --widthinpix
+When called, the values given to the @option{--width} option will be 
interpreted as the number of pixels along each dimension(s).
+See the description of @option{--width} for more.
+
 @item -x FLT[,FLT]
 @itemx --cdelt=FLT[,FLT]
 @cindex CDELTi
diff --git a/lib/gnuastro-internal/options.h b/lib/gnuastro-internal/options.h
index c29fa447..30b79d03 100644
--- a/lib/gnuastro-internal/options.h
+++ b/lib/gnuastro-internal/options.h
@@ -52,7 +52,8 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 /* Statically allocated space for printing option values. */
 #define GAL_OPTIONS_STATIC_MEM_FOR_VALUES 2000
 
-
+/* Pixel width of output image. */
+#define GAL_OPTIONS_WIDTH_TOO_LARGE_SIZE 50000
 
 
 
@@ -252,6 +253,9 @@ gal_options_add_to_not_given(struct 
gal_options_common_params *cp,
 void
 gal_options_abort_if_mandatory_missing(struct gal_options_common_params *cp);
 
+void
+gal_options_width_too_large(double width, size_t dim_num,
+                            double pixwidth, double pixscale);
 
 
 /**********************************************************************/
diff --git a/lib/options.c b/lib/options.c
index 7d9de9ad..f2c90ced 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -150,6 +150,23 @@ gal_options_abort_if_mandatory_missing(struct 
gal_options_common_params *cp)
 
 
 
+void
+gal_options_width_too_large(double width, size_t dim_num,
+                            double pixwidth, double pixscale)
+{
+  /* Just a warning, will not exit program. */
+  error(EXIT_SUCCESS, 0, "WARNING: value %g (requested WCS-based width "
+        "along dimension %zu) translates to %.0f pixels on this dataset! "
+        "This is most probably not what you wanted! Note that the "
+        "dataset's pixel size in this dimension is %g. If you intended "
+        "this number to show the width in pixels, please add the "
+        "'--widthinpix' option", width, dim_num, pixwidth, pixscale);
+}
+
+
+
+
+
 static char *
 options_get_home()
 {



reply via email to

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