[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 05c660a 3/9: Library: new ds9.h library functi
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 05c660a 3/9: Library: new ds9.h library functions for parsing ds9 files |
Date: |
Fri, 21 May 2021 23:39:17 -0400 (EDT) |
branch: master
commit 05c660a8ee596be96a95453295370399dbc5bef8
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Library: new ds9.h library functions for parsing ds9 files
Until now, there was only a single 'ui_polygon_from_ds9_reg' function in
the Crop program for reading a DS9 region file. However, other programs
(like Table) also have this feature (and would thus need this
function). Also, generally, there are more operations that can be done on
DS9 region files or other types of ds9 output files.
With this commit, that function has been generalized into a new library
file called ('lib/ds9.c', with its corresponding 'lib/gnuastro/ds9.h'
header). Its calling with the crop program has also been correspondingly
corrected.
---
bin/crop/ui.c | 154 ++++++++++++----------------------------------------
lib/Makefile.am | 20 +++----
lib/ds9.c | 156 +++++++++++++++++++++++++++++++++++++++++++++++++++++
lib/gnuastro/ds9.h | 74 +++++++++++++++++++++++++
4 files changed, 273 insertions(+), 131 deletions(-)
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index f6f6fa8..b6f4e2e 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -28,6 +28,7 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
#include <stdio.h>
#include <string.h>
+#include <gnuastro/ds9.h>
#include <gnuastro/wcs.h>
#include <gnuastro/list.h>
#include <gnuastro/fits.h>
@@ -269,119 +270,45 @@ ui_parse_coordinate_mode(struct argp_option *option,
char *arg,
/**************************************************************/
/*************** Sanity Check *******************/
/**************************************************************/
+
+/* Do polygon-related sanity checks that can be very low-level. */
static void
-ui_polygon_from_ds9_reg(struct cropparams *p)
+ui_check_polygon_from_ds9(struct cropparams *p)
{
- FILE *fp;
- char *polygonstr;
- size_t commacounter=0;
- int coordmode=IMGCROP_MODE_INVALID;
- size_t plinelen, linesize=10, lineno=0;
- char *c, *line, *ds9regstart="# Region file format: DS9";
- char *polygonformaterr="It is expected for the line to have "
- "this format: 'polygon(AAA,BBB,...)'. Where 'AAA' and 'BBB' "
- "are numbers and '...' signifies that any number of points "
- "are possible";
-
- /* Allocate size to the lines on the file and check if it was sucessfull.
- The getline function reallocs the necessary memory. */
- errno=0;
- line = malloc(linesize * sizeof(*line));
- if(line == NULL)
- error(EXIT_FAILURE, errno, "%s: %zu bytes for line buffer",
- __func__, linesize * sizeof(*line));
+ int ds9regmode;
- /* Open the file and checks if it's not null. */
- errno=0;
- fp = fopen(p->polygonname, "r");
- if(fp == NULL)
- error(EXIT_FAILURE, errno, "The polygon file is blank");
-
- /* Get the lines on the file. */
- while(getline(&line, &linesize, fp)!=-1)
+ /* This is only relevant when a region file is actually given. */
+ if(p->polygonname)
{
- /* To have line-counters starting from 1. */
- ++lineno;
-
- /* The first line should start with a fixed string. */
- if(lineno==1)
- {
- if( strncmp(line, ds9regstart, 25) )
- error(EXIT_FAILURE, 0, "%s: doesn't appear to be a DS9 "
- "region file! We assume that DS9 region files begin "
- "with this string in their first line: '%s'",
- p->polygonname, ds9regstart);
- continue;
- }
-
- /* If we are on the coordinate mode line, then set the mode of Crop
- based on it. */
- if( !strcmp(line, "fk5\n") || !strcmp(line, "image\n") )
+ /* These two options cannot be called together. */
+ if(p->polygon)
+ error(EXIT_FAILURE, errno, "'--polygon' and '--polygonname' "
+ "cannot be given together. With the first you specify the "
+ "polygon vertices directly on the command-line. With the "
+ "second, you give a DS9 region file and the polygon "
+ "vertices are read from that.");
+ else
{
- /* Make sure it hasn't been called more than once. */
- if(coordmode!=IMGCROP_MODE_INVALID)
- error_at_line(EXIT_FAILURE, 0, p->polygonname, lineno,
- "more than one coordinate line defined");
-
- /* Set the proper mode. */
- if(!strcmp(line, "fk5\n")) coordmode=IMGCROP_MODE_WCS;
- else coordmode=IMGCROP_MODE_IMG;
-
- /* Stop parsing the file if the polygon has also been found by
- this point (we don't need any more information, no need to
- waste the user's CPU and time). */
- if(p->polygon) break;
+ /* Extract the polygon and the coordinate mode. */
+ p->polygon=gal_ds9_reg_read_polygon(p->polygonname,
+ &ds9regmode);
+ switch(ds9regmode)
+ {
+ case GAL_DS9_COORD_MODE_IMG: p->mode=IMGCROP_MODE_IMG; break;
+ case GAL_DS9_COORD_MODE_WCS: p->mode=IMGCROP_MODE_WCS; break;
+ default:
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at "
+ "'%s' to fix the problem. The output coordinate mode "
+ "of 'gal_ds9_reg_read_polygon' (%d) isn't recognized "
+ "by this function", __func__, PACKAGE_BUGREPORT,
+ ds9regmode);
+ }
}
- /* The line containing the polygon information starts with
- 'polygon('. */
- if( !strncmp(line, "polygon(", 8) )
- {
- /* Get the line length and check if it is indeed in the proper
- format. If so, remove the last parenthesis. */
- plinelen=strlen(line);
- if(line[plinelen-2]==')')
- line[plinelen-2]='\0';
- else
- error_at_line(EXIT_FAILURE, 0, p->polygonname, lineno,
- "line with polygon vertices doesn't end "
- "with ')'. %s", polygonformaterr);
-
- /* Convert the string to the expected format (with ':' separating
- each vertice). Note how we are ignoring the first 8 characters
- that contain 'polygon('. */
- polygonstr=&line[8];
- for(c=polygonstr; *c!='\0'; ++c)
- if(*c==',' && (++commacounter % 2) == 0 ) *c=':';
-
- /* Read the coordinates within the line. */
- p->polygon=gal_options_parse_colon_sep_csv_raw(polygonstr,
- p->polygonname,
- lineno);
-
- /* Stop parsing the file if the coordinate mode has also been
- found by this point (we don't need any more information, no
- need to waste the user's CPU and time). */
- if(coordmode!=IMGCROP_MODE_INVALID) break;
- }
+ /* Clean up. */
+ free(p->polygonname);
+ p->polygonname=NULL;
}
-
- /* If no coordinate mode was found in the file, print an error. */
- if(coordmode==IMGCROP_MODE_INVALID)
- error(EXIT_FAILURE, 0, "%s: no coordinate mode found! "
- "We expect one line to be either 'fk5' or 'image'",
- p->polygonname);
-
- /* If no polygon line was in the file, abort with an error. */
- if(p->polygon==NULL)
- error(EXIT_FAILURE, 0, "%s: no polygon statement found! We expect "
- "one line in the format of 'polygon(AAA,BBB,...)' in the "
- "file given to '--polygonname' option. %s", p->polygonname,
- polygonformaterr);
-
- /* Free the space used. */
- free(line);
- fclose(fp);
}
@@ -399,22 +326,7 @@ ui_read_check_only_options(struct cropparams *p)
/* If a DS9 region file should be used for the polygon, read it. This is
done first for two reasons. 1) It can change the value of '--mode'. 2)
It will set the '--polygon' option's value. */
- if(p->polygonname)
- {
- if(p->polygon)
- error(EXIT_FAILURE, errno, "'--polygon' and '--polygonname' "
- "cannot be given together. With the first you specify the "
- "polygon vertices directly on the command-line. With the "
- "second, you give a DS9 region file and the polygon "
- "vertices are read from that.");
- else
- {
- ui_polygon_from_ds9_reg(p);
- free(p->polygonname);
- p->polygonname=NULL;
- }
- }
-
+ ui_check_polygon_from_ds9(p);
/* Make sure that only one of the crop definitions is given. */
checksum = ( (p->center!=NULL)
diff --git a/lib/Makefile.am b/lib/Makefile.am
index 4b4b297..de1a311 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -70,7 +70,7 @@ libgnuastro_la_SOURCES = $(MAYBE_WCSDISTORTION) arithmetic.c \
arithmetic-le.c arithmetic-lt.c arithmetic-minus.c arithmetic-modulo.c \
arithmetic-multiply.c arithmetic-ne.c arithmetic-or.c \
arithmetic-plus.c arithmetic-set.c array.c binary.c blank.c box.c \
- checkset.c convolve.c cosmology.c data.c eps.c fits.c git.c \
+ checkset.c convolve.c cosmology.c data.c ds9.c eps.c fits.c git.c \
interpolate.c jpeg.c kdtree.c label.c list.c match.c options.c pdf.c \
permutation.c pointer.c polygon.c qsort.c dimension.c speclines.c \
statistics.c table.c tableintern.c threads.c tiff.c tile.c \
@@ -87,15 +87,15 @@ headersdir=$(top_srcdir)/lib/gnuastro
pkginclude_HEADERS = gnuastro/config.h $(headersdir)/arithmetic.h \
$(headersdir)/array.h $(headersdir)/binary.h $(headersdir)/blank.h \
$(headersdir)/box.h $(headersdir)/convolve.h $(headersdir)/cosmology.h \
- $(headersdir)/data.h $(headersdir)/dimension.h $(headersdir)/eps.h \
- $(headersdir)/fits.h $(headersdir)/git.h $(headersdir)/interpolate.h \
- $(headersdir)/jpeg.h $(headersdir)/kdtree.h $(headersdir)/label.h \
- $(headersdir)/list.h $(headersdir)/match.h $(headersdir)/pdf.h \
- $(headersdir)/permutation.h $(headersdir)/pointer.h $(headersdir)/polygon.h \
- $(headersdir)/qsort.h $(headersdir)/speclines.h $(headersdir)/statistics.h \
- $(headersdir)/table.h $(headersdir)/threads.h $(headersdir)/tiff.h \
- $(headersdir)/tile.h $(headersdir)/txt.h $(headersdir)/type.h \
- $(headersdir)/units.h $(headersdir)/wcs.h
+ $(headersdir)/data.h $(headersdir)/dimension.h $(headersdir)/ds9.h \
+ $(headersdir)/eps.h $(headersdir)/fits.h $(headersdir)/git.h \
+ $(headersdir)/interpolate.h $(headersdir)/jpeg.h $(headersdir)/kdtree.h \
+ $(headersdir)/label.h $(headersdir)/list.h $(headersdir)/match.h \
+ $(headersdir)/pdf.h $(headersdir)/permutation.h $(headersdir)/pointer.h \
+ $(headersdir)/polygon.h $(headersdir)/qsort.h $(headersdir)/speclines.h \
+ $(headersdir)/statistics.h $(headersdir)/table.h $(headersdir)/threads.h \
+ $(headersdir)/tiff.h $(headersdir)/tile.h $(headersdir)/txt.h \
+ $(headersdir)/type.h $(headersdir)/units.h $(headersdir)/wcs.h
diff --git a/lib/ds9.c b/lib/ds9.c
new file mode 100644
index 0000000..9fb6155
--- /dev/null
+++ b/lib/ds9.c
@@ -0,0 +1,156 @@
+/*********************************************************************
+Functions to interface with DS9 files.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+ Mohammad Akhlaghi <mohammad@akhlaghi.org>
+Contributing author(s):
+Copyright (C) 2015-2021, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#include <config.h>
+
+#include <stdio.h>
+#include <errno.h>
+#include <error.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gnuastro/ds9.h>
+#include <gnuastro/data.h>
+
+#include <gnuastro-internal/options.h>
+
+
+/* Read the polygon specified in the given DS9 region file and parse it in
+ the standard format. */
+gal_data_t *
+gal_ds9_reg_read_polygon(char *filename, int *coordmode)
+{
+ FILE *fp;
+ char *polygonstr;
+ gal_data_t *out=NULL;
+ size_t commacounter=0;
+ size_t plinelen, linesize=10, lineno=0;
+ char *c, *line, *ds9regstart="# Region file format: DS9";
+ char *polygonformaterr="It is expected for the line to have "
+ "this format: 'polygon(AAA,BBB,...)'. Where 'AAA' and 'BBB' "
+ "are numbers and '...' signifies that any number of points "
+ "are possible";
+
+ /* Initialize 'coordmode'. */
+ *coordmode=GAL_DS9_COORD_MODE_INVALID;
+
+ /* Allocate size to the lines on the file and check if it was sucessfull.
+ The getline function reallocs the necessary memory. */
+ errno=0;
+ line = malloc(linesize * sizeof(*line));
+ if(line == NULL)
+ error(EXIT_FAILURE, errno, "%s: %zu bytes for line buffer",
+ __func__, linesize * sizeof(*line));
+
+ /* Open the file and checks if it's not null. */
+ errno=0;
+ fp = fopen(filename, "r");
+ if(fp == NULL)
+ error(EXIT_FAILURE, errno, "The polygon file is blank");
+
+ /* Get the lines on the file. */
+ while(getline(&line, &linesize, fp)!=-1)
+ {
+ /* To have line-counters starting from 1. */
+ ++lineno;
+
+ /* The first line should start with a fixed string. */
+ if(lineno==1)
+ {
+ if( strncmp(line, ds9regstart, 25) )
+ error(EXIT_FAILURE, 0, "%s: doesn't appear to be a DS9 "
+ "region file! We assume that DS9 region files begin "
+ "with this string in their first line: '%s'",
+ filename, ds9regstart);
+ continue;
+ }
+
+ /* If we are on the coordinate mode line, then set the mode of Crop
+ based on it. */
+ if( !strcmp(line, "fk5\n") || !strcmp(line, "image\n") )
+ {
+ /* Make sure it hasn't been called more than once. */
+ if(*coordmode!=GAL_DS9_COORD_MODE_INVALID)
+ error_at_line(EXIT_FAILURE, 0, filename, lineno,
+ "more than one coordinate line defined");
+
+ /* Set the proper mode. */
+ if(!strcmp(line, "fk5\n")) *coordmode=GAL_DS9_COORD_MODE_WCS;
+ else *coordmode=GAL_DS9_COORD_MODE_IMG;
+
+ /* Stop parsing the file if the polygon has also been found by
+ this point (we don't need any more information, no need to
+ waste the user's CPU and time). */
+ if(out) break;
+ }
+
+ /* The line containing the polygon information starts with
+ 'polygon('. */
+ if( !strncmp(line, "polygon(", 8) )
+ {
+ /* Get the line length and check if it is indeed in the proper
+ format. If so, remove the last parenthesis. */
+ plinelen=strlen(line);
+ if(line[plinelen-2]==')')
+ line[plinelen-2]='\0';
+ else
+ error_at_line(EXIT_FAILURE, 0, filename, lineno,
+ "line with polygon vertices doesn't end "
+ "with ')'. %s", polygonformaterr);
+
+ /* Convert the string to the expected format (with ':' separating
+ each vertice). Note how we are ignoring the first 8 characters
+ that contain 'polygon('. */
+ polygonstr=&line[8];
+ for(c=polygonstr; *c!='\0'; ++c)
+ if(*c==',' && (++commacounter % 2) == 0 ) *c=':';
+
+ /* Read the coordinates within the line. */
+ out=gal_options_parse_colon_sep_csv_raw(polygonstr,
+ filename,
+ lineno);
+
+ /* Stop parsing the file if the coordinate mode has also been
+ found by this point (we don't need any more information, no
+ need to waste the user's CPU and time). */
+ if(*coordmode!=GAL_DS9_COORD_MODE_INVALID) break;
+ }
+ }
+
+ /* If no coordinate mode was found in the file, print an error. */
+ if(*coordmode==GAL_DS9_COORD_MODE_INVALID)
+ error(EXIT_FAILURE, 0, "%s: no coordinate mode found! "
+ "We expect one line to be either 'fk5' or 'image'",
+ filename);
+
+ /* If no polygon line was in the file, abort with an error. */
+ if(out==NULL)
+ error(EXIT_FAILURE, 0, "%s: no polygon statement found! We expect "
+ "one line in the format of 'polygon(AAA,BBB,...)' in the "
+ "file given to '--polygonname' option. %s", filename,
+ polygonformaterr);
+
+ /* Clean up and return. */
+ free(line);
+ fclose(fp);
+ return out;
+}
diff --git a/lib/gnuastro/ds9.h b/lib/gnuastro/ds9.h
new file mode 100644
index 0000000..41e5719
--- /dev/null
+++ b/lib/gnuastro/ds9.h
@@ -0,0 +1,74 @@
+/*********************************************************************
+Functions to interface with DS9 files.
+This is part of GNU Astronomy Utilities (Gnuastro) package.
+
+Original author:
+ Mohammad Akhlaghi <mohammad@akhlaghi.org>
+Contributing author(s):
+Copyright (C) 2015-2021, Free Software Foundation, Inc.
+
+Gnuastro is free software: you can redistribute it and/or modify it
+under the terms of the GNU General Public License as published by the
+Free Software Foundation, either version 3 of the License, or (at your
+option) any later version.
+
+Gnuastro is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with Gnuastro. If not, see <http://www.gnu.org/licenses/>.
+**********************************************************************/
+#ifndef __GAL_DS9_H__
+#define __GAL_DS9_H__
+
+/* Include other headers if necessary here. Note that other header files
+ must be included before the C++ preparations below */
+
+#include <gnuastro/data.h>
+
+/* C++ Preparations */
+#undef __BEGIN_C_DECLS
+#undef __END_C_DECLS
+#ifdef __cplusplus
+# define __BEGIN_C_DECLS extern "C" {
+# define __END_C_DECLS }
+#else
+# define __BEGIN_C_DECLS /* empty */
+# define __END_C_DECLS /* empty */
+#endif
+/* End of C++ preparations */
+
+
+
+/* Actual header contants (the above were for the Pre-processor). */
+__BEGIN_C_DECLS /* From C++ preparations */
+
+
+
+
+
+/* Modes to interpret coordinates. */
+enum gal_ds9_coord_modes
+{
+ GAL_DS9_COORD_MODE_INVALID, /* For sanity checks. */
+
+ GAL_DS9_COORD_MODE_IMG, /* Image coordinates. */
+ GAL_DS9_COORD_MODE_WCS, /* WCS coordinates. */
+};
+
+
+
+
+
+gal_data_t *
+gal_ds9_reg_read_polygon(char *filename, int *coordmode);
+
+
+
+
+
+__END_C_DECLS /* From C++ preparations */
+
+#endif /* __GAL_WCS_H__ */
- [gnuastro-commits] master updated (27df4f2 -> 3dff1e4), Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master d3cfd8e 1/9: Crop: added option to crop polygon from ds9 file, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master 326b42a 2/9: Crop: polished the implementation of new --polygonname option, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master 05c660a 3/9: Library: new ds9.h library functions for parsing ds9 files,
Mohammad Akhlaghi <=
- [gnuastro-commits] master cbf8a79 4/9: Table: added the --polygonname option, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master c3d437d 8/9: Book: adjusted --polygon option, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master 564da39 5/9: Book: new --polygonname option and new ds9 library added, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master 89be245 7/9: Crop and Table: --polygon now accepts filenames, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master d2bca9d 6/9: Crop and Table: --polygonfile new name for --polygonname, Mohammad Akhlaghi, 2021/05/21
- [gnuastro-commits] master 3dff1e4 9/9: Book: edited gal_ds9_reg_read_polygon from DS9 Library, corrected NEWS, Mohammad Akhlaghi, 2021/05/21