[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master b57d408: Copying of a range of keywords from o
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master b57d408: Copying of a range of keywords from one HDU to another with Fits |
Date: |
Tue, 1 Jan 2019 21:12:42 -0500 (EST) |
branch: master
commit b57d408d4410b032f45ace50b957f72574e9c895
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
Copying of a range of keywords from one HDU to another with Fits
With this commit, the Fits program can copy a range of keyword records from
one HDU to another (possibly in another file).
To do this, we also had to define a blank macro for the `long' and
`unsigned long' types. Finally, since this involved a change in the library
(a start of many to come in future commits), the library Soname was
incremented to 7 (from 6).
---
NEWS | 7 ++++
bin/crop/onecrop.c | 2 +-
bin/fits/args.h | 35 +++++++++++++++++-
bin/fits/keywords.c | 88 ++++++++++++++++++++++++++++++++++++++++++--
bin/fits/main.h | 3 ++
bin/fits/ui.c | 101 ++++++++++++++++++++++++++++++++++++++++++++++++++-
bin/fits/ui.h | 2 +
configure.ac | 2 +-
doc/gnuastro.texi | 36 ++++++++++++++++++
lib/gnuastro/blank.h | 8 ++++
10 files changed, 277 insertions(+), 7 deletions(-)
diff --git a/NEWS b/NEWS
index d995c91..6ec5a75 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,13 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
`--write=datasum' (only for `DATASUM').
--verify: confirm if the `DATASUM' and `CHECKSUM' keyword values agree
with the specified HDU's content and/or data.
+ --copykeys: Copy several keyword records (in a given range) from one
+ FITS HDU/extension into another (possibly in another file).
+ --outhdu: The name/number of the output HDU (for `--copykeys').
+
+ Library:
+ GAL_BLANK_LONG: new macro for the `long' type blank value.
+ GAL_BLANK_ULONG: new macro for the `unsigned long' type blank value.
** Removed features
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index 7dcefc7..c605677 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -98,7 +98,7 @@ onecrop_parse_section(struct cropparams *p, size_t *dsize,
}
- /* Parse the string. */
+ /* Parse the string: `forl': "first-or-last". */
while(*pt!='\0')
{
add=0;
diff --git a/bin/fits/args.h b/bin/fits/args.h
index b2ecfe0..81a7570 100644
--- a/bin/fits/args.h
+++ b/bin/fits/args.h
@@ -31,7 +31,7 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
/* Array of acceptable options. */
struct argp_option program_options[] =
{
-
+ /* Input options */
{
0, 0, 0, 0,
"HDUs (extensions):",
@@ -227,9 +227,42 @@ struct argp_option program_options[] =
GAL_OPTIONS_NOT_MANDATORY,
GAL_OPTIONS_NOT_SET
},
+ {
+ "copykeys",
+ UI_KEY_COPYKEYS,
+ "STR",
+ 0,
+ "Range of keywords to copy to output HDU.",
+ UI_GROUP_KEYWORD,
+ &p->copykeys,
+ GAL_TYPE_STRING,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+
+
+
+
+
+ /* Output options. */
+ {
+ "outhdu",
+ UI_KEY_OUTHDU,
+ "STR",
+ 0,
+ "HDU/extension in output for --copykeys.",
+ GAL_OPTIONS_GROUP_OUTPUT,
+ &p->outhdu,
+ GAL_TYPE_STRING,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
+ /* Operating mode options. */
{
"quitonerror",
UI_KEY_QUITONERROR,
diff --git a/bin/fits/keywords.c b/bin/fits/keywords.c
index fbda9c4..98682ee 100644
--- a/bin/fits/keywords.c
+++ b/bin/fits/keywords.c
@@ -324,9 +324,9 @@ keywords_verify(struct fitsparams *p, fitsfile **fptr)
/* Print the verification result. */
printf("DATASUM: %s\n",
- dataok==1 ? "Verified" : ( dataok==0 ? "NOT-PRESENT" : "INCORRECT") );
+ dataok==1 ? "Verified" : (dataok==0 ? "NOT-PRESENT" : "INCORRECT"));
printf("CHECKSUM: %s\n",
- hduok==1 ? "Verified" : ( hduok==0 ? "NOT-PRESENT" : "INCORRECT") );
+ hduok==1 ? "Verified" : (hduok==0 ? "NOT-PRESENT" : "INCORRECT"));
/* Return failure if any of the keywords are not verified. */
return (dataok==-1 || hduok==-1) ? EXIT_FAILURE : EXIT_SUCCESS;
@@ -337,6 +337,68 @@ keywords_verify(struct fitsparams *p, fitsfile **fptr)
+static void
+keywords_copykeys(struct fitsparams *p, char *inkeys, size_t numinkeys)
+{
+ size_t i;
+ int status=0;
+ long initial;
+ fitsfile *fptr;
+
+ /* Initial sanity check. Since `numinkeys' includes `END' (counting from
+ 1, as we do here), the first keyword must not be larger OR EQUAL to
+ `numinkeys'. */
+ if(p->copykeysrange[0]>=numinkeys)
+ error(EXIT_FAILURE, 0, "%s (hdu %s): first keyword number give to "
+ "`--copykeys' (%ld) is larger than the number of keywords in this "
+ "header (%ld, including the `END' keyword)", p->filename, p->cp.hdu,
+ p->copykeysrange[0], numinkeys);
+
+ /* If the user wanted to count from the end (by giving a negative value),
+ then do that. */
+ if(p->copykeysrange[1]<0)
+ {
+ /* Set the last keyword requested. */
+ initial=p->copykeysrange[1];
+ p->copykeysrange[1] += numinkeys;
+
+ /* Sanity check. */
+ if(p->copykeysrange[0]>=p->copykeysrange[1])
+ error(EXIT_FAILURE, 0, "%s (hdu %s): the last keyword given to "
+ "`--copykeys' (%ld, or %ld after counting from the bottom) "
+ "is earlier than the first (%ld)", p->filename, p->cp.hdu,
+ initial, p->copykeysrange[1], p->copykeysrange[0]);
+ }
+
+ /* Final sanity check (on range limit). */
+ if(p->copykeysrange[1]>=numinkeys)
+ error(EXIT_FAILURE, 0, "%s (hdu %s): second keyword number give to "
+ "`--copykeys' (%ld) is larger than the number of keywords in this "
+ "header (%ld, including the `END' keyword)", p->filename, p->cp.hdu,
+ p->copykeysrange[1], numinkeys);
+
+
+ /* Open the output HDU. */
+ fptr=gal_fits_hdu_open(p->cp.output, p->outhdu, READWRITE);
+
+
+ /* Copy the requested headers into the output. */
+ for(i=p->copykeysrange[0]-1; i<=p->copykeysrange[1]-1; ++i)
+ if( fits_write_record(fptr, &inkeys[i*80], &status ) )
+ gal_fits_io_error(status, NULL);
+
+ /* Close the output FITS file. */
+ status=0;
+ if(fits_close_file(fptr, &status))
+ gal_fits_io_error(status, NULL);
+}
+
+
+
+
+
+
+
@@ -365,10 +427,11 @@ keywords_verify(struct fitsparams *p, fitsfile **fptr)
int
keywords(struct fitsparams *p)
{
- int status=0;
+ char *inkeys=NULL;
int r=EXIT_SUCCESS;
fitsfile *fptr=NULL;
gal_list_str_t *tstll;
+ int status=0, numinkeys;
/* Delete the requested keywords. */
@@ -479,11 +542,30 @@ keywords(struct fitsparams *p)
}
+ /* If a range of keywords must be copied, get all the keywords as a
+ single string. */
+ if(p->copykeys)
+ {
+ keywords_open(p, &fptr, READONLY);
+ if( fits_convert_hdr2str(fptr, 0, NULL, 0, &inkeys, &numinkeys,
+ &status) )
+ gal_fits_io_error(status, NULL);
+ status=0;
+ }
+
+
/* Close the FITS file */
if(fits_close_file(fptr, &status))
gal_fits_io_error(status, NULL);
+ /* Write desired keywords into output. */
+ if(p->copykeys)
+ {
+ keywords_copykeys(p, inkeys, numinkeys);
+ free(inkeys);
+ }
+
/* Return. */
return r;
}
diff --git a/bin/fits/main.h b/bin/fits/main.h
index 78f0054..299ff71 100644
--- a/bin/fits/main.h
+++ b/bin/fits/main.h
@@ -56,6 +56,7 @@ struct fitsparams
struct gal_options_common_params cp; /* Common parameters. */
int hdu_in_commandline; /* HDU wasn't given in config. file. */
char *filename; /* Name of input file. */
+ char *outhdu; /* HDU of output (only when necessary). */
gal_list_str_t *remove; /* Remove extensions from a file. */
gal_list_str_t *copy; /* Copy extensions to output. */
gal_list_str_t *cut; /* Copy ext. to output and remove. */
@@ -70,10 +71,12 @@ struct fitsparams
gal_list_str_t *history; /* HISTORY value. */
gal_list_str_t *comment; /* COMMENT value. */
uint8_t *verify; /* Verify the CHECKSUM and DATASUM keys. */
+ char *copykeys; /* Range of keywords to copy in output. */
uint8_t quitonerror; /* Quit if an error occurs. */
/* Internal: */
int mode; /* Operating on HDUs or keywords. */
+ long copykeysrange[2]; /* Start and end of copy. */
gal_fits_list_key_t *write_keys; /* Keys to write in the header. */
gal_fits_list_key_t *update_keys; /* Keys to update in the header. */
time_t rawtime; /* Starting time of the program. */
diff --git a/bin/fits/ui.c b/bin/fits/ui.c
index 1674865..25da309 100644
--- a/bin/fits/ui.c
+++ b/bin/fits/ui.c
@@ -217,6 +217,100 @@ parse_opt(int key, char *arg, struct argp_state *state)
/**************************************************************/
/*************** Sanity Check *******************/
/**************************************************************/
+static void
+ui_check_copykeys(struct fitsparams *p)
+{
+ long read;
+ char *tailptr;
+ size_t group=0;
+ char forl='f', *pt=p->copykeys;
+
+ /* Initialize the values. */
+ p->copykeysrange[0]=p->copykeysrange[1]=GAL_BLANK_LONG;
+
+ /* Parse the string: `forl': "first-or-last". */
+ while(*pt!='\0')
+ {
+ switch(*pt)
+ {
+ case ':':
+ forl='l';
+ ++pt;
+ break;
+ case '.':
+ error(EXIT_FAILURE, 0, "the numbers in the argument to "
+ "`--section` (`-s') have to be integers. You input "
+ "includes a float number: %s", p->copykeys);
+ break;
+ case ' ': case '\t':
+ ++pt;
+ break;
+
+ /* Numerical characters signify the start of a number, so we don't
+ need to increment the pointer and can just break out. */
+ case '0': case '1': case '2': case '3': case '4': case '5':
+ case '6': case '7': case '8': case '9': case '-':
+ break;
+
+ /* An un-recognized character should crash the program. */
+ case ',':
+ ++group;
+ forl='f';
+ ++pt;
+
+ /* For the time being, we just support one group. So we are
+ commenting the break here for it to follow onto default.
+ break;
+ */
+ default:
+ error(EXIT_FAILURE, 0, "value to `--copykeys' must only contain "
+ "integer numbers and these special characters between them: "
+ "`,', `:', `*' when necessary. But it is `%s' (the first "
+ "non-acceptable character is `%c').\n", p->copykeys, *pt);
+ break;
+ }
+
+ /* Read the number: */
+ read=strtol(pt, &tailptr, 0);
+
+ /* Check the progress.
+ printf("\n\n------\n%c: %ld (%s)\n", *pt, read, tailptr);
+ */
+
+ /* Make sure if a number was read at all? */
+ if(tailptr==pt) continue; /* No number was read! */
+
+ /* Put it in the correct place. */
+ p->copykeysrange[ forl=='f' ? 0 : 1 ]=read;
+ pt=tailptr;
+ }
+
+ /* Basic sanity checks. */
+ if( p->copykeysrange[1]==GAL_BLANK_LONG )
+ error(EXIT_FAILURE, 0, "no ending keyword number given to `--copykeys'. "
+ "If you want to copy all the keywords after a certain one "
+ "(without worrying about how many there are), you can use `-1'.\n\n"
+ "For example if you want to copy all the keywords after the 20th, "
+ "you can use `--copykeys=20,-1'. Generally, you can use negative "
+ "numbers for the last keyword number to count from the end.");
+ if( p->copykeysrange[0]<=0 )
+ error(EXIT_FAILURE, 0, "the first number given to `--copykeys' must be "
+ "positive");
+ if( p->copykeysrange[1]>=0 && p->copykeysrange[0]>=p->copykeysrange[1] )
+ error(EXIT_FAILURE, 0, "the first number (%ld) given to `--copykeys' "
+ "must be smaller than the second (%ld)", p->copykeysrange[0],
+ p->copykeysrange[1]);
+
+ /* For a check:
+ printf("copykeys: %ld, %ld\n", p->copykeysrange[0], p->copykeysrange[1]);
+ exit(0);
+ */
+}
+
+
+
+
+
/* Read and check ONLY the options. When arguments are involved, do the
check in `ui_check_options_and_arguments'. */
static void
@@ -225,7 +319,8 @@ ui_read_check_only_options(struct fitsparams *p)
/* If any of the keyword manipulation options are requested, then set the
mode flag to keyword-mode. */
if( p->date || p->comment || p->history || p->asis || p->delete
- || p->rename || p->update || p->write || p->verify || p->printallkeys )
+ || p->rename || p->update || p->write || p->verify || p->printallkeys
+ || p->copykeys )
{
/* Set the mode. */
p->mode=FITS_MODE_KEY;
@@ -235,6 +330,10 @@ ui_read_check_only_options(struct fitsparams *p)
error(EXIT_FAILURE, 0, "a HDU (extension) is necessary for keywrod "
"related options but none was defined. Please use the "
"`--hdu' (or `-h') option to select one");
+
+ /* If Copy keys has been given, read it and make sure its setup. */
+ if(p->copykeys)
+ ui_check_copykeys(p);
}
/* Same for the extension-related options */
diff --git a/bin/fits/ui.h b/bin/fits/ui.h
index 3df455a..f96dce6 100644
--- a/bin/fits/ui.h
+++ b/bin/fits/ui.h
@@ -69,6 +69,8 @@ enum option_keys_enum
/* Only with long version (start with a value 1000, the rest will be set
automatically). */
UI_KEY_TITLE = 1000,
+ UI_KEY_OUTHDU,
+ UI_KEY_COPYKEYS,
};
diff --git a/configure.ac b/configure.ac
index 6313a4d..068070f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -50,7 +50,7 @@ AC_CONFIG_MACRO_DIRS([bootstrapped/m4])
# Library version, see the GNU Libtool manual ("Library interface versions"
# section for the exact definition of each) for
-GAL_CURRENT=6
+GAL_CURRENT=7
GAL_REVISION=0
GAL_AGE=0
GAL_LT_VERSION="${GAL_CURRENT}:${GAL_REVISION}:${GAL_AGE}"
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 53e2900..9f14ed4 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -10146,6 +10146,8 @@ effect then the update operations.
@option{--printallkeys}
@item
@option{--verify}
address@hidden
address@hidden
@end enumerate
@noindent
All possible syntax errors will be reported before the keywords are
@@ -10405,6 +10407,30 @@ By default this function will also print a short
description of the
@code{DATASUM} AND @code{CHECKSUM} keywords. You can supress this extra
information with @code{--quiet} option.
address@hidden --copykeys=INT:INT
+Copy the input's keyword records in the given range (inclusive) to the
+output HDU (specified with the @option{--output} and @option{--outhdu}
+options, for the filename and HDU/extension respectively).
+
+The given string to this option must be two integers separated by a colon
+(@key{:}). The first integer must be positive (counting of the keyword
+records starts from 1). The second integer may be negative (zero is not
+acceptable) or an integer larger than the first.
+
+A negative second integer means counting from the end. So @code{-1} is the
+last copy-able keyword (not including the @code{END} keyword).
+
+To see the header keywords of the input with a number before them, you can
+pipe the output of the FITS program (when it prints all the keywords in an
+extension) into the @command{cat} program like below:
+
address@hidden
+$ astfits input.fits -h1 | cat -n
address@hidden example
+
address@hidden --outhdu
+The HDU/extension to write the output keywords of @option{--copykeys}.
+
@item -Q
@itemx --quitonerror
Quit if any of the operations above are not successful. By default if
@@ -23570,6 +23596,16 @@ Blank value for an unsigned, 64-bit integer.
Blank value for a signed, 64-bit integer.
@end deffn
address@hidden {Global integer} GAL_BLANK_LONG
+Blank value for @code{long} type (@code{int32_t} or @code{int64_t} in
+32-bit or 64-bit systems).
address@hidden deffn
+
address@hidden {Global integer} GAL_BLANK_ULONG
+Blank value for @code{unsigned long} type (@code{uint32_t} or
address@hidden in 32-bit or 64-bit systems).
address@hidden deffn
+
@deffn {Global integer} GAL_BLANK_SIZE_T
Blank value for @code{size_t} type (@code{uint32_t} or @code{uint64_t} in
32-bit or 64-bit systems).
diff --git a/lib/gnuastro/blank.h b/lib/gnuastro/blank.h
index 7e36214..ba92425 100644
--- a/lib/gnuastro/blank.h
+++ b/lib/gnuastro/blank.h
@@ -81,6 +81,14 @@ __BEGIN_C_DECLS /* From C++ preparations */
#define GAL_BLANK_SIZE_T GAL_BLANK_UINT64
#endif
+#if GAL_CONFIG_SIZEOF_LONG == 4
+#define GAL_BLANK_LONG GAL_BLANK_INT32
+#define GAL_BLANK_ULONG GAL_BLANK_UINT32
+#elif GAL_CONFIG_SIZEOF_LONG == 8
+#define GAL_BLANK_LONG GAL_BLANK_INT64
+#define GAL_BLANK_ULONG GAL_BLANK_UINT64
+#endif
+
/* Functions. */
void
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master b57d408: Copying of a range of keywords from one HDU to another with Fits,
Mohammad Akhlaghi <=