[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 9ad1dff7: Crop: new option to print single-pix
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 9ad1dff7: Crop: new option to print single-pixel's output to stdout |
Date: |
Sat, 11 Jun 2022 20:04:35 -0400 (EDT) |
branch: master
commit 9ad1dff71a73bdcefa3de87329fdeb2cbcc1cbcd
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Crop: new option to print single-pixel's output to stdout
Until now, Crop would always only create FITS images. However, when the
output only has a single pixel, it is highly likely that the user just
wanted to read that pixel's value. But doing this from a FITS file is
annoying (requires creation of a file for every coordinate/pixel they
want).
With this commit, Crop now has a new option called '--oneelemstdout' (or in
short '-t'). When the output has a single pixel and this option is called,
then crop will print the value on the standard output instead of a FITS
file.
This feature was suggested by Raul Infante-Sainz.
---
NEWS | 8 ++++++
bin/crop/args.h | 13 +++++++++
bin/crop/main.h | 1 +
bin/crop/onecrop.c | 84 +++++++++++++++++++++++++++++++++++-------------------
bin/crop/ui.h | 3 +-
doc/gnuastro.texi | 30 +++++++++++++++++--
6 files changed, 107 insertions(+), 32 deletions(-)
diff --git a/NEWS b/NEWS
index 7ebbe815..5527148c 100644
--- a/NEWS
+++ b/NEWS
@@ -16,6 +16,14 @@ See the end of the file for license conditions.
written with the help of S. Zahra Hosseini Shahisavandi and Sepideh
Eskandarlou.
+ Crop:
+ --oneelemstdout: when a crop has a single pixel and this option is
+ called, the single pixel's value will be printed on the standard
+ output instead of creating a FITS file. This option can be useful in
+ labeled images like detection maps (when you want to see what label a
+ certain coordiante/pixel corresponds to). This option was suggested by
+ Raul Infante-Sainz.
+
Fits:
--copykeys: can now take any number of keyword names also. For example
'--copykeys=KEYNAME1,KEYNAME2,KEYNAME3'. Until now, it was only
diff --git a/bin/crop/args.h b/bin/crop/args.h
index 725b0f46..f8f04f5b 100644
--- a/bin/crop/args.h
+++ b/bin/crop/args.h
@@ -128,6 +128,19 @@ struct argp_option program_options[] =
GAL_OPTIONS_MANDATORY,
GAL_OPTIONS_NOT_SET
},
+ {
+ "oneelemstdout",
+ UI_KEY_ONEELEMSTDOUT,
+ 0,
+ 0,
+ "Print one element's value on stdout.",
+ GAL_OPTIONS_GROUP_OUTPUT,
+ &p->oneelemstdout,
+ 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 bb6a0815..c1a2801d 100644
--- a/bin/crop/main.h
+++ b/bin/crop/main.h
@@ -119,6 +119,7 @@ struct cropparams
void *blankptrwrite; /* Null value for writing of output type.*/
struct inputimgs *imgs; /* WCS and size information for inputs. */
gal_data_t *log; /* Log file contents. */
+ int oneelemstdout; /* Print one element crops on stdout. */
};
#endif
diff --git a/bin/crop/onecrop.c b/bin/crop/onecrop.c
index 4107a562..16c2ee35 100644
--- a/bin/crop/onecrop.c
+++ b/bin/crop/onecrop.c
@@ -646,8 +646,9 @@ onecrop(struct onecropparams *crp)
struct inputimgs *img=&p->imgs[crp->in_ind];
void *array;
- int returnvalue=1;
+ char *stdoutstring;
int status=0, anynul=0;
+ int returnvalue=1, hasoneelem=1;
fitsfile *ifp=crp->infits, *ofp;
char basekeyname[FLEN_KEYWORD-5]; /* '-5': avoid gcc 8.1+ warnings! */
gal_fits_list_key_t *headers=NULL; /* See above comment for more. */
@@ -674,9 +675,15 @@ onecrop(struct onecropparams *crp)
/* Find the overlap and apply it if there is any overlap. */
if( gal_box_overlap(naxes, fpixel_i, lpixel_i, fpixel_o, lpixel_o, ndim) )
{
- /* Make the output FITS image and initialize it with an array of
- NaN or BLANK values. */
- if(crp->outfits==NULL)
+ /* See if the output only has a single element or not. */
+ for(i=0;i<ndim;++i)
+ if(fpixel_o[i]!=1 || lpixel_o[i]!=1)
+ {hasoneelem=0; break;}
+
+ /* Make the output FITS image and initialize it with an array of NaN
+ or BLANK values. But only when '--oneelemstdout' isn't called and
+ the output is single-element. */
+ if(crp->outfits==NULL && !( p->oneelemstdout && hasoneelem) )
onecrop_make_array(crp, fpixel_i, lpixel_i, fpixel_o, lpixel_o);
ofp=crp->outfits;
@@ -701,8 +708,8 @@ onecrop(struct onecropparams *crp)
onecrop_zero_to_nan(array, cropsize, p->type);
- /* If a polygon is given, remove all the pixels within or
- outside of it.*/
+ /* If a polygon is given, remove all the pixels within or outside of
+ it.*/
if(p->polygon)
{
/* A small sanity check until this part supports 3D. */
@@ -719,31 +726,50 @@ onecrop(struct onecropparams *crp)
}
- /* Write the array into the image. */
- status=0;
- if( fits_write_subset(ofp, gal_fits_type_to_datatype(p->type),
- fpixel_o, lpixel_o, array, &status) )
- gal_fits_io_error(status, NULL);
+ /* Write the output (either to a file or standard output if its a
+ single element and the user asked for it). */
+ if(crp->outfits)
+ {
+ /* Write the array into the image. */
+ status=0;
+ if( fits_write_subset(ofp, gal_fits_type_to_datatype(p->type),
+ fpixel_o, lpixel_o, array, &status) )
+ gal_fits_io_error(status, NULL);
+
+
+ /* Write the selected region of this image as a string to include as
+ a FITS keyword. Then we want to delete the last coma ','.*/
+ j=0;
+ for(i=0;i<ndim;++i)
+ j += sprintf(®ion[j], "%ld:%ld,", fpixel_i[i], lpixel_i[i]);
+ region[j-1]='\0';
+
+
+ /* A section has been added to the cropped image from this input
+ image, so save the information of this image. */
+ sprintf(basekeyname, "ICF%zu", crp->numimg);
+ gal_fits_key_write_filename(basekeyname, img->name, &headers, 0,
+ p->cp.quiet);
+ sprintf(regionkey, "%sPIX", basekeyname);
+ gal_fits_key_list_add_end(&headers, GAL_TYPE_STRING, regionkey,
+ 0, region, 0, "Range of pixels used for "
+ "this output.", 0, NULL, 0);
+ gal_fits_key_write_in_ptr(&headers, ofp);
+ }
- /* Write the selected region of this image as a string to include as
- a FITS keyword. Then we want to delete the last coma ','.*/
- j=0;
- for(i=0;i<ndim;++i)
- j += sprintf(®ion[j], "%ld:%ld,", fpixel_i[i], lpixel_i[i]);
- region[j-1]='\0';
-
-
- /* A section has been added to the cropped image from this input
- image, so save the information of this image. */
- sprintf(basekeyname, "ICF%zu", crp->numimg);
- gal_fits_key_write_filename(basekeyname, img->name, &headers, 0,
- p->cp.quiet);
- sprintf(regionkey, "%sPIX", basekeyname);
- gal_fits_key_list_add_end(&headers, GAL_TYPE_STRING, regionkey,
- 0, region, 0, "Range of pixels used for "
- "this output.", 0, NULL, 0);
- gal_fits_key_write_in_ptr(&headers, ofp);
+ /* The output should be printed in standard output. */
+ else
+ {
+ /* Convert the value into a string. If we only have a single
+ output, then print it without anything else (no identifier is
+ necessary!). Otherwise, use the desired output filename as the
+ identifier. */
+ stdoutstring=gal_type_to_string(array, p->type, 0);
+ if(p->numout==1) printf("%s\n", stdoutstring);
+ else printf("%s %s\n", crp->name, stdoutstring);
+ free(stdoutstring);
+ }
/* Free the allocated array. */
diff --git a/bin/crop/ui.h b/bin/crop/ui.h
index 8bba8b8d..c1bcee4a 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 Y
*/
enum option_keys_enum
@@ -63,6 +63,7 @@ enum option_keys_enum
UI_KEY_WIDTHINPIX = 'X',
UI_KEY_CENTER = 'c',
UI_KEY_COORDCOL = 'x',
+ UI_KEY_ONEELEMSTDOUT = 't',
/* Only with long version (start with a value 1000, the rest will be set
automatically). */
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index eb736c80..743a9496 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -14634,8 +14634,7 @@ The value must either be @option{img} or @option{wcs},
see @ref{Crop modes} for
@node Crop output, Crop known issues, Crop options, Invoking astcrop
@subsubsection Crop output
-The string given to @option{--output} option will be interpreted depending
-on how many crops were requested, see @ref{Crop modes}:
+The string given to @option{--output} option will be interpreted depending on
how many crops were requested, see @ref{Crop modes}:
@itemize
@item
@@ -14676,6 +14675,33 @@ A @code{0} if the central few pixels (value to the
@option{--checkcenter} option
When the crop was not defined by its center (see @ref{Crop modes}), or
@option{--checkcenter} was given a value of 0 (see @ref{Invoking astcrop}), the
center will not be checked and this column will be given a value of @code{-1}.
@end enumerate
+If the output crop(s) have a single element (pixel in an image) and
@option{--oneelemstdout} has been called, no output file will be produced!
+Instead, the single element's value is printed on the standard output.
+See the description of @option{--oneelemstdout} below for more:
+
+@table @option
+@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.
+By default (without this option), a single-pixel crop will be saved to a file,
just like a crop of any other size.
+
+When a single crop is requested (either through @option{--center}, or a
catalog of one row is given), the single value alone is printed with nothing
else.
+This makes it easy to immediately write the value into a shell variable for
example:
+
+@example
+value=$(astcrop img.fits --mode=wcs --center=1.234,5.678 \
+ --width=1 --widthinpix --oneelemstdout \
+ --quiet)
+@end example
+
+If a catalog of coordinates is given (that would produce multiple crops; or
multiple values in this scenario), the solution for a single value won't work!
+Recall that Crop will do the crops in parallel, therefore each time you run
it, the order of the rows will be different and not correspond to the order of
the inputs.
+
+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 won't actually be created, but
the value of the pixel it would have contained (if this option wasn't called)
is printed after it.
+@end table
+
+
@node Crop known issues, , Crop output, Invoking astcrop
@subsubsection Crop known issues
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master 9ad1dff7: Crop: new option to print single-pixel's output to stdout,
Mohammad Akhlaghi <=