[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 7564d430: Crop: new --append operator to add c
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 7564d430: Crop: new --append operator to add crop as new HDU fo output |
Date: |
Sun, 30 Oct 2022 12:30:33 -0400 (EDT) |
branch: master
commit 7564d430421ecacfac36d50f0ca663bf0337409f
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Crop: new --append operator to add crop as new HDU fo output
Until now, Crop would always delete the output file if it already
existed. However, in some scenarios, it is necessary keep existing HDUs and
just append the new crop to them. To do this, it was necessary to put the
cropped HDU in a temporary file, then use 'astfits' to copy that HDU into
the file with existing HDUs. But this is an annoying extra step (given that
the low-level structure to preserve the HDUs is already present in crop).
With this commit, a new '--append' option has been added for this job. When
it is called, if the output file already exists, the cropped HDU will be
written after the last HDU. An example usage of this to crop all image-HDUs
of a file has been added at the example commands in the "Invoking Crop"
section of the book.
In the process, I also noticed that Crop's output options weren't listed in
the "Crop output" sub-section of the "invoking Crop" section. They have
also been moved there with this commit.
This issue was implemented after a discussion with Michael Stein and Elham
Saremi.
---
NEWS | 3 +
bin/crop/args.h | 13 ++++
bin/crop/main.h | 1 +
bin/crop/onecrop.c | 42 +++++++-----
bin/crop/ui.c | 7 +-
bin/crop/ui.h | 3 +-
bin/mkprof/ui.c | 2 +-
doc/announce-acknowledge.txt | 1 +
doc/gnuastro.texi | 139 ++++++++++++++++++++-------------------
lib/checkset.c | 4 +-
lib/gnuastro-internal/checkset.h | 2 +-
11 files changed, 125 insertions(+), 92 deletions(-)
diff --git a/NEWS b/NEWS
index c2963b45..6c679098 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,9 @@ See the end of the file for license conditions.
- counteronly: similar to 'counter', but pops the top stack dataset.
Crop:
+ --append: if the output file already exists, append the cropped image
+ HDU to the already existing HDUs of the file. Without this option, any
+ existing HDUs in the output file will be removed (default behavior).
--metaname: Specify the name of the cropped output HDU (value to the
'EXTNAME' keyword in FITS).
diff --git a/bin/crop/args.h b/bin/crop/args.h
index 97fcc435..50152a64 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -154,6 +154,19 @@ struct argp_option program_options[] =
GAL_OPTIONS_MANDATORY,
GAL_OPTIONS_NOT_SET
},
+ {
+ "append",
+ UI_KEY_APPEND,
+ 0,
+ 0,
+ "If output exists, append crop to existing HDUs.",
+ GAL_OPTIONS_GROUP_OUTPUT,
+ &p->append,
+ GAL_OPTIONS_NO_ARG_TYPE,
+ GAL_OPTIONS_RANGE_0_OR_1,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET
+ },
diff --git a/bin/crop/main.h b/bin/crop/main.h
index b0ccc505..706d7cdf 100644
--- a/bin/crop/main.h
+++ b/bin/crop/main.h
@@ -86,6 +86,7 @@ struct cropparams
int mode; /* Image or WCS mode. */
uint8_t zeroisnotblank; /* ==1: In float or double, keep 0.0. */
uint8_t primaryimghdu; /* ==1: write in primary/0-th HDU. */
+ uint8_t append; /* If output exists, append crop. */
uint8_t noblank; /* ==1: no blank (out of image) pixels. */
char *suffix; /* Ending of output file name. */
gal_data_t *incheckcenter; /* Value given to '--checkcenter'. */
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index de267552..537b1a53 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -405,7 +405,7 @@ onecrop_name(struct onecropparams *crp)
error(EXIT_FAILURE, 0, "%s: asprintf allocation", __func__);
/* Make sure the file doesn't exist. */
- gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
+ gal_checkset_writable_remove(crp->name, cp->keep, cp->dontdelete);
}
else
{
@@ -413,12 +413,14 @@ onecrop_name(struct onecropparams *crp)
if(p->outnameisfile) /* An output file was specified. */
{
crp->name=cp->output;
- gal_checkset_writable_remove(crp->name, 0, cp->dontdelete);
+ gal_checkset_writable_remove(crp->name, cp->keep, cp->dontdelete);
}
else /* The output was a directory, use automatic output. */
+ {
crp->name=gal_checkset_automatic_output(cp,
p->imgs[crp->in_ind].name,
p->suffix);
+ }
}
}
@@ -516,19 +518,21 @@ static void
onecrop_make_array(struct onecropparams *crp, long *fpixel_i,
long *lpixel_i, long *fpixel_c, long *lpixel_c)
{
+ struct cropparams *p=crp->p;
+
double crpix;
fitsfile *ofp;
long naxes[MAXDIM];
char *outname=crp->name;
- int status=0, type=crp->p->type;
+ int status=0, type=p->type;
char **strarr, cpname[FLEN_KEYWORD];
+ size_t i, ndim=p->imgs->ndim, totsize;
gal_data_t *rkey=gal_data_array_calloc(1);
- size_t i, ndim=crp->p->imgs->ndim, totsize;
- struct inputimgs *img=&crp->p->imgs[crp->in_ind];
+ struct inputimgs *img=&p->imgs[crp->in_ind];
/* Set the size of the output, in WCS mode, noblank==0. */
- if(crp->p->noblank && crp->p->mode==IMGCROP_MODE_IMG)
+ if(p->noblank && p->mode==IMGCROP_MODE_IMG)
for(i=0;i<ndim;++i)
{
fpixel_c[i] = 1;
@@ -541,15 +545,19 @@ onecrop_make_array(struct onecropparams *crp, long
*fpixel_i,
/* Create the FITS file with a blank first extension, then close it, so
with the next 'fits_open_file', we build the image in the second
- extension. This way, atleast for Gnuastro's outputs, we can
- consistently use '-h1' (something like how you count columns, or
- generally everything from 1). */
- if(fits_create_file(&ofp, outname, &status))
- gal_fits_io_error(status, "creating file");
- if(crp->p->primaryimghdu==0)
+ extension. But only if the user didn't want the append the crop to an
+ existing file or if the file doesn't exist at all. This way, at least
+ for Gnuastro's outputs, we can consistently use '-h1' (something like
+ how you count columns, or generally everything from 1). */
+ if(p->append==0 || gal_checkset_check_file_return(outname)==0)
{
- fits_create_img(ofp, SHORT_IMG, 0, naxes, &status);
- fits_close_file(ofp, &status);
+ if(fits_create_file(&ofp, outname, &status))
+ gal_fits_io_error(status, "creating file");
+ if(p->primaryimghdu==0)
+ {
+ fits_create_img(ofp, SHORT_IMG, 0, naxes, &status);
+ fits_close_file(ofp, &status);
+ }
}
@@ -574,7 +582,7 @@ onecrop_make_array(struct onecropparams *crp, long
*fpixel_i,
/* Name of extension. */
- fits_update_key(ofp, TSTRING, "EXTNAME", crp->p->metaname,
+ fits_update_key(ofp, TSTRING, "EXTNAME", p->metaname,
"Name of HDU (extension).", &status);
gal_fits_io_error(status, "writing EXTNAME");
@@ -597,8 +605,8 @@ onecrop_make_array(struct onecropparams *crp, long
*fpixel_i,
/* Write the blank value as a FITS keyword if necessary. */
if( type!=GAL_TYPE_FLOAT32 && type!=GAL_TYPE_FLOAT64 )
- if(fits_write_key(ofp, gal_fits_type_to_datatype(crp->p->type), "BLANK",
- crp->p->blankptrwrite, "Pixels with no data.",
+ if(fits_write_key(ofp, gal_fits_type_to_datatype(type), "BLANK",
+ p->blankptrwrite, "Pixels with no data.",
&status) )
gal_fits_io_error(status, "adding Blank");
totsize = naxes[0]*naxes[1] * (ndim==3?naxes[2]:1);
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index 30b775f8..d5da5507 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -433,6 +433,10 @@ ui_read_check_only_options(struct cropparams *p)
if(p->mode==IMGCROP_MODE_WCS && p->noblank)
error(EXIT_FAILURE, 0, "'--noblanks' ('-b') is only for image mode. "
"You have called it with WCS mode");
+
+ /* If '--apend' has been called, set 'cp.keep' to 1 (since we don't want
+ to delete the output file). */
+ if(p->append) p->cp.keep=1;
}
@@ -501,8 +505,7 @@ ui_check_options_and_arguments(struct cropparams *p)
else
{
p->cp.numthreads=1;
- p->outnameisfile=gal_checkset_dir_0_file_1(p->cp.output,
- p->cp.dontdelete);
+ p->outnameisfile=gal_checkset_dir_0_file_1(&p->cp, p->cp.output);
}
}
diff --git a/bin/crop/ui.h b/bin/crop/ui.h
index d5068e5d..056c76d5 100644
--- a/bin/crop/ui.h
+++ b/bin/crop/ui.h
@@ -46,7 +46,7 @@ enum program_args_groups
/* Available letters for short options:
d e f g i j k m r u v y
- A B E G H J L Q R W Y
+ B E G H J L Q R W Y
*/
enum option_keys_enum
{
@@ -65,6 +65,7 @@ enum option_keys_enum
UI_KEY_COORDCOL = 'x',
UI_KEY_ONEELEMSTDOUT = 't',
UI_KEY_METANAME = 'a',
+ UI_KEY_APPEND = 'A',
/* Only with long version (start with a value 1000, the rest will be set
automatically). */
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 0aebbc88..3ac0f5e9 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -636,7 +636,7 @@ ui_check_options_and_arguments(struct mkprofparams *p)
/* Set the necessary output names. */
- d0f1=gal_checkset_dir_0_file_1(p->cp.output, p->cp.dontdelete);
+ d0f1=gal_checkset_dir_0_file_1(&p->cp, p->cp.output);
if(d0f1) /* --output is a file name. */
{
p->mergedimgname=p->cp.output;
diff --git a/doc/announce-acknowledge.txt b/doc/announce-acknowledge.txt
index 991973ad..654805b2 100644
--- a/doc/announce-acknowledge.txt
+++ b/doc/announce-acknowledge.txt
@@ -2,6 +2,7 @@ Alphabetically ordered list to acknowledge in the next release.
Sepideh Eskandarlou
Giulia Golini
+Elham Saremi
Michael Stein
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index c82eccc3..0bb1d33c 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15654,6 +15654,13 @@ $ astcrop --mode=wcs --center=12h36m40.08,62d13m5.53
goodsnorth.fits
## Crop region around pixel coordinate (568.342, 2091.719):
$ astcrop --mode=img --center=568.342,2091.719 --width=201 image.fits
+
+## Crop all HDUs within a FITS file at a certain coordinate, while
+## preserving the names of the HDUs in the output.
+$ for hdu in $(astfits input.fits --listimagehdus); do \
+ astcrop input.fits --hdu=$$hdu --append --output=crop.fits \
+ --metaname=$$hdu --mode=wcs --center=189.16704,62.218203
+ done
@end example
@noindent
@@ -15743,6 +15750,11 @@ The number of values given to this option must be the
same as the dimensions of
The width of the crop should be set with @code{--width}.
The units of the coordinates are read based on the value to the
@option{--mode} option, see below.
+@item -O STR
+@itemx --mode=STR
+Mode to interpret the crop's coordinates (for example with @option{--center},
@option{--catalog} or @option{--polygon}).
+The value must either be @option{img} (to assume image/pixel coordinates) or
@option{wcs} (to assume WCS, usually RA/Dec, coordinates), see @ref{Crop modes}
for a full description.
+
@item -w FLT[,FLT[,...]]
@itemx --width=FLT[,FLT[,...]]
Width of the cropped region about coordinate given to @option{--center}.
@@ -15891,72 +15903,6 @@ When this column is not given, the row number will be
used instead.
@end table
-@noindent
-Output options:
-@table @option
-
-@item -a STR
-@itemx --metaname=STR
-Name of cropped HDU (value to the @code{EXTNAME} keyword of FITS).
-If not given, a default @code{CROP} will be placed there (so the
@code{EXTNAME} keyword will always be present in the output).
-If crop produces many outputs from a catalog, they will be given the same
string as @code{EXTNAME} (the file names containing the cropped HDU will be
different).
-
-@item -c FLT/INT
-@itemx --checkcenter=FLT/INT
-@cindex Check center of crop
-Square box width of region in the center of the image to check for blank
values.
-If any of the pixels in this central region of a crop (defined by its center)
are blank, then it will not be stored in an output file.
-If the value to this option is zero, no checking is done.
-This check is only applied when the cropped region(s) are defined by their
center (not by the vertices, see @ref{Crop modes}).
-
-The units of the value are interpreted based on the @option{--mode} value (in
WCS or pixel units).
-The ultimate checked region size (in pixels) will be an odd integer around the
center (converted from WCS, or when an even number of pixels are given to this
option).
-In WCS mode, the value can be given as fractions, for example, if the WCS
units are in degrees, @code{0.1/3600} will correspond to a check size of 0.1
arcseconds.
-
-Because survey regions do not often have a clean square or rectangle shape,
some of the pixels on the sides of the survey FITS image do not commonly have
any data and are blank (see @ref{Blank pixels}).
-So when the catalog was not generated from the input image, it often happens
that the image does not have data over some of the points.
-
-When the given center of a crop falls in such regions or outside the dataset,
and this option has a non-zero value, no crop will be created.
-Therefore with this option, you can specify a width of a small box (3 pixels
is often good enough) around the central pixel of the cropped image.
-You can check which crops were created and which were not from the
command-line (if @option{--quiet} was not called, see @ref{Operating mode
options}), or in Crop's log file (see @ref{Crop output}).
-
-@item -p STR
-@itemx --suffix=STR
-The suffix (or post-fix) of the output files for when you want all the cropped
images to have a special ending.
-One case where this might be helpful is when besides the science images, you
want the weight images (or exposure maps, which are also distributed with
survey images) of the cropped regions too.
-So in one run, you can set the input images to the science images and
@option{--suffix=_s.fits}.
-In the next run you can set the weight images as input and
@option{--suffix=_w.fits}.
-
-@item --primaryimghdu
-Write the output into the primary (0-th) HDU/extension of the output.
-By default, like all Gnuastro's default outputs, no data is written in the
primary extension because the FITS standard suggests keeping that extension
free of data and only for meta data.
-
-@item -b
-@itemx --noblank
-Pixels outside of the input image that are in the crop box will not be used.
-By default they are filled with blank values (depending on type), see
@ref{Blank pixels}.
-This option only applies only in Image mode, see @ref{Crop modes}.
-
-@item -z
-@itemx --zeroisnotblank
-In float or double images, it is common to give the value of zero to blank
pixels.
-If the input image type is one of these two types, such pixels will also be
considered as blank.
-You can disable this behavior with this option, see @ref{Blank pixels}.
-
-@end table
-
-@noindent
-Operating mode options:
-@table @option
-
-@item -O STR
-@itemx --mode=STR
-Operate in Image mode or WCS mode when the input coordinates can be both image
or WCS.
-The value must either be @option{img} or @option{wcs}, see @ref{Crop modes}
for a full description.
-
-@end table
-
-
@@ -15982,6 +15928,9 @@ By default, as suggested by the FITS standard and
implemented in all Gnuastro pr
The cropped images/cubes will be written into the 2nd HDU of their respective
FITS file (which is actually counted as @code{1} because HDU counting starts
from @code{0}).
However, if you want the cropped data to be written into the primary (0-th)
HDU, run Crop with the @option{--primaryimghdu} option.
+If the output file already exists by default Crop will re-write it (so that
all existing HDUs in it will be deleted).
+If you want the cropped HDU to be appended to existing HDUs, use
@option{--append} described below.
+
The header of each output cropped image will contain the names of the input
image(s) it was cut from.
If a name is longer than the 70 character space that the FITS standard allows
for header keyword values, the name will be cut into several keywords from the
nearest slash (@key{/}).
The keywords have the following format: @command{ICFn_m} (for Crop File).
@@ -16009,6 +15958,29 @@ Instead, the single element's value is printed on the
standard output.
See the description of @option{--oneelemstdout} below for more:
@table @option
+@item -p STR
+@itemx --suffix=STR
+The suffix (or post-fix) of the output files for when you want all the cropped
images to have a special ending.
+One case where this might be helpful is when besides the science images, you
want the weight images (or exposure maps, which are also distributed with
survey images) of the cropped regions too.
+So in one run, you can set the input images to the science images and
@option{--suffix=_s.fits}.
+In the next run you can set the weight images as input and
@option{--suffix=_w.fits}.
+
+@item -a STR
+@itemx --metaname=STR
+Name of cropped HDU (value to the @code{EXTNAME} keyword of FITS).
+If not given, a default @code{CROP} will be placed there (so the
@code{EXTNAME} keyword will always be present in the output).
+If crop produces many outputs from a catalog, they will be given the same
string as @code{EXTNAME} (the file names containing the cropped HDU will be
different).
+
+@item -A
+@itemx --append
+If the output file already exists, append the cropped image HDU to the end of
any existing HDUs.
+By default (when this option isn't given), if an output file already exists,
any exisitng HDU in it will be deleted.
+If the output file doesn't exist, this option is redundant.
+
+@item --primaryimghdu
+Write the output into the primary (0-th) HDU/extension of the output.
+By default, like all Gnuastro's default outputs, no data is written in the
primary extension because the FITS standard suggests keeping that extension
free of data and only for meta data.
+
@item -t
@itemx --oneelemstdout
When a crop only has a single element (a single pixel), print it to the
standard output instead of making a file.
@@ -16028,6 +16000,37 @@ Recall that Crop will do the crops in parallel,
therefore each time you run it,
To allow identification of each value (which row of the input catalog it
corresponds to), Crop will first print the name of the would-be created file
name, and print the value after it (separated by an empty SPACE character).
In other words, the file in the first column will not actually be created, but
the value of the pixel it would have contained (if this option was not called)
is printed after it.
+
+@item -c FLT/INT
+@itemx --checkcenter=FLT/INT
+@cindex Check center of crop
+Square box width of region in the center of the image to check for blank
values.
+If any of the pixels in this central region of a crop (defined by its center)
are blank, then it will not be stored in an output file.
+If the value to this option is zero, no checking is done.
+This check is only applied when the cropped region(s) are defined by their
center (not by the vertices, see @ref{Crop modes}).
+
+The units of the value are interpreted based on the @option{--mode} value (in
WCS or pixel units).
+The ultimate checked region size (in pixels) will be an odd integer around the
center (converted from WCS, or when an even number of pixels are given to this
option).
+In WCS mode, the value can be given as fractions, for example, if the WCS
units are in degrees, @code{0.1/3600} will correspond to a check size of 0.1
arcseconds.
+
+Because survey regions do not often have a clean square or rectangle shape,
some of the pixels on the sides of the survey FITS image do not commonly have
any data and are blank (see @ref{Blank pixels}).
+So when the catalog was not generated from the input image, it often happens
that the image does not have data over some of the points.
+
+When the given center of a crop falls in such regions or outside the dataset,
and this option has a non-zero value, no crop will be created.
+Therefore with this option, you can specify a width of a small box (3 pixels
is often good enough) around the central pixel of the cropped image.
+You can check which crops were created and which were not from the
command-line (if @option{--quiet} was not called, see @ref{Operating mode
options}), or in Crop's log file (see @ref{Crop output}).
+
+@item -b
+@itemx --noblank
+Pixels outside of the input image that are in the crop box will not be used.
+By default they are filled with blank values (depending on type), see
@ref{Blank pixels}.
+This option only applies only in Image mode, see @ref{Crop modes}.
+
+@item -z
+@itemx --zeroisnotblank
+In float or double images, it is common to give the value of zero to blank
pixels.
+If the input image type is one of these two types, such pixels will also be
considered as blank.
+You can disable this behavior with this option, see @ref{Blank pixels}.
@end table
@@ -18053,8 +18056,8 @@ With the command below, we will be masking all pixels
that are 20 pixels away fr
Here is a description of the command below (for the basics of Arithmetic's
notation, see @ref{Reverse polish notation}):
@itemize
@item
-The @code{index} operator just adds a new dataset on the stack: unlike almost
all other operators in Arithmetic, @code{index} doesn't remove the dataset
within @file{image.fits} from the stack (use @code{indexonly} for the
``normal'' behavior).
-This is because @code{index} is returns the pixel metadata not data.
+The @code{index} operator just adds a new dataset on the stack: unlike almost
all other operators in Arithmetic, @code{index} doesn't remove its input
dataset from the stack (use @code{indexonly} for the ``normal'' behavior).
+This is because @code{index} returns the pixel metadata not data.
As a result, after @code{index}, we have two operands on the stack: the input
image and the index image.
@item
With the @code{set-i} operator, the top operand (the image containing the
index of each pixel) is popped from the stack and associated to the name
@code{i}.
diff --git a/lib/checkset.c b/lib/checkset.c
index bf2948a1..04a8f940 100644
--- a/lib/checkset.c
+++ b/lib/checkset.c
@@ -774,7 +774,7 @@ gal_checkset_writable_remove(char *filename, int keep, int
dontdelete)
a directory) it will return 0. Finally, if it exists but cannot be
deleted, report an error and abort. */
int
-gal_checkset_dir_0_file_1(char *name, int dontdelete)
+gal_checkset_dir_0_file_1(struct gal_options_common_params *cp, char *name)
{
FILE *tmpfile;
struct stat nameinfo;
@@ -813,7 +813,7 @@ gal_checkset_dir_0_file_1(char *name, int dontdelete)
return 0;
else if (S_ISREG(nameinfo.st_mode)) /* It is a file, GOOD. */
{
- gal_checkset_writable_remove(name, 0, dontdelete);
+ gal_checkset_writable_remove(name, cp->keep, cp->dontdelete);
return 1;
}
else /* Not a file or a dir, ABORT */
diff --git a/lib/gnuastro-internal/checkset.h b/lib/gnuastro-internal/checkset.h
index d3628e21..9093f7ca 100644
--- a/lib/gnuastro-internal/checkset.h
+++ b/lib/gnuastro-internal/checkset.h
@@ -127,7 +127,7 @@ void /* keep==0 && dontdelete==0: file will be deleted
if exists.*/
gal_checkset_writable_remove(char *filename, int keep, int dontdelete);
int
-gal_checkset_dir_0_file_1(char *name, int dontdelete);
+gal_checkset_dir_0_file_1(struct gal_options_common_params *cp, char *name);
char *
gal_checkset_automatic_output(struct gal_options_common_params *cp,
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master 7564d430: Crop: new --append operator to add crop as new HDU fo output,
Mohammad Akhlaghi <=