[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 95d7fc5: Match: New --coord option for single
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 95d7fc5: Match: New --coord option for single coordinate matching |
Date: |
Tue, 5 Mar 2019 21:18:08 -0500 (EST) |
branch: master
commit 95d7fc596dcd4b6947e37412f78b59a2ac30b28a
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
Match: New --coord option for single coordinate matching
Until now, when trying to match a single point to another catalog, it was
necessary to make a single-row table. With this option, its now possible to
specify the points directly on the command-line and avoid having to make an
extra file (which you probably need to delete afterwards).
---
NEWS | 7 +
bin/match/args.h | 14 ++
bin/match/astmatch.conf | 4 +-
bin/match/main.h | 3 +-
bin/match/match.c | 99 ++++++++--
bin/match/ui.c | 366 +++++++++++++++++++++++++------------
bin/match/ui.h | 3 +-
doc/gnuastro.texi | 44 ++++-
lib/gnuastro-internal/commonopts.h | 2 +-
lib/gnuastro/type.h | 3 +
lib/options.c | 16 +-
lib/type.c | 24 ++-
tests/match/merged-cols.sh | 4 +-
tests/match/positions.sh | 4 +-
14 files changed, 440 insertions(+), 153 deletions(-)
diff --git a/NEWS b/NEWS
index 398d8fb..29a09bc 100644
--- a/NEWS
+++ b/NEWS
@@ -52,6 +52,12 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
contain all the columns from the first input and the 5th column of the
second input. This greatly simplifies the mergining of different table
columns into one.
+ --coord: manually specify coordinates to match on the
+ command-line. Until now, if you only wanted to make check a specific
+ coordinate's matching with a catalog. It was necessary to make a
+ single-row catalog as a file and feed that into Match. With this
+ option, you can now specify the coordinates to match against another
+ catalog with the command-line.
NoiseChisel:
--interpmetric: Set the metric to use to identify the nearest neighbors
@@ -86,6 +92,7 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
gal_dimension_dist_radial: Radial distance between two coordinates.
gal_statistics_outlier_cumulative: Uses flatness of the cumulative
distribution to find outliers.
+ gal_type_is_int: to see if we have an integer (any width, any sign).
** Removed features
diff --git a/bin/match/args.h b/bin/match/args.h
index 0509970..657cf73 100644
--- a/bin/match/args.h
+++ b/bin/match/args.h
@@ -129,6 +129,20 @@ struct argp_option program_options[] =
gal_options_parse_csv_strings
},
{
+ "coord",
+ UI_KEY_COORD,
+ "FLT[,FLT]",
+ 0,
+ "Manually input coordiantes.",
+ UI_GROUP_CATALOGMATCH,
+ &p->coord,
+ GAL_TYPE_STRING,
+ GAL_OPTIONS_RANGE_ANY,
+ GAL_OPTIONS_NOT_MANDATORY,
+ GAL_OPTIONS_NOT_SET,
+ gal_options_parse_csv_float64
+ },
+ {
"aperture",
UI_KEY_APERTURE,
"FLT[,FLT[,FLT]]",
diff --git a/bin/match/astmatch.conf b/bin/match/astmatch.conf
index 6506993..85a90ec 100644
--- a/bin/match/astmatch.conf
+++ b/bin/match/astmatch.conf
@@ -20,6 +20,4 @@
# Input
hdu2 1
-# Catalog matching
- ccol1 2,3
- ccol2 2,3
\ No newline at end of file
+# Catalog matching
\ No newline at end of file
diff --git a/bin/match/main.h b/bin/match/main.h
index f9a5a85..1e776a6 100644
--- a/bin/match/main.h
+++ b/bin/match/main.h
@@ -53,8 +53,9 @@ struct matchparams
char *input1name; /* First input filename. */
char *input2name; /* Second input filename. */
char *hdu2; /* Second input's HDU. */
- gal_data_t *ccol1; /* Array of firs input column names. */
+ gal_data_t *ccol1; /* Array of first input column names. */
gal_data_t *ccol2; /* Array of second input column names. */
+ gal_data_t *coord; /* Array of manual coordinate values. */
gal_data_t *outcols; /* Array of second input column names. */
gal_data_t *aperture; /* Acceptable matching aperture. */
uint8_t logasoutput; /* Don't rearrange inputs, out is log. */
diff --git a/bin/match/match.c b/bin/match/match.c
index 94132a1..e32a74b 100644
--- a/bin/match/match.c
+++ b/bin/match/match.c
@@ -97,6 +97,57 @@ match_add_all_cols(char *filename, char *extname,
gal_list_str_t *stdinlines,
+static gal_data_t *
+match_cat_from_coord(struct matchparams *p, gal_list_str_t *cols,
+ size_t *numcolmatch)
+{
+ void *rptr;
+ gal_list_str_t *col;
+ uint8_t read, readtype;
+ size_t colcounter, counter;
+ gal_data_t *tmp, *ttmp, *out=NULL;
+
+ /* Go over the desired columns and only return the good ones. */
+ colcounter=0;
+ for(col=cols;col!=NULL;col=col->next)
+ {
+ /* In `ui_preparations_out_cols', we have done the necessary sanity
+ checks, so we can safely use the values. */
+ rptr=gal_type_string_to_number(col->v, &readtype);
+ if(readtype!=GAL_TYPE_UINT8)
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+ "the problem. The given string didn't have a `uint8' type",
+ __func__, PACKAGE_BUGREPORT);
+ read=*((uint8_t *)rptr);
+
+ /* Find the proper column in the second input's columns. Just note
+ that column counting starts from 1.*/
+ counter=1;
+ for(tmp=p->cols2;tmp!=NULL;tmp=tmp->next)
+ if(counter++ == read)
+ {
+ ttmp=gal_data_copy(tmp);
+ ttmp->next=NULL;
+ gal_list_data_add(&out, ttmp);
+ ++numcolmatch[colcounter];
+ break;
+ }
+
+ /* Increment the column counter. */
+ ++colcounter;
+ }
+
+ /* Reverse the list. */
+ gal_list_data_reverse(&out);
+
+ /* Return the output columns. */
+ return out;
+}
+
+
+
+
+
/* Read the catalog in the given file and use the given permutation to keep
the proper columns. */
static gal_data_t *
@@ -143,18 +194,21 @@ match_catalog_read_write_all(struct matchparams *p,
size_t *permutation,
/* When the output contains columns from both inputs, we need to keep
the number of columns matched against each column identifier. */
*numcolmatch=gal_pointer_allocate(GAL_TYPE_SIZE_T,
- gal_list_str_number(cols), 0,
+ gal_list_str_number(cols), 1,
__func__, "numcolmatch");
}
else cols=incols;
- /* Read the full table and free the `cols' array if it was allocated
- here. */
- cat=gal_table_read(filename, hdu, filename ? NULL : p->stdinlines, cols,
- p->cp.searchin, p->cp.ignorecase, p->cp.minmapsize,
- *numcolmatch);
- origsize=cat->size;
+ /* Read the full table. NOTE that with `--coord', for the second input,
+ both `filename' and `p->stdinlines' will be NULL. */
+ if(filename || p->stdinlines)
+ cat=gal_table_read(filename, hdu, filename ? NULL : p->stdinlines, cols,
+ p->cp.searchin, p->cp.ignorecase, p->cp.minmapsize,
+ *numcolmatch);
+ else
+ cat=match_cat_from_coord(p, cols, *numcolmatch);
+ origsize = cat ? cat->size : 0;
/* Go over each column and permute its contents. */
@@ -198,10 +252,11 @@ match_catalog_read_write_all(struct matchparams *p,
size_t *permutation,
}
}
+
/* Write the catalog to the output. */
if(p->outcols)
return cat;
- else
+ else if(cat)
{
/* Write the catalog to a file. */
gal_table_write(cat, NULL, p->cp.tableformat, outname, extname, 0);
@@ -227,8 +282,9 @@ match_catalog_read_write_all(struct matchparams *p, size_t
*permutation,
/* Clean up. */
gal_list_data_free(cat);
- return NULL;
}
+
+ return NULL;
}
@@ -380,7 +436,14 @@ match_catalog(struct matchparams *p)
/* Print the number of matches if not in quiet mode. */
if(!p->cp.quiet)
- fprintf(stdout, "%zu\n", nummatched);
+ {
+ fprintf(stdout, "Number of maching rows in both catalogs: %zu\n",
+ nummatched);
+ if(p->out2name && strcmp(p->out1name, p->out2name))
+ fprintf(stdout, "Output:\n %s\n %s", p->out1name, p->out2name);
+ else
+ fprintf(stdout, "Output: %s\n", p->out1name);
+ }
}
@@ -409,8 +472,16 @@ void
match(struct matchparams *p)
{
/* Do the correct type of matching. */
- if(p->mode==MATCH_MODE_CATALOG)
- match_catalog(p);
+ switch(p->mode)
+ {
+ case MATCH_MODE_CATALOG: match_catalog(p); break;
+ case MATCH_MODE_WCS:
+ error(EXIT_FAILURE, 0, "matching by WCS is not yet supported");
+ default:
+ error(EXIT_FAILURE, 0, "%s: a bug! please contact us at %s to fix "
+ "the problem: %d is not a recognized mode",
+ __func__, PACKAGE_BUGREPORT, p->mode);
+ }
/* Write Match's configuration as keywords into the first extension of
the output. */
@@ -420,7 +491,9 @@ match(struct matchparams *p)
? p->input1name
: "Standard input" ),
&p->cp.okeys, 1);
- gal_fits_key_write_filename("input2", p->input2name, &p->cp.okeys, 1);
+ gal_fits_key_write_filename("input2",
+ p->input2name?p->input2name:"--coord",
+ &p->cp.okeys, 1);
gal_fits_key_write_config(&p->cp.okeys, "Match configuration",
"MATCH-CONFIG", p->out1name, "0");
}
diff --git a/bin/match/ui.c b/bin/match/ui.c
index 6423772..d569e87 100644
--- a/bin/match/ui.c
+++ b/bin/match/ui.c
@@ -224,24 +224,45 @@ ui_read_check_only_options(struct matchparams *p)
-
+/* Two necessary catalogs: First: Standard input, or a file.
+ Second: `--coord', or a file.
+ */
static void
ui_check_options_and_arguments(struct matchparams *p)
{
- /* The first input might come from the standard input, in that case, the
- second input's name is stored in `input1name' and `input2name' will be
- left to NULL. So we'll first correct for this. */
- if(p->input1name)
+ /* When `--coord' is given, there should be no second catalog
+ (argument). */
+ if(p->coord)
+ {
+ /* Make sure no second argument is given. */
+ if(p->input2name)
+ error(EXIT_FAILURE, 0, "only one argument can be given with the "
+ "`--coord' option");
+
+ /* No need for `p->input2name' or `p->ccol2'. */
+ gal_data_free(p->ccol2);
+ p->ccol2=NULL;
+ }
+
+ /* `--coord' is not given. */
+ else
{
+ /* Without `coord' atleast one input is necessary. */
+ if(p->input1name==NULL)
+ error(EXIT_FAILURE, 0, "no inputs!\n\n"
+ "Two inputs are necessary. The first can be a file, or from "
+ "the standard input (e.g., a pipe). The second can be a "
+ "file, or its coordinates can be directly specified on the "
+ "command-line with `--coord'");
+
+ /* If the first input should be read from the standard input, the
+ contents of `input1name' actually belong to `input2name'. */
if(p->input2name==NULL)
{
p->input2name=p->input1name;
p->input1name=NULL;
}
}
- else
- error(EXIT_FAILURE, 0, "no inputs! two inputs are necessary. The first "
- "can be from the standard input (e.g., a pipe)");
/* If the first input is a FITS file, make sure its HDU is also given. */
@@ -253,20 +274,13 @@ ui_check_options_and_arguments(struct matchparams *p)
"`--hdu' (`-h') option and give it the HDU number (starting "
"from zero), extension name, or anything acceptable by "
"CFITSIO");
-
- /* If the second input is a FITS file, make sure its HDU is also
- given. */
- if(p->input2name)
- {
- if( gal_fits_name_is_fits(p->input2name) && p->hdu2==NULL )
- error(EXIT_FAILURE, 0, "no HDU for second input. Please use the "
- "`--hdu2' (`-H') option and give it the HDU number (starting "
- "from zero), extension name, or anything acceptable by "
- "CFITSIO");
- }
- else
- error(EXIT_FAILURE, 0, "second input file not specified: two inputs are "
- "necessary");
+ if( p->input2name
+ && gal_fits_name_is_fits(p->input2name)
+ && p->hdu2==NULL )
+ error(EXIT_FAILURE, 0, "no HDU for second input. Please use "
+ "the `--hdu2' (`-H') option and give it the HDU number "
+ "(starting from zero), extension name, or anything "
+ "acceptable by CFITSIO");
}
@@ -294,41 +308,67 @@ ui_check_options_and_arguments(struct matchparams *p)
static void
ui_set_mode(struct matchparams *p)
{
- /* Check if we are in image or catalog mode. We will base the mode on the
- first input, then check with the second. */
+ int tin1, tin2;
+ char *t1=NULL, *t2=NULL;
+
+ /* We will base the mode on the first input, then check with the
+ second. Note that when the first is from standard input (it is
+ `NULL'), then we go into catalog mode because currently we assume
+ standard input is only for plain text and WCS matching is not defined
+ on plain text. */
if( p->input1name && gal_fits_name_is_fits(p->input1name) )
- p->mode = ( (gal_fits_hdu_format(p->input1name, p->cp.hdu) == IMAGE_HDU)
- ? MATCH_MODE_WCS
- : MATCH_MODE_CATALOG );
+ {
+ tin1=gal_fits_hdu_format(p->input1name, p->cp.hdu);
+ p->mode = (tin1 == IMAGE_HDU) ? MATCH_MODE_WCS : MATCH_MODE_CATALOG;
+ }
else
p->mode=MATCH_MODE_CATALOG;
- /* Now that the mode is set, check the second input's type. */
- if( gal_fits_name_is_fits(p->input2name) )
+
+ /* Necessary sanity checks. */
+ if(p->mode==MATCH_MODE_CATALOG && p->cp.searchin==0)
+ error(EXIT_FAILURE, 0, "no `--searchin' option specified. Please run "
+ "the following command for more information:\n\n"
+ " $ info gnuastro \"selecting table columns\"\n");
+
+
+ /* Now that the mode is set, do some sanity checks on the second
+ catalog. Recall that when `--coord' is given, there is no second input
+ file.*/
+ if(p->input2name)
{
- if(gal_fits_hdu_format(p->input2name, p->hdu2) == IMAGE_HDU)
+ if(gal_fits_name_is_fits(p->input2name))
{
- if( p->mode==MATCH_MODE_CATALOG)
- error(EXIT_FAILURE, 0, "%s is a catalog, while %s is an image. "
- "Both inputs have to be images or catalogs",
- gal_checkset_dataset_name(p->input1name, p->cp.hdu),
- gal_checkset_dataset_name(p->input2name, p->hdu2) );
+ tin2=gal_fits_hdu_format(p->input2name, p->hdu2);
+ if(tin1==IMAGE_HDU && tin2!=IMAGE_HDU)
+ {
+ t1 = (tin1==IMAGE_HDU) ? "image" : "catalog";
+ t2 = (tin2==IMAGE_HDU) ? "image" : "catalog";
+ }
+ if(t1)
+ error(EXIT_FAILURE, 0, "%s is a %s, while %s is an "
+ "%s. Both inputs have to be images or catalogs",
+ gal_checkset_dataset_name(p->input1name, p->cp.hdu), t1,
+ gal_checkset_dataset_name(p->input2name, p->hdu2), t2 );
}
else
{
- if( p->mode==MATCH_MODE_WCS)
- error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog. "
+ if(p->mode==MATCH_MODE_WCS)
+ error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog! "
"Both inputs have to be images or catalogs",
gal_checkset_dataset_name(p->input1name, p->cp.hdu),
- gal_checkset_dataset_name(p->input2name, p->hdu2));
+ gal_checkset_dataset_name(p->input2name, p->hdu2) );
}
}
else
- if(p->mode==MATCH_MODE_WCS)
- error(EXIT_FAILURE, 0, "%s is an image, while %s is a catalog! Both "
- "inputs have to be images or catalogs",
- gal_checkset_dataset_name(p->input1name, p->cp.hdu),
- gal_checkset_dataset_name(p->input2name, p->hdu2));
+ {
+ /* When there is no second-input file name (`--coord' is given), we
+ cannot be in WCS mode (requiring a FITS file). */
+ if(p->mode==MATCH_MODE_WCS)
+ error(EXIT_FAILURE, 0, "%s is an image, while `--coord' is only "
+ "meaningful for catalogs",
+ gal_checkset_dataset_name(p->input1name, p->cp.hdu));
+ }
}
@@ -404,6 +444,100 @@ ui_read_columns_aperture_2d(struct matchparams *p)
+static size_t
+ui_set_columns_sanity_check_read_aperture(struct matchparams *p)
+{
+ size_t ccol1n, ccol2n;
+
+ /* Make sure the columns to read are given. */
+ if(p->coord)
+ {
+ if(p->ccol1==NULL)
+ error(EXIT_FAILURE, 0, "no value given to `--ccol1' (necessary with "
+ "`--coord')");
+ }
+ else
+ {
+ if(p->ccol1==NULL || p->ccol2==NULL)
+ error(EXIT_FAILURE, 0, "both `--ccol1' and `--ccol2' must be given. "
+ "They specify the columns containing the coordinates to match");
+ }
+
+ /* Make sure the same number of columns is given to both. */
+ ccol1n = p->ccol1->size;
+ ccol2n = p->coord ? p->coord->size : p->ccol2->size;
+ if(ccol1n!=ccol2n)
+ error(EXIT_FAILURE, 0, "number of coordinates given to `--ccol1' "
+ "(%zu) and `--%s' (%zu) must be equal.\n\n"
+ "If you didn't call these options, run with `--checkconfig' to "
+ "see which configuration file is responsible. You can always "
+ "override the configuration file values by calling the option "
+ "manually on the command-line",
+ ccol1n, p->coord ? "coord" : "ccol2", ccol2n);
+
+ /* Read/check the aperture values. */
+ if(p->aperture)
+ switch(ccol1n)
+ {
+ case 1:
+ if(p->aperture->size>1)
+ error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. In a 1D "
+ "match, this option can only take one value",
+ p->aperture->size);
+ break;
+
+ case 2:
+ ui_read_columns_aperture_2d(p);
+ break;
+
+ default:
+ error(EXIT_FAILURE, 0, "%zu dimensional matches are not currently "
+ "supported (maximum is 2 dimensions). The number of "
+ "dimensions is deduced from the number of values given to "
+ "`--ccol1' (or `--coord') and `--ccol2'", ccol1n);
+ }
+ else
+ error(EXIT_FAILURE, 0, "no matching aperture specified. Please use "
+ "the `--aperture' option to define the acceptable aperture for "
+ "matching the coordinates (in the same units as each "
+ "dimension). Please run the following command for more "
+ "information.\n\n $ info %s\n", PROGRAM_EXEC);
+
+ /* Return the number of dimensions. */
+ return ccol1n;
+}
+
+
+
+
+
+/* Save the manually given coordinates (with `--coord') in column format (a
+ list of datasets). */
+static gal_data_t *
+ui_set_columns_from_coord(struct matchparams *p)
+{
+ size_t i, one=1;
+ gal_data_t *out=NULL;
+ double *coord=p->coord->array;
+
+ /* Write each given value as a one-row table column (single element
+ datasets that are linked) */
+ for(i=0;i<p->coord->size;++i)
+ {
+ gal_list_data_add_alloc(&out, NULL, GAL_TYPE_FLOAT64, 1, &one, NULL,
+ 0, -1, NULL, NULL, NULL);
+ *((double *)(out->array))=coord[i];
+ }
+ gal_list_data_reverse(&out);
+
+ /* Return the list. */
+ return out;
+}
+
+
+
+
+
/* We want to keep the columns as double type. So what-ever their original
type is, convert it. */
static gal_data_t *
@@ -469,72 +603,32 @@ ui_read_columns_to_double(struct matchparams *p, char
*filename, char *hdu,
static void
ui_read_columns(struct matchparams *p)
{
- size_t i;
- size_t ccol1n=p->ccol1->size;
- size_t ccol2n=p->ccol2->size;
+ size_t i, ndim;
+ char **strarr1, **strarr2;
gal_list_str_t *cols1=NULL, *cols2=NULL;
- char **strarr1=p->ccol1->array, **strarr2=p->ccol2->array;
-
- /* Make sure the same number of columns is given to both. */
- if(ccol1n!=ccol2n)
- error(EXIT_FAILURE, 0, "the number of values given to `--ccol1' and "
- "`--ccol2' (%zu and %zu) are not equal", ccol1n, ccol2n);
-
-
- /* Read/check the aperture values. */
- if(p->aperture)
- switch(ccol1n)
- {
- case 1:
- if(p->aperture->size>1)
- error(EXIT_FAILURE, 0, "%zu values given to `--aperture'. In a 1D "
- "match, this option can only take one value",
- p->aperture->size);
- break;
-
- case 2:
- ui_read_columns_aperture_2d(p);
- break;
-
- default:
-
- error(EXIT_FAILURE, 0, "%zu dimensional matches are not currently "
- "supported (maximum is 2 dimensions). The number of "
- "dimensions is deduced from the number of values given to "
- "`--ccol1' and `--ccol2'", ccol1n);
- }
- else
- error(EXIT_FAILURE, 0, "no matching aperture specified. Please use "
- "the `--aperture' option to define the acceptable aperture for "
- "matching the coordinates (in the same units as each "
- "dimension). Please run the following command for more "
- "information.\n\n $ info %s\n", PROGRAM_EXEC);
+ /* Basic sanity checks and reading of aperture values. */
+ ndim=ui_set_columns_sanity_check_read_aperture(p);
/* Convert the array of strings to a list of strings for the column
names. */
- for(i=0;i<ccol1n;++i)
+ strarr1=p->ccol1->array;
+ strarr2=p->coord?NULL:p->ccol2->array;
+ for(i=0;i<ndim;++i)
{
gal_list_str_add(&cols1, strarr1[i], 1);
- gal_list_str_add(&cols2, strarr2[i], 1);
+ if(strarr2) gal_list_str_add(&cols2, strarr2[i], 1);
}
gal_list_str_reverse(&cols1);
- gal_list_str_reverse(&cols2);
-
+ if(cols2) gal_list_str_reverse(&cols2);
- /* Read the columns. */
- if(p->cp.searchin)
- {
- /* Read the first dataset. */
- p->cols1=ui_read_columns_to_double(p, p->input1name, p->cp.hdu,
- cols1, ccol1n);
- p->cols2=ui_read_columns_to_double(p, p->input2name, p->hdu2,
- cols2, ccol2n);
- }
- else
- error(EXIT_FAILURE, 0, "no `--searchin' option specified. Please run "
- "the following command for more information:\n\n"
- " $ info gnuastro \"selecting table columns\"\n");
+ /* Read-in the columns. */
+ p->cols1=ui_read_columns_to_double(p, p->input1name, p->cp.hdu,
+ cols1, ndim);
+ p->cols2=( p->coord
+ ? ui_set_columns_from_coord(p)
+ : ui_read_columns_to_double(p, p->input2name, p->hdu2,
+ cols2, ndim) );
/* Free the extra spaces. */
gal_list_str_free(cols1, 1);
@@ -548,27 +642,65 @@ ui_read_columns(struct matchparams *p)
static void
ui_preparations_out_cols(struct matchparams *p)
{
- size_t i;
- char **strarr=p->outcols->array;
+ void *rptr;
+ int goodvalue;
+ gal_data_t *read;
+ uint8_t readtype;
+ char *col, **strarr=p->outcols->array;
+ size_t i, one=1, ndim=p->coord?p->coord->size:0;
/* Go over all the values and put the respective column identifier in the
proper list. */
for(i=0;i<p->outcols->size;++i)
- switch(strarr[i][0])
- {
- case 'a': gal_list_str_add(&p->acols, strarr[i]+1, 0); break;
- case 'b': gal_list_str_add(&p->bcols, strarr[i]+1, 0); break;
- default:
- error(EXIT_FAILURE, 0, "`%s' is not a valid value for `--outcols'. "
- "The first character of each value to this option must be "
- "either `a' or `b'. The former specifies a column from the "
- "first input and the latter a column from the second. The "
- "characters after them can be any column identifier (number, "
- "name, or regular expression). For more on column selection, "
- "please run this command:\n\n"
- " $ info gnuastro \"Selecting table columns\"\n",
- strarr[i]);
- }
+ {
+ col=strarr[i];
+ switch(col[0])
+ {
+ case 'a': gal_list_str_add(&p->acols, col+1, 0); break;
+ case 'b':
+ /* With `--coord', only numbers that are smaller than the number
+ of the dimensions are acceptable. */
+ if(p->coord)
+ {
+ goodvalue=0;
+ rptr=gal_type_string_to_number(col+1, &readtype);
+ if(rptr)
+ {
+ read=gal_data_alloc(rptr, readtype, 1, &one, NULL, 0, -1,
+ NULL, NULL, NULL);
+ if(gal_type_is_int(readtype))
+ {
+ read=gal_data_copy_to_new_type_free(read,GAL_TYPE_LONG);
+ if( *((long *)(read->array)) <= ndim )
+ goodvalue=1;
+ }
+ gal_data_free(read);
+ }
+ if(goodvalue==0)
+ error(EXIT_FAILURE, 0, "bad value to second catalog "
+ "column (%s) of `--outcols'.\n\n"
+ "With the `--coord' option, the second catalog is "
+ "assumed to have a single row and the given number "
+ "of columns. Therefore when using `--outcols', only "
+ "integers that are less than the number of "
+ "dimensions (%zu in this case) are acceptable", col+1,
+ ndim);
+ }
+ gal_list_str_add(&p->bcols, col+1, 0);
+ break;
+ default:
+ error(EXIT_FAILURE, 0, "`%s' is not a valid value for "
+ "`--outcols'.\n\n"
+ "The first character of each value to this option must be "
+ "either `a' or `b'. The former specifies a column from the "
+ "first input and the latter a column from the second. The "
+ "characters after them can be any column identifier (number, "
+ "name, or regular expression). For more on column selection, "
+ "please run this command:\n\n"
+ " $ info gnuastro \"Selecting table columns\"\n",
+ col);
+ }
+ }
/* Revere the lists so they correspond to the input order. */
gal_list_str_reverse(&p->acols);
@@ -611,7 +743,7 @@ ui_preparations_out_name(struct matchparams *p)
}
else
{
- if(p->outcols)
+ if(p->outcols || p->coord)
{
if(p->cp.output)
gal_checkset_allocate_copy(p->cp.output, &p->out1name);
diff --git a/bin/match/ui.h b/bin/match/ui.h
index e949fb4..6d66082 100644
--- a/bin/match/ui.h
+++ b/bin/match/ui.h
@@ -40,7 +40,7 @@ enum program_args_groups
/* Available letters for short options:
- b d e f g i j k m n p r s t u v w x y z
+ b e f g i j k m n p r s t u v w x y z
A B E G J L O Q R W X Y
*/
enum option_keys_enum
@@ -51,6 +51,7 @@ enum option_keys_enum
UI_KEY_LOGASOUTPUT = 'l',
UI_KEY_CCOL1 = 'c',
UI_KEY_CCOL2 = 'C',
+ UI_KEY_COORD = 'd',
/* 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 f9d36b3..6013bcc 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -19752,10 +19752,14 @@ $ astmatch --ccol1=RA,DEC --ccol2=RA_D,DEC_D
--aperture=0.5/3600 \
in1.fits in2.fits
@end example
-Two inputs are necessary for Match to start processing. The inputs can be
-plain text tables or FITS tables, see @ref{Tables}. If only one argument is
-provided, Match will assume look for the first input in Standard input (see
address@hidden input}).
+Match will find the rows that are nearest to each other in two catalogs
+(given some coordinate columns). Therefore two catalogs are necessary for
+input. However, they don't necessarily have to be files: 1) the first
+catalog can also come from the standard input (for example a pipe, see
address@hidden input}); 2) when only one point is needed, you can use the
address@hidden option to avoid creating a file for the second
+catalog. When the inputs are files, they can be plain text tables or FITS
+tables, for more see @ref{Tables}.
Match follows the same basic behavior of all Gnuastro programs as fully
described in @ref{Common program behavior}. If the first input is a FITS
@@ -19848,6 +19852,15 @@ re-arrange the necessary columns and it will write a
single output
table. Combined with regular expressions in large tables, this can be a
very powerful and convenient way to merge various tables into one.
+When @option{--coord} is given, no second catalog will be read. The second
+catalog will be created internally based on the values given to
address@hidden So column names aren't defined and you can only request
+integer column numbers that are less than the number of coordinates given
+to @option{--coord}. For example if you want to find the row matching RA of
+1.2345 and Dec of 6.7890, then you should use
address@hidden,6.7890}. But when using @option{--outcols}, you
+can't give @code{bRA}, or @code{b25}.
+
@item -l
@itemx --logasoutput
The output file will have the contents of the log file: indexes in the two
@@ -19877,6 +19890,25 @@ columns}. See the one-line examples above for some
usages of this option.
The coordinate columns of the second input. See the example in
@option{--ccol1} for more.
address@hidden -d FLT[,FLT]
address@hidden --coord=FLT[,FLT]
+Manually specify the coordinates to match against the given catalog. With
+this option, Match will not look for a second input file/table and will
+directly use the coordinates given to this option.
+
+When this option is called, the output changes in the following ways: 1)
+when @option{--outcols} is specified, for the second input, it can only
+accept integer numbers that are less than the number of values given to
+this option, see description of that option for more. 2) By default (when
address@hidden isn't used), only the matching row of the first table
+will be output (a single file), not two separate files (one for each
+table).
+
+This option is good when you have a (large) catalog and only want to match
+a single coordinate to it (for example to find the nearest catalog entry to
+your desired point). With this option, you can write the coordinates on the
+command-line and thus avoid the need to make a single-row file.
+
@item -a FLT[,FLT[,FLT]]
@itemx --aperture=FLT[,FLT[,FLT]]
Parameters of the aperture for matching. The values given to this option
@@ -23595,6 +23627,10 @@ Note: Do not use the maximum value for a blank value
of a general
@ref{Library blank values} for the definition and usage of blank values.
@end deftypefun
address@hidden int gal_type_is_int (uint8_t @code{type})
+Return 1 if the type is an integer (any width and any sign).
address@hidden deftypefun
+
@deftypefun int gal_type_is_list (uint8_t @code{type})
Return 1 if the type is a linked list and zero otherwise.
@end deftypefun
diff --git a/lib/gnuastro-internal/commonopts.h
b/lib/gnuastro-internal/commonopts.h
index 96046c2..cadd541 100644
--- a/lib/gnuastro-internal/commonopts.h
+++ b/lib/gnuastro-internal/commonopts.h
@@ -266,7 +266,7 @@ struct argp_option gal_commonopts_options[] =
GAL_OPTIONS_KEY_TABLEFORMAT,
"STR",
0,
- "Table format: `fits-ascii', `fits-binary'.",
+ "Table fmt: `fits-ascii', `fits-binary', `txt'.",
GAL_OPTIONS_GROUP_OUTPUT,
&cp->tableformat,
GAL_TYPE_STRING,
diff --git a/lib/gnuastro/type.h b/lib/gnuastro/type.h
index a57214e..195cfce 100644
--- a/lib/gnuastro/type.h
+++ b/lib/gnuastro/type.h
@@ -138,6 +138,9 @@ void
gal_type_max(uint8_t type, void *in);
int
+gal_type_is_int(uint8_t type);
+
+int
gal_type_is_list(uint8_t type);
int
diff --git a/lib/options.c b/lib/options.c
index 2e176ed..5e1d38a 100644
--- a/lib/options.c
+++ b/lib/options.c
@@ -528,10 +528,10 @@ gal_options_read_interpmetric(struct argp_option *option,
char *arg,
gal_checkset_allocate_copy("manhattan", &str);
break;
default:
- error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix
the "
- "problem. The code %u is not recognized as a nearest-neighbor "
- "interpolation metric", __func__, PACKAGE_BUGREPORT,
- *(uint8_t *)(option->value));
+ error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to "
+ "fix the problem. The code %u is not recognized as a "
+ "nearest-neighbor interpolation metric", __func__,
+ PACKAGE_BUGREPORT, *(uint8_t *)(option->value));
}
return str;
}
@@ -546,10 +546,10 @@ gal_options_read_interpmetric(struct argp_option *option,
char *arg,
else if ( !strcmp(arg, "manhattan") )
*(uint8_t *)(option->value) = GAL_INTERPOLATE_CLOSE_METRIC_MANHATTAN;
else
- error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to `%s' "
- "option) isn't valid. Currently only `radial' and "
- "`manhattan' metrics are recognized for nearest neighbor
"
- "interpolation", arg, option->name);
+ error_at_line(EXIT_FAILURE, 0, filename, lineno, "`%s' (value to "
+ "`%s' option) isn't valid. Currently only `radial' "
+ "and `manhattan' metrics are recognized for nearest "
+ "neighbor interpolation", arg, option->name);
/* For no un-used variable warning. This function doesn't need the
pointer. */
diff --git a/lib/type.c b/lib/type.c
index 560a305..af21dec 100644
--- a/lib/type.c
+++ b/lib/type.c
@@ -280,7 +280,29 @@ gal_type_max(uint8_t type, void *in)
case GAL_TYPE_FLOAT32: *(float *) in = FLT_MAX; break;
case GAL_TYPE_FLOAT64: *(double *) in = DBL_MAX; break;
default:
- error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__,
type);
+ error(EXIT_FAILURE, 0, "%s: type code %d not recognized", __func__,
+ type);
+ }
+}
+
+
+
+
+
+int
+gal_type_is_int(uint8_t type)
+{
+ switch(type)
+ {
+ case GAL_TYPE_UINT8: return 1;
+ case GAL_TYPE_INT8: return 1;
+ case GAL_TYPE_UINT16: return 1;
+ case GAL_TYPE_INT16: return 1;
+ case GAL_TYPE_UINT32: return 1;
+ case GAL_TYPE_INT32: return 1;
+ case GAL_TYPE_UINT64: return 1;
+ case GAL_TYPE_INT64: return 1;
+ default: return 0;
}
}
diff --git a/tests/match/merged-cols.sh b/tests/match/merged-cols.sh
index 3e4ac2a..9a21aa3 100755
--- a/tests/match/merged-cols.sh
+++ b/tests/match/merged-cols.sh
@@ -53,6 +53,6 @@ if [ ! -f $execname ]; then echo "$execname not created.";
exit 77; fi
# `check_with_program' can be something like `Valgrind' or an empty
# string. Such programs will execute the command if present and help in
# debugging when the developer doesn't have access to the user's system.
-$check_with_program $execname $cat1 $cat2 --aperture=0.5 \
- -omatch-merged-cols.txt \
+$check_with_program $execname $cat1 $cat2 --aperture=0.5 --ccol1=2,3 \
+ --ccol2=2,3 -omatch-merged-cols.txt \
--outcols=a1,aEFGH,bACCU1,aIJKL,bACCU2
diff --git a/tests/match/positions.sh b/tests/match/positions.sh
index 2622750..e9b51c9 100755
--- a/tests/match/positions.sh
+++ b/tests/match/positions.sh
@@ -53,5 +53,5 @@ if [ ! -f $execname ]; then echo "$execname not created.";
exit 77; fi
# `check_with_program' can be something like `Valgrind' or an empty
# string. Such programs will execute the command if present and help in
# debugging when the developer doesn't have access to the user's system.
-$check_with_program $execname $cat1 $cat2 --aperture=0.5 --log \
- --output=match-positions.fits
+$check_with_program $execname $cat1 $cat2 --aperture=0.5 --log --ccol1=2,3 \
+ --ccol2=2,3 --output=match-positions.fits
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master 95d7fc5: Match: New --coord option for single coordinate matching,
Mohammad Akhlaghi <=