[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master ffc7608: Fits: four new options to find image/
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master ffc7608: Fits: four new options to find image/table HDUs |
Date: |
Sat, 1 May 2021 15:38:31 -0400 (EDT) |
branch: master
commit ffc760820041eedbd5f6a61c417f5d30fda98738
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Fits: four new options to find image/table HDUs
Until now, when a user wanted to see if at least on table/image HDU exists
in a FITS file, they would have to look at the full list of HDUs. For a
human eye that is fine, but for a script, this was annoying and slow. In
particular, as part of current effort to add shell auto-complete features
in Gnuastro. The same goes for scenarios when you want the list of image or
table HDUs.
With this commit, four new options have been added to the Fits program to
greatly simplify these jobs: '--hastablehdu', '--hasimagehdu',
'listtablehdu', '--listimagehdu'. The first two will only parse enough HDUs
to see if atleast one exists and the other two will print each
corresponding HDU name or number in a separate line.
---
NEWS | 5 ++-
bin/fits/args.h | 53 +++++++++++++++++++++++
bin/fits/fits.c | 126 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
bin/fits/main.h | 4 ++
bin/fits/ui.c | 27 +++++++-----
bin/fits/ui.h | 4 ++
doc/gnuastro.texi | 22 ++++++++++
7 files changed, 227 insertions(+), 14 deletions(-)
diff --git a/NEWS b/NEWS
index 3b56f80..7ee4179 100644
--- a/NEWS
+++ b/NEWS
@@ -82,7 +82,10 @@ See the end of the file for license conditions.
you had three input FITS files with input in the same HDU.
Fits:
-
+ --hastablehdu: print 1 if at least one table HDU exists in file.
+ --hasimagehdu: print 1 if at least one image HDU exists in file.
+ --listtablehdus: print table HDU names (or numbers when no name exists).
+ --listimagehdus: print image HDU names (or numbers when no name exists).
--wcscoordsys: convert the WCS coordinate system of the input into any
recognized coordinate system. It currently supports: equatorial
(J2000, B1950), ecliptic (J2000, B1950), Galactic and
diff --git a/bin/fits/args.h b/bin/fits/args.h
index ffe56a9..1a2777f 100644
--- a/bin/fits/args.h
+++ b/bin/fits/args.h
@@ -88,6 +88,59 @@ struct argp_option program_options[] =
GAL_OPTIONS_NOT_MANDATORY,
GAL_OPTIONS_NOT_SET
},
+ {
+ "hastablehdu",
+ UI_KEY_HASTABLEHDU,
+ 0,
+ 0,
+ "File has at least one table HDU.",
+ UI_GROUP_EXTENSION_INFORMATION,
+ &p->hastablehdu,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+ {
+ "hasimagehdu",
+ UI_KEY_HASIMAGEHDU,
+ 0,
+ 0,
+ "File has at least one image HDU.",
+ UI_GROUP_EXTENSION_INFORMATION,
+ &p->hasimagehdu,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+ {
+ "listtablehdus",
+ UI_KEY_LISTTABLEHDUS,
+ 0,
+ 0,
+ "List all table HDUs within the file.",
+ UI_GROUP_EXTENSION_INFORMATION,
+ &p->listtablehdus,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+ {
+ "listimagehdus",
+ UI_KEY_LISTIMAGEHDUS,
+ 0,
+ 0,
+ "List all image HDUs within the file.",
+ UI_GROUP_EXTENSION_INFORMATION,
+ &p->listimagehdus,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+
diff --git a/bin/fits/fits.c b/bin/fits/fits.c
index 718d50c..b3de42a 100644
--- a/bin/fits/fits.c
+++ b/bin/fits/fits.c
@@ -495,6 +495,122 @@ fits_skycoverage(struct fitsparams *p)
+static char *
+fits_list_certain_hdu_string(fitsfile *fptr, int hduindex)
+{
+ size_t i;
+ int status=0;
+ char *out, extname[80];
+
+ /* See if an 'EXTNAME' keyword exists for this HDU. */
+ fits_read_keyword(fptr, "EXTNAME", extname, NULL, &status);
+
+ /* If EXTNAME doesn't exist, write the HDU index (counting from zero),
+ but if it does, remove the ending single quotes and possible extra
+ space characters (the staring single quote will be removed when
+ copying the name into 'out'). */
+ if(status) sprintf(extname, "%d", hduindex);
+ else
+ {
+ for(i=strlen(extname)-1; i>0; --i)
+ if(extname[i]!='\'' && extname[i]!=' ')
+ { extname[i+1]='\0'; break; }
+ }
+
+ /* Put the value into the allocated 'out' string. */
+ gal_checkset_allocate_copy(status ? extname : extname+1, &out);
+ return out;
+}
+
+
+
+
+static void
+fits_certain_hdu(struct fitsparams *p, int list1has0,
+ int table1image0)
+{
+ fitsfile *fptr;
+ gal_list_str_t *names=NULL;
+ int has=0, naxis, hducounter=1, hdutype, status=0;
+
+ /* Open the FITS file. */
+ fits_open_file(&fptr, p->input->v, READONLY, &status);
+ gal_fits_io_error(status, NULL);
+
+ /* Start by moving to the first HDU (counting from 1) and then parsing
+ through them. */
+ fits_movabs_hdu(fptr, hducounter, &hdutype, &status);
+ while(status==0)
+ {
+ /* Check the HDU type. */
+ switch(hdutype)
+ {
+
+ /* Tables are easy. */
+ case BINARY_TBL:
+ case ASCII_TBL:
+ if(table1image0)
+ {
+ if(list1has0)
+ gal_list_str_add(&names,
+ fits_list_certain_hdu_string(fptr,
+ hducounter-1),
+ 0);
+ else has=1;
+ }
+ break;
+
+ /* For images, we need to check there is actually any data. */
+ case IMAGE_HDU:
+ if(table1image0==0)
+ {
+ fits_get_img_dim(fptr, &naxis, &status);
+ gal_fits_io_error(status, NULL);
+ if(naxis>0)
+ {
+ if(list1has0)
+ gal_list_str_add(&names,
+ fits_list_certain_hdu_string(fptr,
+
hducounter-1),
+ 0);
+ else has=1;
+ }
+ }
+ break;
+
+ /* Just to avoid bad bugs. */
+ default:
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s "
+ "to fix the problem. The value %d is not recognized "
+ "for 'hdutype'", __func__, PACKAGE_BUGREPORT, hdutype);
+ }
+
+ /* Move to the next HDU. */
+ fits_movabs_hdu(fptr, ++hducounter, &hdutype, &status);
+
+ /* If we are in "has" mode and the first HDU has already been found,
+ then there is no need to continue parsing the HDUs, so set
+ 'status' to 1 to stop the 'while' above. */
+ if( list1has0==0 && has==1 ) status=1;
+ }
+
+ /* Close the file. */
+ status=0;
+ fits_close_file(fptr, &status);
+
+ /* Print the result. */
+ if( list1has0 )
+ {
+ gal_list_str_print(names);
+ gal_list_str_free(names, 1);
+ }
+ else printf("%d\n", has);
+}
+
+
+
+
+
static void
fits_hdu_remove(struct fitsparams *p, int *r)
{
@@ -623,9 +739,13 @@ fits(struct fitsparams *p)
/* Options that must be called alone. */
if(p->numhdus) fits_hdu_number(p);
- else if(p->datasum) fits_datasum(p);
- else if(p->pixelscale) fits_pixelscale(p);
- else if(p->skycoverage) fits_skycoverage(p);
+ else if(p->datasum) fits_datasum(p);
+ else if(p->pixelscale) fits_pixelscale(p);
+ else if(p->skycoverage) fits_skycoverage(p);
+ else if(p->hasimagehdu) fits_certain_hdu(p, 0, 0);
+ else if(p->hastablehdu) fits_certain_hdu(p, 0, 1);
+ else if(p->listimagehdus) fits_certain_hdu(p, 1, 0);
+ else if(p->listtablehdus) fits_certain_hdu(p, 1, 1);
/* Options that can be called together. */
else
diff --git a/bin/fits/main.h b/bin/fits/main.h
index c0254c2..87c7ec6 100644
--- a/bin/fits/main.h
+++ b/bin/fits/main.h
@@ -64,6 +64,10 @@ struct fitsparams
uint8_t datasum; /* Calculate and print HDU's datasum. */
uint8_t pixelscale; /* Calculate and print HDU's pixelscale. */
uint8_t skycoverage; /* Calculate and image coverage in WCS. */
+ uint8_t hastablehdu; /* File has atleast one table HDU. */
+ uint8_t hasimagehdu; /* File has atleast one image HDU. */
+ uint8_t listtablehdus; /* List all table HDUs within the file. */
+ uint8_t listimagehdus; /* List all image HDUs within the file. */
uint8_t primaryimghdu; /* Copy/cut HDU into primary HDU. */
uint8_t printallkeys; /* Print all the header keywords. */
uint8_t date; /* Set DATE to current time. */
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index 536ecd5..d63a0dd 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -367,7 +367,8 @@ ui_read_check_only_options(struct fitsparams *p)
/* Same for the extension-related options */
if( p->remove || p->copy || p->cut || p->numhdus || p->datasum
- || p->pixelscale || p->skycoverage )
+ || p->pixelscale || p->skycoverage || p->hastablehdu
+ || p->hasimagehdu || p->listtablehdus || p->listimagehdus )
{
/* A small sanity check. */
if(p->mode!=FITS_MODE_INVALID)
@@ -375,26 +376,32 @@ ui_read_check_only_options(struct fitsparams *p)
"cannot be called together");
/* Some HDU options cannot be called with other options. */
- stdoutcheck = p->numhdus + p->datasum + p->pixelscale + p->skycoverage;
+ stdoutcheck = ( p->numhdus + p->datasum + p->pixelscale
+ + p->skycoverage + p->hastablehdu + p->hasimagehdu
+ + p->listtablehdus + p->listimagehdus );
/* Make sure if an output file is needed. */
if(stdoutcheck)
{
- /* Make sure the other HDU-related options aren't called. */
+ /* Make sure HDU reading and editing options aren't called
+ together. */
if(p->remove || p->copy || p->cut)
- error(EXIT_FAILURE, 0, "'--numhdus', '--datasum', '--pixelscale' "
- "or '--skycoverage' options cannot be called with any of "
- "the '--remove', '--copy' or '--cut' options");
+ error(EXIT_FAILURE, 0, "HDU reading options (like "
+ "'--numhdus', '--datasum' and etc) cannot be called "
+ "with any of the HDU modification options like "
+ "'--remove', '--copy' or '--cut' options");
/* Make sure these options are called alone. */
if(stdoutcheck>1)
- error(EXIT_FAILURE, 0, "'--numhdus', '--datasum', '--pixelscale' "
- "or '--skycoverage' options cannot be called together, "
- "only one at a time");
+ error(EXIT_FAILURE, 0, "HDU info options, like '--numhdus', "
+ "'--datasum', '--pixelscale' or '--skycoverage', cannot "
+ "be called together, only one at a time");
/* Make sure the HDU is given if any of the options except
'--numhdus' are called. */
- if( stdoutcheck-p->numhdus && p->cp.hdu==NULL )
+ if( ( p->numhdus || p->hastablehdu || p->hasimagehdu
+ || p->listtablehdus || p->listimagehdus)
+ && p->cp.hdu==NULL )
error(EXIT_FAILURE, 0, "a HDU (extension) is necessary for the "
"'--datasum', '--pixelscale' or '--skycoverage' options. "
"Please use the '--hdu' (or '-h') option to select one");
diff --git a/bin/fits/ui.h b/bin/fits/ui.h
index 61f70af..cb400c5 100644
--- a/bin/fits/ui.h
+++ b/bin/fits/ui.h
@@ -75,6 +75,10 @@ enum option_keys_enum
UI_KEY_DATASUM,
UI_KEY_PIXELSCALE,
UI_KEY_SKYCOVERAGE,
+ UI_KEY_HASTABLEHDU,
+ UI_KEY_HASIMAGEHDU,
+ UI_KEY_LISTTABLEHDUS,
+ UI_KEY_LISTIMAGEHDUS,
UI_KEY_OUTHDU,
UI_KEY_COPYKEYS,
UI_KEY_WCSCOORDSYS,
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index b23fd9a..c81e811 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -9052,6 +9052,28 @@ It is thus useful in scripts, for example when you need
to do check the number o
For a complete list of basic meta-data on the extensions in a FITS file, don't
use any of the options in this section or in @ref{Keyword inspection and
manipulation}.
For more, see @ref{Invoking astfits}.
+@item --hastablehdu
+Print @code{1} (on standard output) if at least one table HDU (ASCII or
binary) exists in the FITS file.
+Otherwise (when no table HDU exists in the file), print @code{0}.
+
+@item --listtablehdus
+Print the names or numbers (when a name doesn't exist, counting from zero) of
HDUs that contain a table (ASCII or Binary) on standard output, one per line.
+Otherwise (when no table HDU exists in the file) nothing will be printed.
+
+@item --hasimagehdu
+Print @code{1} (on standard output) if at least one image HDU exists in the
FITS file.
+Otherwise (when no image HDU exists in the file), print @code{0}.
+
+In the FITS standard, any array with any dimensions is called an ``image'',
therefore this option includes 1, 3 and 4 dimensional arrays too.
+However, an image HDU with zero dimensions (which is usually the first
extension and only contains metadata) is not counted here.
+
+@item --listimagehdus
+Print the names or numbers (when a name doesn't exist, counting from zero) of
HDUs that contain an image on standard output, one per line.
+Otherwise (when no image HDU exists in the file) nothing will be printed.
+
+In the FITS standard, any array with any dimensions is called an ``image'',
therefore this option includes 1, 3 and 4 dimensional arrays too.
+However, an image HDU with zero dimensions (which is usually the first
extension and only contains metadata) is not counted here.
+
@item --pixelscale
Print the HDU's pixel-scale (change in world coordinate for one pixel along
each dimension) and pixel area or voxel volume.
Without the @option{--quiet} option, the output of @option{--pixelscale} has
multiple lines and explanations, thus being more human-friendly.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master ffc7608: Fits: four new options to find image/table HDUs,
Mohammad Akhlaghi <=