[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master d02c999 079/113: Recent work in master importe
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master d02c999 079/113: Recent work in master imported, conflicts fixed |
Date: |
Fri, 16 Apr 2021 10:33:52 -0400 (EDT) |
branch: master
commit d02c9998aaad8c87d77deabfd7f5311497450d14
Merge: 4021652 388c6be
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Recent work in master imported, conflicts fixed
Conflicts due to the new minimum and maximum position columns of
MakeCatalog were fixed and are now merged into this branch.
---
NEWS | 14 ++-
bin/arithmetic/arithmetic.c | 19 +++-
bin/arithmetic/main.h | 5 +-
bin/arithmetic/operands.c | 211 ++++++++++++++++++++++++++++++++++++++++----
bin/arithmetic/operands.h | 5 ++
bin/arithmetic/ui.c | 40 +++++----
bin/buildprog/Makefile.am | 35 +++++---
bin/mkcatalog/args.h | 56 ++++++++++++
bin/mkcatalog/columns.c | 113 ++++++++++++++++++++++++
bin/mkcatalog/main.h | 4 +
bin/mkcatalog/parse.c | 28 +++++-
bin/mkcatalog/ui.c | 4 +
bin/mkcatalog/ui.h | 4 +
doc/gnuastro.en.html | 5 +-
doc/gnuastro.fr.html | 8 +-
doc/gnuastro.texi | 80 +++++++++++++++--
lib/array.c | 20 ++++-
lib/gnuastro/array.h | 3 +
18 files changed, 590 insertions(+), 64 deletions(-)
diff --git a/NEWS b/NEWS
index 07b2347..a0c9680 100644
--- a/NEWS
+++ b/NEWS
@@ -9,14 +9,24 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
--enable-check-with-valgrind: Run `make check' tests within Valgrind.
Arithmetic:
+ - `set-A': Set a name (`A' in this case) for the popped dataset. This
+ allows only reading the dataset it into memory once and
+ possibly using it many times.
- `collapse-sum': collapse/remove a dimension by summing over it.
- `collapse-mean': collapse/remove a dimension by averaging over it.
- `collapse-number': Number of elements included in the collapse.
+ MakeCatalog:
+ --minx: minimum position along first FITS axis.
+ --maxx: maximum position along first FITS axis.
+ --miny: minimum position along second FITS axis.
+ --maxy: maximum position along second FITS axis.
+
Table:
--colinfoinstdout: column information when writing to standard output.
Library:
+ - gal_array_name_recognized_multiext: If format contains multiple datasets.
- gal_dimension_collapse_sum: collapse/remove a dimension by summing.
- gal_dimension_collapse_mean: collapse/remove a dimension by averaging.
- gal_dimension_collapse_number: collapse/remove a dimension by number.
@@ -43,13 +53,13 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
bug #54063: Match tests in make check fail randomly.
bug #54186: MakeCatalog's --checkupperlimit not keeping output's name.
bug #54188: MakeCatalog's Upperlimit not being sigma-clipped properly.
- bug #54284: Crop segrault when catalog contains no data.
+ bug #54284: Crop segfault when catalog contains no data.
bug #54285: make check fails if g++ not present.
bug #54286: BuildProgram's configuration file, not built by default.
bug #54297: No Match output when --notmatched called and no match.
bug #54298: Table not writing array when there are no rows.
bug #54312: Crash when CFITSIO doesn't have fits_is_reentrant function.
-
+ bug #54346: Non '-I' or non '-L' strings in CPPFLAGS or LDFLAGS cause crash.
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index f83e461..ba8ef38 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -817,10 +817,14 @@ reversepolish(struct arithmeticparams *p)
/* If we have a name or number, then add it to the operands linked
list. Otherwise, pull out two members and do the specified
operation on them. */
- if(gal_array_name_recognized(token->v))
+ if( gal_array_name_recognized(token->v)
+ || operands_is_name(p, token->v) )
operands_add(p, token->v, NULL);
else if( (d1=gal_data_copy_string_to_number(token->v)) )
operands_add(p, NULL, d1);
+ else if( !strncmp(token->v, SET_OPERATOR_PREFIX,
+ SET_OPERATOR_PREFIX_LENGTH) )
+ operands_set_name(p, token->v);
else
{
@@ -969,7 +973,7 @@ reversepolish(struct arithmeticparams *p)
/* Finished checks with known operators */
else
error(EXIT_FAILURE, 0, "the argument \"%s\" could not be "
- "interpretted as a recognized input file name, number, or "
+ "interpretted as a file name, named dataset, number, or "
"operator", token->v);
@@ -1069,8 +1073,18 @@ reversepolish(struct arithmeticparams *p)
}
}
}
+
+ /* Increment the token counter. */
+ ++p->tokencounter;
}
+
+ /* If there aren't any more operands (a variable has been set but not
+ used), then there is nothing to create. */
+ if(p->operands==NULL)
+ error(EXIT_FAILURE, 0, "no operands on the stack to write (as output)");
+
+
/* If there is more than one node in the operands stack then the user has
given too many operands which is an error. */
if(p->operands->next!=NULL)
@@ -1130,6 +1144,7 @@ reversepolish(struct arithmeticparams *p)
into `d1', so it is freed when freeing d1. */
gal_data_free(d1);
free(p->refdata.dsize);
+ gal_list_data_free(p->named);
/* Clean up. Note that the tokens were taken from the command-line
arguments, so the string within each token linked list must not be
diff --git a/bin/arithmetic/main.h b/bin/arithmetic/main.h
index c0c2a1d..652f7e8 100644
--- a/bin/arithmetic/main.h
+++ b/bin/arithmetic/main.h
@@ -38,9 +38,10 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
-
/* Constants: */
#define NEG_DASH_REPLACE 11 /* Vertical tab (ASCII=11) for negative dash */
+#define SET_OPERATOR_PREFIX "set-"
+#define SET_OPERATOR_PREFIX_LENGTH strlen(SET_OPERATOR_PREFIX)
@@ -73,6 +74,8 @@ struct arithmeticparams
size_t popcounter; /* The number of FITS images popped. */
gal_data_t refdata; /* Container for information of the data. */
char *globalhdu; /* Single HDU for all inputs. */
+ gal_data_t *named; /* List containing variables. */
+ size_t tokencounter; /* Counter for finding place in tokens. */
/* Operating mode: */
diff --git a/bin/arithmetic/operands.c b/bin/arithmetic/operands.c
index 8329b5e..a4914ae 100644
--- a/bin/arithmetic/operands.c
+++ b/bin/arithmetic/operands.c
@@ -58,6 +58,162 @@ operands_num(struct arithmeticparams *p)
+static int
+operands_name_is_used_later(struct arithmeticparams *p, char *name)
+{
+ size_t counter=0;
+ gal_list_str_t *token;
+
+ /* If the name indeed exists afterwards, then just return 1. */
+ for(token=p->tokens;token!=NULL;token=token->next)
+ if( counter++ > p->tokencounter && !strcmp(token->v, name) )
+ return 1;
+
+ /* If we get to this point, it means that the name doesn't exist. */
+ return 0;
+}
+
+
+
+
+
+/* Pop a dataset and keep it in the `named' list for later use. */
+void
+operands_set_name(struct arithmeticparams *p, char *token)
+{
+ gal_data_t *tmp;
+ char *varname=&token[ SET_OPERATOR_PREFIX_LENGTH ];
+
+ /* Make sure the variable name hasn't been set before. */
+ for(tmp=p->named; tmp!=NULL; tmp=tmp->next)
+ if( !strcmp(varname, tmp->name) )
+ error(EXIT_FAILURE, 0, "`%s' was previously set as a name",
+ varname);
+
+ /* Pop the top operand, then add it to the list of named datasets, but
+ only if it is used in later tokens. If it isn't, free the popped
+ dataset. The latter case (to define a name, but not use it), is
+ obviously a redundant operation, but that is upto the user, we
+ shouldn't worry about it here. We should just have everything in
+ place, so no crashes occur or no extra memory is consumed. */
+ if( operands_name_is_used_later(p, varname) )
+ {
+ /* Add the top popped operand to the list of names. */
+ gal_list_data_add(&p->named, operands_pop(p, "set"));
+
+ /* Write the requested name into this dataset. But note that `name'
+ MUST be already empty. So to be safe, we'll do a sanity check. */
+ if(p->named->name)
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+ "the problem. The `name' element should be NULL at this "
+ "point, but it isn't", __func__, PACKAGE_BUGREPORT);
+ gal_checkset_allocate_copy(varname, &p->named->name);
+ }
+ else
+ {
+ /* Pop the top operand, then free it. */
+ tmp=operands_pop(p, "set");
+ gal_data_free(tmp);
+ }
+}
+
+
+
+
+
+/* See if a given token is the name of a variable. */
+int
+operands_is_name(struct arithmeticparams *p, char *token)
+{
+ gal_data_t *tmp;
+
+ /* Make sure the variable name hasn't been set before. */
+ for(tmp=p->named; tmp!=NULL; tmp=tmp->next)
+ if( !strcmp(token, tmp->name) )
+ return 1;
+
+ /* If control reaches here, then there was no match*/
+ return 0;
+}
+
+
+
+
+
+/* Remove a name from the list of names and retrun the dataset it points
+ to. */
+static gal_data_t *
+operands_remove_name(struct arithmeticparams *p, char *name)
+{
+ gal_data_t *tmp, *removed=NULL, *prev=NULL;
+
+ /* Go over all the given names. */
+ for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
+ {
+ if( !strcmp(tmp->name, name) )
+ {
+ removed=tmp;
+ if(prev) prev->next = tmp->next;
+ else p->named = tmp->next;
+ }
+
+ /* Set this node as the `prev' pointer. */
+ prev=tmp;
+ }
+
+ /* A small sanity check. */
+ if(removed==NULL)
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix the "
+ "problem. `removed' must not be NULL at this point", __func__,
+ PACKAGE_BUGREPORT);
+
+ /* Nothing in the list points to it now. So we can safely modify and
+ return it. */
+ free(removed->name);
+ removed->name=NULL;
+ return removed;
+}
+
+
+
+
+
+/* Return a copy of the named dataset. */
+static gal_data_t *
+operands_copy_named(struct arithmeticparams *p, char *name)
+{
+ gal_data_t *out=NULL, *tmp;
+
+ /* Find the proper named element to use. */
+ for(tmp=p->named;tmp!=NULL;tmp=tmp->next)
+ if( !strcmp(tmp->name, name) )
+ {
+ /* If the named operand is used later, then copy it into the
+ output. */
+ if( operands_name_is_used_later(p, name) )
+ {
+ out=gal_data_copy(tmp);
+ free(out->name);
+ out->name=NULL;
+ }
+ /* The named operand is not used any more. Remove it from the list
+ of named datasets and continue. */
+ else out=operands_remove_name(p, name);
+ }
+
+ /* A small sanity check. */
+ if(out==NULL)
+ error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s to fix the "
+ "problem. The requested name `%s' couldn't be found in the list",
+ __func__, PACKAGE_BUGREPORT, name);
+
+ /* Return. */
+ return out;
+}
+
+
+
+
void
operands_add(struct arithmeticparams *p, char *filename, gal_data_t *data)
{
@@ -75,22 +231,32 @@ operands_add(struct arithmeticparams *p, char *filename,
gal_data_t *data)
error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for `newnode'",
__func__, sizeof *newnode);
- /* Fill in the values. */
- newnode->data=data;
- newnode->filename=filename;
-
- /* See if a HDU must be read or not. */
- if(filename != NULL
- && ( gal_fits_name_is_fits(filename)
- || gal_tiff_name_is_tiff(filename) ) )
+ /* If the `filename' is the name of a dataset, then use a copy of it.
+ otherwise, do the basic analysis. */
+ if( filename && operands_is_name(p, filename) )
+ {
+ newnode->filename=NULL;
+ newnode->data=operands_copy_named(p, filename);
+ }
+ else
{
- /* Set the HDU for this filename. */
- if(p->globalhdu)
- gal_checkset_allocate_copy(p->globalhdu, &newnode->hdu);
- else
- newnode->hdu=gal_list_str_pop(&p->hdus);
+ /* Set the basic parameters. */
+ newnode->data=data;
+ newnode->filename=filename;
+
+ /* See if a HDU must be read or not. */
+ if(filename != NULL
+ && ( gal_fits_name_is_fits(filename)
+ || gal_tiff_name_is_tiff(filename) ) )
+ {
+ /* Set the HDU for this filename. */
+ if(p->globalhdu)
+ gal_checkset_allocate_copy(p->globalhdu, &newnode->hdu);
+ else
+ newnode->hdu=gal_list_str_pop(&p->hdus);
+ }
+ else newnode->hdu=NULL;
}
- else newnode->hdu=NULL;
/* Make the link to the previous list. */
newnode->next=p->operands;
@@ -116,21 +282,28 @@ operands_pop(struct arithmeticparams *p, char *operator)
error(EXIT_FAILURE, 0, "not enough operands for the \"%s\" operator",
operator);
-
/* Set the dataset. If filename is present then read the file
and fill in the array, if not then just set the array. */
if(operands->filename)
{
+ /* Set the HDU and filename */
hdu=operands->hdu;
filename=operands->filename;
/* Read the dataset. */
data=gal_array_read_one_ch(filename, hdu, p->cp.minmapsize);
+ /* Arithmetic changes the contents of a dataset, so the existing name
+ (in the FITS `EXTNAME' keyword) should not be passed on beyond
+ this point. Also, in Arithmetic, the `name' element is used to
+ identify variables. */
+ if(data->name) { free(data->name); data->name=NULL; }
+
/* In case this is the first image that is read, then keep the WCS
information in the `refdata' structure. */
if(p->popcounter==0)
- p->refdata.wcs=gal_wcs_read(filename, hdu, 0, 0, &p->refdata.nwcs);
+ p->refdata.wcs=gal_wcs_read(filename, hdu, 0, 0,
+ &p->refdata.nwcs);
/* When the reference data structure's dimensionality is non-zero, it
means that this is not the first image read. So, write its basic
@@ -151,7 +324,8 @@ operands_pop(struct arithmeticparams *p, char *operator)
/* Allocate the dsize array. */
errno=0;
- p->refdata.dsize=malloc(p->refdata.ndim * sizeof *p->refdata.dsize);
+ p->refdata.dsize=malloc(p->refdata.ndim
+ * sizeof *p->refdata.dsize);
if(p->refdata.dsize==NULL)
error(EXIT_FAILURE, errno, "%s: allocating %zu bytes for "
"p->refdata.dsize", __func__,
@@ -166,7 +340,7 @@ operands_pop(struct arithmeticparams *p, char *operator)
if(!p->cp.quiet) printf(" - %s (hdu %s) is read.\n", filename, hdu);
/* Free the HDU string: */
- free(hdu);
+ if(hdu) free(hdu);
/* Add to the number of popped FITS images: */
++p->popcounter;
@@ -174,6 +348,7 @@ operands_pop(struct arithmeticparams *p, char *operator)
else
data=operands->data;
+
/* Remove this node from the queue, return the data structure. */
p->operands=operands->next;
free(operands);
diff --git a/bin/arithmetic/operands.h b/bin/arithmetic/operands.h
index ae487f5..e784f6d 100644
--- a/bin/arithmetic/operands.h
+++ b/bin/arithmetic/operands.h
@@ -32,5 +32,10 @@ operands_add(struct arithmeticparams *p, char *filename,
gal_data_t *data);
gal_data_t *
operands_pop(struct arithmeticparams *p, char *operator);
+void
+operands_set_name(struct arithmeticparams *p, char *token);
+
+int
+operands_is_name(struct arithmeticparams *p, char *token);
#endif
diff --git a/bin/arithmetic/ui.c b/bin/arithmetic/ui.c
index 8c57feb..3824f3b 100644
--- a/bin/arithmetic/ui.c
+++ b/bin/arithmetic/ui.c
@@ -26,10 +26,12 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
#include <errno.h>
#include <error.h>
#include <stdio.h>
+#include <string.h>
#include <gnuastro/list.h>
#include <gnuastro/fits.h>
#include <gnuastro/table.h>
+#include <gnuastro/array.h>
#include <gnuastro-internal/timing.h>
#include <gnuastro-internal/options.h>
@@ -229,7 +231,7 @@ static void
ui_check_options_and_arguments(struct arithmeticparams *p)
{
int output_checked=0;
- size_t numfits=0, numhdus=0;
+ size_t nummultiext=0, numhdus=0;
gal_list_str_t *token, *hdu;
/* First, make sure that any tokens are actually given. */
@@ -247,19 +249,21 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
was done in `gal_options_read_config_set'. */
gal_list_str_reverse(&p->tokens);
- /* Set the output file name (if any is needed). Note that since the
- lists are already reversed, the first FITS file encountered, is
- the first FITS file given by teh user. Also, notet that these
- file name operations are only necessary for the first FITS file
- in the token list. */
+ /* Set the output file name (if any is needed). Note that since the lists
+ are already reversed, the first FITS file encountered, is the first
+ FITS file given by the user. Also, note that these file name
+ operations are only necessary for the first FITS file in the token
+ list. */
for(token=p->tokens; token!=NULL; token=token->next)
{
- /* This token is a FITS file, count them and use it to set the output
- filename if it has not been set. */
- if(gal_fits_name_is_fits(token->v))
+ /* This token is a file, count how many mult-extension files we haev
+ and use the first to set the output filename (if it has not been
+ set). */
+ if( gal_array_name_recognized(token->v) )
{
/* Increment the counter for FITS files. */
- ++numfits;
+ if( gal_array_name_recognized_multiext(token->v) )
+ ++nummultiext;
/* If the output filename isn't set yet, then set it. */
if(output_checked==0)
@@ -288,13 +292,15 @@ ui_check_options_and_arguments(struct arithmeticparams *p)
else
{
for(hdu=p->hdus; hdu!=NULL; hdu=hdu->next) ++numhdus;
- if(numhdus<numfits)
- error(EXIT_FAILURE, 0, "not enough HDUs. There are %zu input FITS "
- "files, so the `--hdu' (`-h') option must be called %zu "
- "times (once for each FITS file). If the HDU value is the "
- "same for all the files, you may use `--globalhdu' (`-g') to "
- "specify a single HDU to be used for any number of input "
- "files", numfits, numfits);
+ if(numhdus<nummultiext)
+ error(EXIT_FAILURE, 0, "not enough HDUs. There are %zu input "
+ "files in formats that may contain multiple extensions (for "
+ "example FITS or TIFF). Therefore, the `--hdu' (`-h') option "
+ "must be called atleaset %zu times (once for each "
+ "multi-extension file). If the HDU value is the same for all "
+ "the files, you may use `--globalhdu' (`-g') to specify a "
+ "single HDU to be used for any number of input files",
+ nummultiext, nummultiext);
}
}
diff --git a/bin/buildprog/Makefile.am b/bin/buildprog/Makefile.am
index 446186e..58d9b03 100644
--- a/bin/buildprog/Makefile.am
+++ b/bin/buildprog/Makefile.am
@@ -51,26 +51,37 @@ EXTRA_DIST = main.h authors-cite.h args.h ui.h buildprog.h
astbuildprog.conf.in
# directories in order to compile its programs. With the rule below, the
# directories in these variables will be written into the final
# BuildProgram configuration file.
+#
+# The user might give non-`-I' arguments to CPPFLAGS and non-`-L' arguments
+# to LDFLAGS (see bug #54346). But here, we only want these two options,
+# and nothing else. To make the check, we'll see if `$i' (the input string)
+# is the same as `$v' or not. If the string starts with `-I' or `-L', it
+# will change between the two (the `-I' or `-L' have been removed), so it
+# shouldn't be the same.
astbuildprog.conf: $(top_srcdir)/bin/buildprog/astbuildprog.conf.in
cp $< $@
infoadded="no"; \
for i in $(CPPFLAGS); do \
- if test $$infoadded = "no"; then \
- echo "" >> $@; \
- echo "# Installation information" >> $@; \
- infoadded="yes"; \
+ v=$$(echo $$i | sed -e 's/^-I//'); \
+ if test $$i != $$v; then \
+ if test $$infoadded = "no"; then \
+ echo "" >> $@; \
+ echo "# Installation information" >> $@; \
+ infoadded="yes"; \
+ fi; \
+ echo " includedir $$v" >> $@; \
fi; \
- v=$$(echo $$i | sed -e 's/-I//'); \
- echo " includedir $$v" >> $@; \
done; \
for i in $(LDFLAGS); do \
- if test $$infoadded = "no"; then \
- echo "" >> $@; \
- echo "# Installation information" >> $@; \
- infoadded="yes"; \
+ v=$$(echo $$i | sed -e 's/^-L//'); \
+ if test $$i != $$v; then \
+ if test $$infoadded = "no"; then \
+ echo "" >> $@; \
+ echo "# Installation information" >> $@; \
+ infoadded="yes"; \
+ fi; \
+ echo " linkdir $$v" >> $@; \
fi; \
- v=$$(echo $$i | sed -e 's/-L//'); \
- echo " linkdir $$v" >> $@; \
done
diff --git a/bin/mkcatalog/args.h b/bin/mkcatalog/args.h
index cfdfb5e..1cd79fd 100644
--- a/bin/mkcatalog/args.h
+++ b/bin/mkcatalog/args.h
@@ -511,6 +511,62 @@ struct argp_option program_options[] =
ui_column_codes_ll
},
{
+ "minx",
+ UI_KEY_MINX,
+ 0,
+ 0,
+ "Minimum first FITS axis position.",
+ UI_GROUP_COLUMNS_POSITION_PIXEL,
+ 0,
+ GAL_TYPE_INVALID,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET,
+ ui_column_codes_ll
+ },
+ {
+ "maxx",
+ UI_KEY_MAXX,
+ 0,
+ 0,
+ "Maximum first FITS axis position.",
+ UI_GROUP_COLUMNS_POSITION_PIXEL,
+ 0,
+ GAL_TYPE_INVALID,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET,
+ ui_column_codes_ll
+ },
+ {
+ "miny",
+ UI_KEY_MINY,
+ 0,
+ 0,
+ "Minimum second FITS axis position.",
+ UI_GROUP_COLUMNS_POSITION_PIXEL,
+ 0,
+ GAL_TYPE_INVALID,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET,
+ ui_column_codes_ll
+ },
+ {
+ "maxy",
+ UI_KEY_MAXY,
+ 0,
+ 0,
+ "Maximum second FITS axis position.",
+ UI_GROUP_COLUMNS_POSITION_PIXEL,
+ 0,
+ GAL_TYPE_INVALID,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET,
+ ui_column_codes_ll
+ },
+ {
"clumpsx",
UI_KEY_CLUMPSX,
0,
diff --git a/bin/mkcatalog/columns.c b/bin/mkcatalog/columns.c
index 49ee9d3..7a6db1e 100644
--- a/bin/mkcatalog/columns.c
+++ b/bin/mkcatalog/columns.c
@@ -655,6 +655,57 @@ columns_define_alloc(struct mkcatalogparams *p)
disp_width = 10;
disp_precision = 3;
oiflag[ OCOL_C_GZ ] = 1;
+
+ case UI_KEY_MINX:
+ name = "MIN_X";
+ unit = "pixel";
+ ocomment = "Minimum X axis pixel position.";
+ ccomment = ocomment;
+ otype = GAL_TYPE_UINT32;
+ ctype = GAL_TYPE_UINT32;
+ disp_fmt = 0;
+ disp_width = 10;
+ disp_precision = 0;
+ ciflag[ CCOL_MINX ] = 1;
+ break;
+
+ case UI_KEY_MAXX:
+ name = "MAX_X";
+ unit = "pixel";
+ ocomment = "Maximum X axis pixel position.";
+ ccomment = ocomment;
+ otype = GAL_TYPE_UINT32;
+ ctype = GAL_TYPE_UINT32;
+ disp_fmt = 0;
+ disp_width = 10;
+ disp_precision = 0;
+ ciflag[ CCOL_MAXX ] = 1;
+ break;
+
+ case UI_KEY_MINY:
+ name = "MIN_Y";
+ unit = "pixel";
+ ocomment = "Minimum Y axis pixel position.";
+ ccomment = ocomment;
+ otype = GAL_TYPE_UINT32;
+ ctype = GAL_TYPE_UINT32;
+ disp_fmt = 0;
+ disp_width = 10;
+ disp_precision = 0;
+ ciflag[ CCOL_MINY ] = 1;
+ break;
+
+ case UI_KEY_MAXY:
+ name = "MAX_Y";
+ unit = "pixel";
+ ocomment = "Maximum Y axis pixel position.";
+ ccomment = ocomment;
+ otype = GAL_TYPE_UINT32;
+ ctype = GAL_TYPE_UINT32;
+ disp_fmt = 0;
+ disp_width = 10;
+ disp_precision = 0;
+ ciflag[ CCOL_MAXY ] = 1;
break;
case UI_KEY_W1:
@@ -1638,6 +1689,46 @@ columns_clump_brightness(double *ci)
+/* Measure the minimum and maximum positions. */
+static uint32_t
+columns_xy_extrema(struct mkcatalog_passparams *pp, size_t *coord, int key)
+{
+ gal_data_t *tile=pp->tile, *block=tile->block;
+
+ /* We only want to do the coordinate estimation once: in `columns_fill',
+ we initialized the coordinates with `GAL_BLANK_SIZE_T'. When the
+ coordinate has already been measured already, it won't have this value
+ any more. */
+ if(coord[0]==GAL_BLANK_SIZE_T)
+ gal_dimension_index_to_coord(gal_pointer_num_between(block->array,
+ tile->array,
+ block->type),
+ block->ndim, block->dsize, coord);
+
+ /* Return the proper value: note that `coord' is in C standard: starting
+ from the slowest dimension and counting from zero.*/
+ switch(key)
+ {
+ case UI_KEY_MINX: return coord[1] + 1; break;
+ case UI_KEY_MAXX: return coord[1] + tile->dsize[1]; break;
+ case UI_KEY_MINY: return coord[0] + 1; break;
+ case UI_KEY_MAXY: return coord[0] + tile->dsize[0]; break;
+ default:
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us to fix the "
+ "problem. The value %d is not a recognized value", __func__,
+ key);
+ }
+
+ /* Control should not reach here. */
+ error(EXIT_FAILURE, 0, "%s: a bug! please contact us to fix the problem. "
+ "Control should not reach the end of this function", __func__);
+ return GAL_BLANK_UINT32;
+}
+
+
+
+
+
/* The magnitude error is directly derivable from the S/N:
To derive the error in measuring the magnitude from the S/N, let's take
@@ -1692,6 +1783,8 @@ columns_fill(struct mkcatalog_passparams *pp)
void *colarr;
gal_data_t *column;
double *ci, *oi=pp->oi;
+ size_t coord[2]={GAL_BLANK_SIZE_T, GAL_BLANK_SIZE_T};
+
size_t sr=pp->clumpstartindex, cind, coind;
size_t oind=pp->object-1; /* IDs start from 1, indexs from 0. */
double **vo=NULL, **vc=NULL, **go=NULL, **gc=NULL, **vcc=NULL, **gcc=NULL;
@@ -1802,6 +1895,12 @@ columns_fill(struct mkcatalog_passparams *pp)
case UI_KEY_CLUMPSGEOZ:
((float *)colarr)[oind] = MKC_RATIO( oi[OCOL_C_GZ],
oi[OCOL_C_NUMALL] );
+
+ case UI_KEY_MINX:
+ case UI_KEY_MAXX:
+ case UI_KEY_MINY:
+ case UI_KEY_MAXY:
+ ((uint32_t *)colarr)[oind]=columns_xy_extrema(pp, coord, key);
break;
case UI_KEY_W1:
@@ -2046,6 +2145,20 @@ columns_fill(struct mkcatalog_passparams *pp)
case UI_KEY_GEOZ:
((float *)colarr)[cind] = MKC_RATIO( ci[CCOL_GZ],
ci[CCOL_NUMALL] );
+ case UI_KEY_MINX:
+ ((uint32_t *)colarr)[cind] = ci[CCOL_MINX];
+ break;
+
+ case UI_KEY_MAXX:
+ ((uint32_t *)colarr)[cind] = ci[CCOL_MAXX];
+ break;
+
+ case UI_KEY_MINY:
+ ((uint32_t *)colarr)[cind] = ci[CCOL_MINY];
+ break;
+
+ case UI_KEY_MAXY:
+ ((uint32_t *)colarr)[cind] = ci[CCOL_MAXY];
break;
case UI_KEY_W1:
diff --git a/bin/mkcatalog/main.h b/bin/mkcatalog/main.h
index 9376d7d..94cb2d3 100644
--- a/bin/mkcatalog/main.h
+++ b/bin/mkcatalog/main.h
@@ -140,6 +140,10 @@ enum clumpcols
CCOL_GXX, /* Second order geometric moment. */
CCOL_GYY, /* Second order geometric moment. */
CCOL_GXY, /* Second order geometric moment. */
+ CCOL_MINX, /* Minimum X value of clump. */
+ CCOL_MAXX, /* Maximum X value of clump. */
+ CCOL_MINY, /* Minimum Y value of clump. */
+ CCOL_MAXY, /* Maximum Y value of clump. */
CCOL_UPPERLIMIT_B, /* Upper limit brightness. */
CCOL_UPPERLIMIT_S, /* Upper limit one-sigma value. */
CCOL_UPPERLIMIT_Q, /* Quantile of object in random distribution.*/
diff --git a/bin/mkcatalog/parse.c b/bin/mkcatalog/parse.c
index 95ccfc0..a593308 100644
--- a/bin/mkcatalog/parse.c
+++ b/bin/mkcatalog/parse.c
@@ -362,6 +362,19 @@ parse_objects(struct mkcatalog_passparams *pp)
+/* Macro to help in finding the minimum and maximum coordinates. */
+#define CMIN(COL, DIM) ( ci[ CCOL_NUMALL ]==1.0f \
+ ? (c[ DIM ]+1) \
+ : ( (c[ DIM ]+1) < ci[ COL ] \
+ ? (c[ DIM ]+1) : ci[ COL ] ) )
+#define CMAX(COL, DIM) ( ci[ CCOL_NUMALL ]==1.0f \
+ ? (c[ DIM ]+1) \
+ : ( (c[ DIM ]+1) > ci[ COL ] \
+ ? (c[ DIM ]+1) : ci[ COL ] ) )
+
+
+
+
/* Parse over the clumps within an object. */
void
parse_clumps(struct mkcatalog_passparams *pp)
@@ -397,6 +410,10 @@ parse_clumps(struct mkcatalog_passparams *pp)
|| cif[ CCOL_VX ]
|| cif[ CCOL_VY ]
|| cif[ CCOL_VZ ]
+ || cif[ CCOL_MINX ]
+ || cif[ CCOL_MAXX ]
+ || cif[ CCOL_MINY ]
+ || cif[ CCOL_MAXY ]
|| sc
|| tid==GAL_BLANK_SIZE_T )
? gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 0, __func__,
@@ -451,7 +468,10 @@ parse_clumps(struct mkcatalog_passparams *pp)
ci=&pp->ci[ (*C-1) * CCOL_NUMCOLS ];
/* Add to the area of this object. */
- if(cif[ CCOL_NUMALL ]) ci[ CCOL_NUMALL ]++;
+ if( cif[ CCOL_NUMALL ]
+ || cif[ CCOL_MINX ] || cif[ CCOL_MAXX ]
+ || cif[ CCOL_MINY ] || cif[ CCOL_MAXY ] )
+ ci[ CCOL_NUMALL ]++;
if(cif[ CCOL_NUMALLXY ])
((uint8_t *)(xybin[*C-1].array))[ pind ] = 1;
@@ -461,6 +481,12 @@ parse_clumps(struct mkcatalog_passparams *pp)
/* Get "C" the coordinates of this point. */
gal_dimension_index_to_coord(O-objects, ndim, dsize, c);
+ /* Position extrema measurements. */
+ if(cif[ CCOL_MINX ]) ci[CCOL_MINX]=CMIN(CCOL_MINX, 1);
+ if(cif[ CCOL_MAXX ]) ci[CCOL_MAXX]=CMAX(CCOL_MAXX, 1);
+ if(cif[ CCOL_MINY ]) ci[CCOL_MINY]=CMIN(CCOL_MINY, 0);
+ if(cif[ CCOL_MAXY ]) ci[CCOL_MAXY]=CMAX(CCOL_MAXY, 0);
+
/* If we need tile-ID, get the tile ID now. */
if(tid!=GAL_BLANK_SIZE_T)
tid=gal_tile_full_id_from_coord(&p->cp.tl, c);
diff --git a/bin/mkcatalog/ui.c b/bin/mkcatalog/ui.c
index e418f68..10d1595 100644
--- a/bin/mkcatalog/ui.c
+++ b/bin/mkcatalog/ui.c
@@ -774,6 +774,10 @@ ui_necessary_inputs(struct mkcatalogparams *p, int
*values, int *sky,
case CCOL_GXX: /* Only clump labels. */ break;
case CCOL_GYY: /* Only clump labels. */ break;
case CCOL_GXY: /* Only clump labels. */ break;
+ case CCOL_MINX: /* Only clump labels. */ break;
+ case CCOL_MAXX: /* Only clump labels. */ break;
+ case CCOL_MINY: /* Only clump labels. */ break;
+ case CCOL_MAXY: /* Only clump labels. */ break;
case CCOL_UPPERLIMIT_B: *values = 1; break;
case CCOL_UPPERLIMIT_S: *values = 1; break;
case CCOL_UPPERLIMIT_Q: *values = 1; break;
diff --git a/bin/mkcatalog/ui.h b/bin/mkcatalog/ui.h
index 6004fc6..86a4cc2 100644
--- a/bin/mkcatalog/ui.h
+++ b/bin/mkcatalog/ui.h
@@ -116,6 +116,10 @@ enum option_keys_enum
UI_KEY_CLUMPSGEOX,
UI_KEY_CLUMPSGEOY,
UI_KEY_CLUMPSGEOZ,
+ UI_KEY_MINX,
+ UI_KEY_MAXX,
+ UI_KEY_MINY,
+ UI_KEY_MAXY,
UI_KEY_W1,
UI_KEY_W2,
UI_KEY_W3,
diff --git a/doc/gnuastro.en.html b/doc/gnuastro.en.html
index 323e152..b19f9da 100644
--- a/doc/gnuastro.en.html
+++ b/doc/gnuastro.en.html
@@ -122,7 +122,10 @@ review of the Gnuastro's building and installation
commands.</p>
<p>Gnuastro only has three mandatory
dependencies: <a href="manual/html_node/GNU-Scientific-Library.html">GNU
Scientific
-Library</a>, <a href="manual/html_node/CFITSIO.html">CFITSIO</a>, <a
href="manual/html_node/WCSLIB.html">WCSLIB</a>.</p>
+Library</a>, <a href="manual/html_node/CFITSIO.html">CFITSIO</a>, <a
href="manual/html_node/WCSLIB.html">WCSLIB</a>.<br />See <a
href="manual/html_node/Dependencies-from-package-managers.html">Dependencies
+from package managers</a> for easy installation of Gnuastro's dependencies
+using tools like <code>apt-get</code>, <code>dnf</code>
+(or <code>yum</code>), <code>pacman</code> or <code>brew</code>.</p>
<p>For a more detailed description, see
the <a href="manual/html_node/Installation.html">Installation</a> chapter
diff --git a/doc/gnuastro.fr.html b/doc/gnuastro.fr.html
index 5705db3..62ba52e 100644
--- a/doc/gnuastro.fr.html
+++ b/doc/gnuastro.fr.html
@@ -118,7 +118,13 @@ h3 { clear: both; }
<p>Gnuastro n'a que trois dépendances obligatoires :
<a href="manual/html_node/GNU-Scientific-Library.html">GNU Scientific
Library</a>, <a href="manual/html_node/CFITSIO.html">CFITSIO</a> et
- <a href="manual/html_node/WCSLIB.html">WCSLIB</a>.</p>
+ <a href="manual/html_node/WCSLIB.html">WCSLIB</a>.<br />Dans le
+ chapitre <a
href="manual/html_node/Dependencies-from-package-managers.html">Dépendances
+ des gestionnaires de paquets</a> vous trouverez les commandes pour une
+ installation facile des dépendances de Gnuastro en utilisant des
+ logiciels comme <code>apt-get</code>, <code>dnf</code>
+ (ou <code>yum</code>),
+ <code>pacman</code> ou <code>brew</code>.</p>
<p>Dans le chapitre <cite><a href="manual/html_node/Installation.html">
Installation</a></cite>, vous trouverez des explications complètes sur
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 8fbbcf8..061dab9 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -11811,6 +11811,52 @@ Convert the type of the popped operand to 64-bit
(double precision)
floating point (see @ref{Numeric data types}). The internal conversion of C
will be used.
+@item set-AAA
+Set a name (all characters after the dash, @code{AAA} in the case shown
+here) for the first popped operand on the stack. The name can be any
+string, but avoid strings ending with standard filename suffixes (for
+example @file{.fits})@footnote{A dataset name like @file{a.fits} (which can
+be set with @command{set-a.fits}) will cause confusion in the the initial
+parser of Arithmetic. It will assume this name is a FITS file, and if it is
+used multiple times, Arithmetic will abort, complaining that you haven't
+provided enough HDUs.}. The named dataset will be freed from memory as soon
+as it is no longer needed in the rest of the command. This operator thus
+enables re-usability of a dataset without having to re-read it from a file
+everytime its necessary during a process.
+
+The name to give the popped dataset is part of the operator's name. For
+example the @code{set-a} operator of the command below, gives the name of
+``@code{a}'' to the contents of @file{image.fits}. This name is then used
+instead of the actual filename to multiply the dataset by two.
+
+@example
+$ astarithmetic image.fits set-a a 2 x
+@end example
+
+This is a unique operator, because it doesn't actually do anything to the
+contents of the popped dataset, it just assigns a name to the dataset. This
+makes it very easy to use a single dataset on the command-line multiple
+times and avoid extra attempts at reading it into memory.
+
+One example of the usefulness of this operator is in the @code{where}
+operator. For example, let's assume you want to mask all pixels larger than
+@code{5} in @file{image.fits} (extension number 1) with a NaN
+value. Without using this operator, you have to run
+
+@example
+$ astarithmetic image.fits image.fits 5 gt nan where -g1
+@end example
+
+But with this operator you can simply give @file{image.fits} the name
+@code{i} and simplify the command above:
+
+@example
+$ astarithmetic image.fits set-i i i 5 gt nan where
+@end example
+
+This operator can thus help simplify reading/writing on the command-line
+(avoid potential bugs), while also speeding up your processing.
+
@end table
@cartouche
@@ -18092,6 +18138,18 @@ their pixel values.
The geometric center of all objects and clumps along the second FITS axis
axis, see @option{--geox}.
+@item --minx
+The minimum position of all objects and clumps along the first FITS axis.
+
+@item --maxx
+The maximum position of all objects and clumps along the first FITS axis.
+
+@item --miny
+The minimum position of all objects and clumps along the second FITS axis.
+
+@item --maxy
+The maximum position of all objects and clumps along the second FITS axis.
+
@item --clumpsx
[Objects] The flux weighted center of all the clumps in this object along
the first FITS axis. See @option{--x}.
@@ -22394,10 +22452,10 @@ are fixed width types, these types are portable to
all systems and are
defined in the standard C header @file{stdint.h}. You don't need to include
this header, it is included by any Gnuastro header that deals with the
different types. However, the most commonly used types in a C (or C++)
-program (for example @code{int} or @code{long} are not defined by their
-exact width (storage), but by their minimum storage. So for example on some
-systems, @code{int} may be 2 bytes (16-bits, the minimum required by the
-standard) and on others it may be 4 bytes (32-bits, common in modern
+program (for example @code{int} or @code{long}) are not defined by their
+exact width (storage size), but by their minimum storage. So for example on
+some systems, @code{int} may be 2 bytes (16-bits, the minimum required by
+the standard) and on others it may be 4 bytes (32-bits, common in modern
systems).
With every type, a unique ``blank'' value (or place holder showing the
@@ -24342,6 +24400,12 @@ Return 1 if the given file name corresponds to one of
the recognized file
types for reading arrays.
@end deftypefun
+@deftypefun int gal_array_name_recognized_multiext (char @code{*filename})
+Return 1 if the given file name corresponds to one of the recognized file
+types for reading arrays which may contain multiple extesions (for example
+FITS or TIFF) formats.
+@end deftypefun
+
@deftypefun gal_data_t gal_array_read (char @code{*filename}, char
@code{*extension}, size_t @code{minmapsize})
Read the array within the given extension (@code{extension}) of
@code{filename}. If the array is larger than @code{minmapsize} bytes, then
@@ -24677,9 +24741,9 @@ One important issue to consider is that CFITSIO's types
are not fixed width
(for example @code{long} may be 32-bits or 64-bits on different
systems). However, Gnuastro's types are defined by their width. These
functions will use information on the host system to do the proper
-conversion, so it strongly recommended to use these functions for
-portability of your code and not to assume a fixed correspondence between
-CFITSIO and Gnuastro's types.
+conversion. To have a portable (usable on different systems) code, is thus
+recommended to use these functions and not to assume a fixed correspondence
+between CFITSIO and Gnuastro's types.
@deftypefun uint8_t gal_fits_bitpix_to_type (int @code{bitpix})
Return the Gnuastro type identifier that corresponds to CFITSIO's
@@ -28693,7 +28757,7 @@ language, but it can be considered one of the
lowest-level languages among
all high-level languages.} (closer to the hardware), it is much less
complex for both the human reader @emph{and} the computer. The benefits of
simplicity for a human were discussed above. Simplicity for the computer
-translates into more efficiently (faster) programs. This creates a much
+translates into more efficient (faster) programs. This creates a much
closer relation between the scientist/programmer (or their program) and the
actual data and processing. The GNU coding
standards@footnote{@url{http://www.gnu.org/prep/standards/}} also encourage
diff --git a/lib/array.c b/lib/array.c
index 0aa708e..6c63afc 100644
--- a/lib/array.c
+++ b/lib/array.c
@@ -48,9 +48,27 @@ along with Gnuastro. If not, see
<http://www.gnu.org/licenses/>.
int
gal_array_name_recognized(char *name)
{
+ if( gal_array_name_recognized_multiext(name) ) return 1;
+ else if ( gal_jpeg_name_is_jpeg(name) ) return 1;
+ else return 0;
+
+ /* Control should not get to here, but just to avoid compiler warnings,
+ we'll return a NULL. */
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to solve the "
+ "problem. Control must not reach the end of this function", __func__,
+ PACKAGE_BUGREPORT);
+ return 0;
+}
+
+
+
+
+
+int
+gal_array_name_recognized_multiext(char *name)
+{
if( gal_fits_name_is_fits(name) ) return 1;
else if ( gal_tiff_name_is_tiff(name) ) return 1;
- else if ( gal_jpeg_name_is_jpeg(name) ) return 1;
else return 0;
/* Control should not get to here, but just to avoid compiler warnings,
diff --git a/lib/gnuastro/array.h b/lib/gnuastro/array.h
index aaff1fd..faff5f2 100644
--- a/lib/gnuastro/array.h
+++ b/lib/gnuastro/array.h
@@ -55,6 +55,9 @@ __BEGIN_C_DECLS /* From C++ preparations */
int
gal_array_name_recognized(char *name);
+int
+gal_array_name_recognized_multiext(char *name);
+
gal_data_t *
gal_array_read(char *filename, char *extension, size_t minmapsize);
- [gnuastro-commits] master 325d717 045/113: 3D matching now in Match program and library, (continued)
- [gnuastro-commits] master 325d717 045/113: 3D matching now in Match program and library, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master d7e0037 047/113: Brought in recent work in master, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 303e6e2 048/113: Incorporated recent work, minor conflict corrected, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 5831e9e 052/113: Recent work in master imported, no conflicts, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 1af4ea9 062/113: Correct checks for kernel dimension in NoiseChisel and Segment, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master d13c715 065/113: Imported work in master, no conflicts, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 91f2d3e 068/113: Imported recent work in master, conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 63b4edd 070/113: Imported work in master, conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 0ced9e5 072/113: Imported recent work in master, no conflicts, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 88935ae 073/113: Dataset pointers initialized to NULL in upperlimit_write_check, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master d02c999 079/113: Recent work in master imported, conflicts fixed,
Mohammad Akhlaghi <=
- [gnuastro-commits] master 4021652 078/113: Imported recent work in master, conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 8d64628 081/113: Recent work in master imported, minor conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 800c769 082/113: Imported all the work in master, conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master ac91655 084/113: Imported recent work in master, no conflicts, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master d57e0e6 087/113: New spectrum measurement from 3D inputs in MakeCatalog, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master a8428fe 088/113: Imported recent work in master, conflicts fixed, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 175354f 095/113: All MakeCatalog spectrums set to NaN when no measurement was done, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master fe0e594 097/113: Imported recent work in master, no conflicts, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master 5d5fd95 106/113: NoiseChisel: independent test of input's dimensions, Mohammad Akhlaghi, 2021/04/16
- [gnuastro-commits] master ee4bf1e 069/113: Imported recent work from master, Segment's 3D kernels added, Mohammad Akhlaghi, 2021/04/16