gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master d3cfd8e 1/9: Crop: added option to crop polygo


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master d3cfd8e 1/9: Crop: added option to crop polygon from ds9 file
Date: Fri, 21 May 2021 23:39:17 -0400 (EDT)

branch: master
commit d3cfd8e3c6b03f7ae8b1e966bda81c6f36ee7388
Author: Natáli D. Anzanello <natali.anzanello@ufrgs.br>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Crop: added option to crop polygon from ds9 file
    
    Until now, to define a cropping polygon, it was necessary to pass the
    polygon vertice coordinates to the '--polygon' option on the
    command-line. However, polygons are usually defined based on the larger
    image and trying to visually identify their vertices by hovering your mouse
    over them and writing down the coordiantes is very annoying and prone to
    serious bugs. The need for this had already been discussed in task #14409
    (Polygon vertices from a DS9 region file).
    
    With this commit, work is starting on implementing this feature through a
    new '--polygonname' option.
    
    NOTE: commit message edited by Mohammad Akhlaghi.
---
 bin/crop/args.h |  13 +++++
 bin/crop/main.h |   1 +
 bin/crop/ui.c   | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 bin/crop/ui.h   |   3 +-
 4 files changed, 162 insertions(+), 2 deletions(-)

diff --git a/bin/crop/args.h b/bin/crop/args.h
index 7eddd38..6bbd6b2 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -307,6 +307,19 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
+    {
+      "polygonname",
+      UI_KEY_POLYGONNAME,
+      "REG",
+      0,
+      "Input polygon filename made in DS9.",
+      UI_GROUP_REGION,
+      &p->polygonname,
+      GAL_TYPE_STRING,
+      GAL_OPTIONS_RANGE_ANY,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
 
 
 
diff --git a/bin/crop/main.h b/bin/crop/main.h
index f18a88c..31098d2 100644
--- a/bin/crop/main.h
+++ b/bin/crop/main.h
@@ -99,6 +99,7 @@ struct cropparams
   gal_data_t          *polygon;  /* Input string of polygon vertices.     */
   uint8_t           polygonout;  /* ==1: Keep the inner polygon region.   */
   uint8_t          polygonsort;  /* Don't sort polygon vertices.          */
+  char            *polygonname;  /* Name of input polygon file.           */
 
   /* Internal */
   size_t                 numin;  /* Number of input images.               */
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 0b99b27..913e94c 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -1147,6 +1147,139 @@ ui_preparations(struct cropparams *p)
 
 
 /**************************************************************/
+/*********             Parser ds9 file             ************/
+/**************************************************************/
+size_t ui_ds9_coordinates_number(char *line)
+{
+  char *token;
+  char delimiters[] = "(,)\n";
+  size_t quantity = 0;
+  char *var;
+  
+  /* Copy the line to another variable to inspect it. */
+  var = malloc ((strlen(line) + 1) * sizeof(*var));
+  strcpy(var, line);
+  
+  /* Get the first token (the geometry of the region). */
+  token = strtok(var, delimiters);
+  
+  /* The rest of the tokens are coordinates. So go through them and count. */
+  while(token != NULL)
+  {
+    ++quantity;
+    token = strtok(NULL, delimiters);
+  }
+  
+  free(var);  
+  
+  /* Check if quantity is zero to avoid returning -1. */
+  if(quantity==0)
+    ++quantity;
+  return(quantity-1);
+}
+
+
+void ui_read_ds9_file(struct cropparams *p)
+{
+  FILE *fp;
+  size_t linesize, lineno, coordno;
+  char *line, *token, *coordmode, delimiters[] = "(,)\n";
+  int modecmp, modecmp2, polygoncmp, coordinatesit;
+  double *coordinates = NULL;
+  struct gal_data_t *newpolygon;
+    
+  /* Allocate size to the lines on the file and check if it was sucessfull.
+     The getline function reallocs the necessary memory. */
+  linesize=10;
+  line = malloc(linesize * sizeof(*line));
+  errno=0;
+  if(line == NULL)
+    error(EXIT_FAILURE, errno, "Given polygon file and coordinates! Choose" 
+          "one.");
+ 
+  /* Open the file and checks if it's not null. */
+  fp = fopen(p->polygonname, "r");
+  if(fp == NULL)
+    error(EXIT_FAILURE, errno, "The polygon file is blank.");
+ 
+  /* Get the lines on the file. */
+  lineno=0;
+  while(getline(&line, &linesize, fp)!=-1)
+    {
+      ++lineno;  
+      /* Line 3 has the type of the coordinates. */
+      if(lineno==3)
+        {
+          /* Check if the mode on the file is consistent with the mode
+             selected to crop. */
+          coordmode = strtok(line, "\n");
+          modecmp = strcmp(coordmode, "fk5");
+          modecmp2 = strcmp(coordmode, "image");
+          if((!modecmp && p->mode!=IMGCROP_MODE_WCS) || 
+             (!modecmp2 && p->mode!=IMGCROP_MODE_IMG))
+              error(EXIT_FAILURE, errno, "The program coordinates mode is" 
+              " different from the file mode.\nThe mode in the file is: %s",
+              coordmode);
+        }
+      /* Line 4 has the geometry and the coordinates. */ 
+      if(lineno == 4)
+        {
+          /* Gets the number of coordinates given. */
+          coordno = ui_ds9_coordinates_number(line);
+          /* Checks if its a polygon and if the number of coordinates is 
+             valid (divisible by two, because we are dealing with 2d, and if
+             its greater than zero. */
+          token = strtok(line, delimiters);
+          polygoncmp = strcmp(token, "polygon");
+          if(polygoncmp==0 && coordno>0 && coordno%2==0)
+            {
+              /* Allocate size to the coordinates and set it. */
+              coordinates = malloc ((coordno + 1) * sizeof(*coordinates));
+              token = strtok(NULL, delimiters);
+              *coordinates = atof(token);
+              token = strtok(NULL, delimiters);
+              coordinatesit=1;
+              while(token != NULL)
+                {
+                    *(coordinates + coordinatesit) = atof(token);
+                    ++coordinatesit;
+                    token = strtok(NULL, delimiters);
+                }
+              }
+          else
+            error(EXIT_FAILURE, errno, "It's not a polygon or the number"
+                  " of coordinates is invalid: %ld found.",coordno);
+        }
+    }
+    /* Create the polygon structure and points the main parameter to it. */
+    newpolygon = gal_data_alloc(coordinates, GAL_TYPE_FLOAT64, 1, &coordno,
+                                NULL, 0, -1, 1, NULL, NULL, NULL);
+    p->polygon = newpolygon;
+    /* Free the space used. */
+    free(line);
+    fclose(fp);
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+/**************************************************************/
 /************         Set the parameters          *************/
 /**************************************************************/
 
@@ -1177,7 +1310,19 @@ ui_read_check_inputs_setup(int argc, char *argv[], 
struct cropparams *p)
   errno=0;
   if(argp_parse(&thisargp, argc, argv, 0, 0, p))
     error(EXIT_FAILURE, errno, "parsing arguments");
-
+  
+  
+  /* If it's a polygon file from ds9, we adjust the polygon parameter to 
+     hold the values in the file. */
+  if(p->polygonname!=NULL)
+    {
+      if(p->polygon == NULL)
+          ui_read_ds9_file(p);
+      else
+          error(EXIT_FAILURE, errno, "Given polygon file and coordinates!"
+                " Choose one.");
+    }
+  
 
   /* Read the configuration files and set the common values. */
   gal_options_read_config_set(&p->cp);
diff --git a/bin/crop/ui.h b/bin/crop/ui.h
index 9a34fa2..7826f63 100644
--- a/bin/crop/ui.h
+++ b/bin/crop/ui.h
@@ -45,7 +45,7 @@ enum program_args_groups
 
 /* Available letters for short options:
 
-   a d e f g i j k m r t u v y
+   a d e f g i j k m r u v y
    A B E G H J L Q R W X Y
 */
 enum option_keys_enum
@@ -62,6 +62,7 @@ enum option_keys_enum
   UI_KEY_WIDTH          = 'w',
   UI_KEY_CENTER         = 'c',
   UI_KEY_COORDCOL       = 'x',
+  UI_KEY_POLYGONNAME    = 't',
 
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */



reply via email to

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