gnuastro-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gnuastro-commits] master 346a256: Matched output can be a merging of bo


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 346a256: Matched output can be a merging of both input columns
Date: Tue, 5 Dec 2017 14:02:36 -0500 (EST)

branch: master
commit 346a256ca90a5b47ae187b2d3a4f7e9a3fb4ee8b
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>

    Matched output can be a merging of both input columns
    
    When the user wanted specific columns of the two inputs, until now Match
    would output the whole of both inputs in an arranged order. So another step
    was necessary to keep certain columns for higher level analysis. Match now
    has a `--outcols' option which the user can use to specify which columns of
    the two inputs they want in the output.
    
    To make this possible, it was necessary to have the number of columns
    matched with certain column selection options. Therefore `gal_table_read'
    was given a new pointer argument. When this pointer is not NULL, the number
    of columns in the output that match a given input are stored in the
    respective space.
---
 NEWS                        |   4 ++
 bin/crop/ui.c               |   2 +-
 bin/match/args.h            |  40 ++++++++-----
 bin/match/main.h            |   3 +
 bin/match/match.c           | 135 ++++++++++++++++++++++++++++++++++++--------
 bin/match/ui.c              | 122 ++++++++++++++++++++++++++++-----------
 bin/match/ui.h              |   1 +
 bin/mkprof/ui.c             |   2 +-
 bin/statistics/ui.c         |   2 +-
 bin/table/ui.c              |   2 +-
 doc/gnuastro.texi           |  86 +++++++++++++++++++---------
 lib/gnuastro/table.h        |   3 +-
 lib/table.c                 |  13 +++--
 tests/Makefile.am           |   3 +-
 tests/match/merged-cols.sh  |  53 +++++++++++++++++
 tests/match/positions-1.txt |   3 +
 tests/match/positions-2.txt |   3 +
 17 files changed, 370 insertions(+), 107 deletions(-)

diff --git a/NEWS b/NEWS
index 5429b65..e674196 100644
--- a/NEWS
+++ b/NEWS
@@ -92,6 +92,10 @@ GNU Astronomy Utilities NEWS                          -*- 
outline -*-
   the library (declared in `gnuastro/cosmology.h'). These functions are
   also used in the CosmicCalculator program.
 
+  `gal_table_read' can now return the number of columns matched with each
+  input column (for example with regular expressions), a new argument has
+  been added to allow this feature.
+
   `gal_fits_key_img_blank': returns the value that must be used in the
   BLANK keyword for the given type as defined by the FITS standard.
 
diff --git a/bin/crop/ui.c b/bin/crop/ui.c
index c30b958..e71be0b 100644
--- a/bin/crop/ui.c
+++ b/bin/crop/ui.c
@@ -599,7 +599,7 @@ ui_read_cols(struct cropparams *p)
 
   /* Read the desired columns from the file. */
   cols=gal_table_read(p->catname, p->cathdu, colstrs, p->cp.searchin,
-                      p->cp.ignorecase, p->cp.minmapsize);
+                      p->cp.ignorecase, p->cp.minmapsize, NULL);
 
 
   /* Set the number of objects (rows in each column). */
diff --git a/bin/match/args.h b/bin/match/args.h
index 9f780cc..a0d36fa 100644
--- a/bin/match/args.h
+++ b/bin/match/args.h
@@ -63,6 +63,33 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_MANDATORY,
       GAL_OPTIONS_NOT_SET
     },
+    {
+      "notmatched",
+      UI_KEY_NOTMATCHED,
+      0,
+      0,
+      "Output is rows that don't match.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->notmatched,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET
+    },
+    {
+      "outcols",
+      UI_KEY_OUTCOLS,
+      "STR",
+      0,
+      "Out cols in CSV, `a': first, `b': second input.",
+      GAL_OPTIONS_GROUP_OUTPUT,
+      &p->outcols,
+      GAL_OPTIONS_NO_ARG_TYPE,
+      GAL_OPTIONS_RANGE_0_OR_1,
+      GAL_OPTIONS_NOT_MANDATORY,
+      GAL_OPTIONS_NOT_SET,
+      gal_options_parse_csv_strings
+    },
 
 
 
@@ -115,19 +142,6 @@ struct argp_option program_options[] =
       GAL_OPTIONS_NOT_SET,
       gal_options_parse_csv_float64
     },
-    {
-      "notmatched",
-      UI_KEY_NOTMATCHED,
-      0,
-      0,
-      "Output is rows that don't match.",
-      UI_GROUP_CATALOGMATCH,
-      &p->notmatched,
-      GAL_OPTIONS_NO_ARG_TYPE,
-      GAL_OPTIONS_RANGE_0_OR_1,
-      GAL_OPTIONS_NOT_MANDATORY,
-      GAL_OPTIONS_NOT_SET
-    },
 
 
 
diff --git a/bin/match/main.h b/bin/match/main.h
index 1419dfa..3bd8a34 100644
--- a/bin/match/main.h
+++ b/bin/match/main.h
@@ -55,6 +55,7 @@ struct matchparams
   char                  *hdu2;  /* Second input's HDU.                  */
   gal_data_t           *ccol1;  /* Array of firs input column names.    */
   gal_data_t           *ccol2;  /* Array of second input column names.  */
+  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.  */
   uint8_t          notmatched;  /* Output is rows that don't match.     */
@@ -63,6 +64,8 @@ struct matchparams
   int                    mode;  /* Mode of operation: image or catalog. */
   gal_data_t           *cols1;  /* Column values of first input.        */
   gal_data_t           *cols2;  /* Column values of second input.       */
+  gal_list_str_t       *acols;  /* Output columns from first input.     */
+  gal_list_str_t       *bcols;  /* Output columns from second input.    */
   char               *logname;  /* Name of log file.                    */
   char              *out1name;  /* Name of first matched output.        */
   char              *out2name;  /* Name of second matched output.       */
diff --git a/bin/match/match.c b/bin/match/match.c
index a8f4c23..c963479 100644
--- a/bin/match/match.c
+++ b/bin/match/match.c
@@ -42,20 +42,34 @@ along with Gnuastro. If not, see 
<http://www.gnu.org/licenses/>.
 
 /* Read the catalog in the given file and use the given permutation to keep
    the proper columns. */
-static void
-match_catalog_write(struct matchparams *p, char *filename, char *hdu,
-                    size_t *permutation, size_t nummatched, char *outname,
-                    char *extname)
+static gal_data_t *
+match_catalog_read_write_all(struct matchparams *p, size_t *permutation,
+                             size_t nummatched, int f1s2,
+                             size_t **numcolmatch)
 {
   size_t origsize;
   gal_data_t *tmp, *cat;
   gal_list_void_t *arrays=NULL;
 
+  char *hdu            = (f1s2==1) ? p->cp.hdu     : p->hdu2;
+  gal_list_str_t *cols = (f1s2==1) ? p->acols      : p->bcols;
+  char *extname        = (f1s2==1) ? "INPUT_1"     : "INPUT_2";
+  char *outname        = (f1s2==1) ? p->out1name   : p->out2name;
+  char *filename       = (f1s2==1) ? p->input1name : p->input2name;
+
+  /* When the output contains columns from both inputs, we need to keep the
+     number of columns matched against each column identifier. */
+  if(p->outcols)
+    *numcolmatch=gal_data_malloc_array(GAL_TYPE_SIZE_T,
+                                       gal_list_str_number(cols), __func__,
+                                       "numcolmatch");
+
   /* Read the full table. */
-  cat=gal_table_read(filename, hdu, NULL,p->cp.searchin, p->cp.ignorecase,
-                     p->cp.minmapsize);
+  cat=gal_table_read(filename, hdu, cols, p->cp.searchin, p->cp.ignorecase,
+                     p->cp.minmapsize, *numcolmatch);
   origsize=cat->size;
 
+
   /* Go over each column and permute its contents. */
   for(tmp=cat; tmp!=NULL; tmp=tmp->next)
     {
@@ -83,27 +97,79 @@ match_catalog_write(struct matchparams *p, char *filename, 
char *hdu,
         tmp->size=tmp->dsize[0]=nummatched;
     }
 
-  /* Write the catalog to the output. */
-  gal_table_write(cat, NULL, p->cp.tableformat, outname, extname);
 
-  /* Correct arrays and sizes (when `notmatched' was called). The `array'
-     element has to be corrected for later freeing. */
-  if(p->notmatched)
+  /* Write the catalog to the output. */
+  if(p->outcols)
+    return cat;
+  else
     {
-      /* Reverse the list of array pointers to write them back in. */
-      gal_list_void_reverse(&arrays);
+      /* Write the catalog to a file. */
+      gal_table_write(cat, NULL, p->cp.tableformat, outname, extname);
 
-      /* Correct the array and size pointers. */
-      for(tmp=cat; tmp!=NULL; tmp=tmp->next)
+      /* Correct arrays and sizes (when `notmatched' was called). The
+         `array' element has to be corrected for later freeing.
+
+         IMPORTANT: `--notmatched' cannot be called with `--outcols'. So
+         you don't have to worry about the checks here being done later. */
+      if(p->notmatched)
         {
-          tmp->array=gal_list_void_pop(&arrays);
-          tmp->size=tmp->dsize[0]=origsize;
-          tmp->block=NULL;
+          /* Reverse the list of array pointers to write them back in. */
+          gal_list_void_reverse(&arrays);
+
+          /* Correct the array and size pointers. */
+          for(tmp=cat; tmp!=NULL; tmp=tmp->next)
+            {
+              tmp->array=gal_list_void_pop(&arrays);
+              tmp->size=tmp->dsize[0]=origsize;
+              tmp->block=NULL;
+            }
         }
+
+      /* Clean up. */
+      gal_list_data_free(cat);
+      return NULL;
     }
+}
+
+
 
-  /* Clean up. */
-  gal_list_data_free(cat);
+
+
+/* When specific columns from both inputs are requested, this function
+   will write them out into a single table. */
+static void
+match_catalog_write_one(struct matchparams *p, gal_data_t *a, gal_data_t *b,
+                        size_t *acolmatch, size_t *bcolmatch)
+{
+  gal_data_t *cat=NULL;
+  size_t i, j, ac=0, bc=0;
+  char **strarr=p->outcols->array;
+
+  /* Go over the initial list of strings. */
+  for(i=0; i<p->outcols->size; ++i)
+    switch(strarr[i][0])
+      {
+      case 'a':
+        for(j=0;j<acolmatch[ac];++j)
+          gal_list_data_add(&cat, gal_list_data_pop(&a));
+        ac++;
+        break;
+
+      case 'b':
+        for(j=0;j<bcolmatch[bc];++j)
+          gal_list_data_add(&cat, gal_list_data_pop(&b));
+        bc++;
+        break;
+
+      default:
+        error(EXIT_FAILURE, 0, "a bug! Please contact us at %s to fix the "
+              "problem. the value to strarr[%zu][0] (%c) is not recognized",
+              PACKAGE_BUGREPORT, i, strarr[i][0]);
+      }
+
+  /* Reverse the table and write it out. */
+  gal_list_data_reverse(&cat);
+  gal_table_write(cat, NULL, p->cp.tableformat, p->cp.output, "MATCHED");
 }
 
 
@@ -114,8 +180,9 @@ static void
 match_catalog(struct matchparams *p)
 {
   uint32_t *u, *uf;
-  size_t nummatched;
   gal_data_t *tmp, *mcols;
+  gal_data_t *a=NULL, *b=NULL;
+  size_t nummatched, *acolmatch, *bcolmatch;
 
   /* Find the matching coordinates. We are doing the processing in
      place, */
@@ -128,10 +195,28 @@ match_catalog(struct matchparams *p)
       /* Read all the first catalog columns. */
       if(p->logasoutput==0)
         {
-          match_catalog_write(p, p->input1name, p->cp.hdu, mcols->array,
-                              nummatched, p->out1name, "INPUT_1");
-          match_catalog_write(p, p->input2name, p->hdu2, mcols->next->array,
-                              nummatched, p->out2name, "INPUT_2");
+          /* Read (and possibly write) the outputs. Note that we only need
+             to read the table when it is necessary for the output (the
+             user user might have asked for `--outcols', only with columns
+             of one of the two inputs. */
+          if(p->outcols==NULL || p->acols)
+            a=match_catalog_read_write_all(p, mcols->array, nummatched,
+                                           1, &acolmatch);
+          if(p->outcols==NULL || p->bcols)
+            b=match_catalog_read_write_all(p, mcols->next->array, nummatched,
+                                           2, &bcolmatch);
+
+          /* If one catalog (with specific columns from either of the two
+             inputs) was requested, then write it out. */
+          if(p->outcols)
+            {
+              /* Arrange the columns and write the output. */
+              match_catalog_write_one(p, a, b, acolmatch, bcolmatch);
+
+              /* Clean up. */
+              if(acolmatch) free(acolmatch);
+              if(bcolmatch) free(bcolmatch);
+            }
         }
 
       /* Write the raw information in a log file if necessary.  */
diff --git a/bin/match/ui.c b/bin/match/ui.c
index c08eba2..032ec3d 100644
--- a/bin/match/ui.c
+++ b/bin/match/ui.c
@@ -209,13 +209,16 @@ parse_opt(int key, char *arg, struct argp_state *state)
 /***************       Sanity Check         *******************/
 /**************************************************************/
 /* Read and check ONLY the options. When arguments are involved, do the
-   check in `ui_check_options_and_arguments'.
+   check in `ui_check_options_and_arguments'. */
 static void
 ui_read_check_only_options(struct matchparams *p)
 {
-
+  if(p->outcols && p->notmatched)
+    error(EXIT_FAILURE, 0, "`--outcols' and `--notmatched' cannot be called "
+          "at the same time. The former is only for cases when the matches "
+          "are required");
 }
-*/
+
 
 
 
@@ -402,7 +405,7 @@ ui_read_columns_to_double(struct matchparams *p, char 
*filename, char *hdu,
 
   /* Read the columns. */
   tout=gal_table_read(filename, hdu, cols, cp->searchin, cp->ignorecase,
-                     cp->minmapsize);
+                      cp->minmapsize, NULL);
 
   /* A small sanity check. */
   if(gal_list_data_number(tout)!=numcols)
@@ -525,6 +528,40 @@ ui_read_columns(struct matchparams *p)
 
 
 static void
+ui_preparations_out_cols(struct matchparams *p)
+{
+  size_t i;
+  char **strarr=p->outcols->array;
+
+  /* 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]);
+      }
+
+  /* Revere the lists so they correspond to the input order. */
+  gal_list_str_reverse(&p->acols);
+  gal_list_str_reverse(&p->bcols);
+}
+
+
+
+
+
+static void
 ui_preparations_out_name(struct matchparams *p)
 {
   if(p->logasoutput)
@@ -547,42 +584,58 @@ ui_preparations_out_name(struct matchparams *p)
     }
   else
     {
-      /* Set `p->out1name' and `p->out2name'. */
-      if(p->cp.output)
+      if(p->outcols)
         {
-          if( gal_fits_name_is_fits(p->cp.output) )
-            {
-              gal_checkset_allocate_copy(p->cp.output, &p->out1name);
-              gal_checkset_allocate_copy(p->cp.output, &p->out2name);
-            }
-          else
-            {
-              p->out1name=gal_checkset_automatic_output(&p->cp, p->cp.output,
-                                                        "_matched_1.txt");
-              p->out2name=gal_checkset_automatic_output(&p->cp, p->cp.output,
-                                                        "_matched_2.txt");
-            }
+          if(p->cp.output==NULL)
+            p->cp.output = gal_checkset_automatic_output(&p->cp,
+                 p->input1name, ( p->cp.tableformat==GAL_TABLE_FORMAT_TXT
+                                  ? "_matched.txt" : "_matched.fits") );
+          gal_checkset_writable_remove(p->cp.output, 0, p->cp.dontdelete);
         }
       else
         {
-          if(p->cp.tableformat==GAL_TABLE_FORMAT_TXT)
+          /* Set `p->out1name' and `p->out2name'. */
+          if(p->cp.output)
             {
-              p->out1name=gal_checkset_automatic_output(&p->cp, p->input1name,
-                                                        "_matched_1.txt");
-              p->out2name=gal_checkset_automatic_output(&p->cp, p->input2name,
-                                                        "_matched_2.txt");
+              if( gal_fits_name_is_fits(p->cp.output) )
+                {
+                  gal_checkset_allocate_copy(p->cp.output, &p->out1name);
+                  gal_checkset_allocate_copy(p->cp.output, &p->out2name);
+                }
+              else
+                {
+                  p->out1name=gal_checkset_automatic_output(&p->cp,
+                                                            p->cp.output,
+                                                            "_matched_1.txt");
+                  p->out2name=gal_checkset_automatic_output(&p->cp,
+                                                            p->cp.output,
+                                                            "_matched_2.txt");
+                }
             }
           else
             {
-              p->out1name=gal_checkset_automatic_output(&p->cp, p->input1name,
-                                                        "_matched.fits");
-              gal_checkset_allocate_copy(p->out1name, &p->out2name);
+              if(p->cp.tableformat==GAL_TABLE_FORMAT_TXT)
+                {
+                  p->out1name=gal_checkset_automatic_output(&p->cp,
+                                                            p->input1name,
+                                                            "_matched_1.txt");
+                  p->out2name=gal_checkset_automatic_output(&p->cp,
+                                                            p->input2name,
+                                                            "_matched_2.txt");
+                }
+              else
+                {
+                  p->out1name=gal_checkset_automatic_output(&p->cp,
+                                                            p->input1name,
+                                                            "_matched.fits");
+                  gal_checkset_allocate_copy(p->out1name, &p->out2name);
+                }
             }
-        }
 
-      /* Make sure no file with these names exists. */
-      gal_checkset_writable_remove(p->out1name, 0, p->cp.dontdelete);
-      gal_checkset_writable_remove(p->out2name, 0, p->cp.dontdelete);
+          /* Make sure no file with these names exists. */
+          gal_checkset_writable_remove(p->out1name, 0, p->cp.dontdelete);
+          gal_checkset_writable_remove(p->out2name, 0, p->cp.dontdelete);
+        }
 
       /* If a log file is necessary, set its name here. */
       if(p->cp.log)
@@ -610,7 +663,10 @@ ui_preparations(struct matchparams *p)
     error(EXIT_FAILURE, 0, "currently Match only works on catalogs, we will "
           "implement the WCS matching routines later");
   else
-    ui_read_columns(p);
+    {
+      ui_read_columns(p);
+      if(p->outcols) ui_preparations_out_cols(p);
+    }
 
   /* Set the output filename. */
   ui_preparations_out_name(p);
@@ -669,9 +725,9 @@ ui_read_check_inputs_setup(int argc, char *argv[], struct 
matchparams *p)
 
 
   /* Read the options into the program's structure, and check them and
-     their relations prior to printing.
+     their relations prior to printing. */
   ui_read_check_only_options(p);
-  */
+
 
   /* Print the option values if asked. Note that this needs to be done
      after the option checks so un-sane values are not printed in the
diff --git a/bin/match/ui.h b/bin/match/ui.h
index 6c70f47..e56730a 100644
--- a/bin/match/ui.h
+++ b/bin/match/ui.h
@@ -55,6 +55,7 @@ enum option_keys_enum
   /* Only with long version (start with a value 1000, the rest will be set
      automatically). */
   UI_KEY_NOTMATCHED      = 1000,
+  UI_KEY_OUTCOLS,
 };
 
 
diff --git a/bin/mkprof/ui.c b/bin/mkprof/ui.c
index 897bd58..84a7fa3 100644
--- a/bin/mkprof/ui.c
+++ b/bin/mkprof/ui.c
@@ -620,7 +620,7 @@ ui_read_cols(struct mkprofparams *p)
 
   /* Read the desired columns from the file. */
   cols=gal_table_read(p->catname, p->cp.hdu, colstrs, p->cp.searchin,
-                      p->cp.ignorecase, p->cp.minmapsize);
+                      p->cp.ignorecase, p->cp.minmapsize, NULL);
 
   /* Set the number of objects. */
   p->num=cols->size;
diff --git a/bin/statistics/ui.c b/bin/statistics/ui.c
index 4626f54..4187afc 100644
--- a/bin/statistics/ui.c
+++ b/bin/statistics/ui.c
@@ -719,7 +719,7 @@ ui_read_columns(struct statisticsparams *p)
 
   /* Read the desired column(s). */
   cols=gal_table_read(p->inputname, p->cp.hdu, column, p->cp.searchin,
-                      p->cp.ignorecase, p->cp.minmapsize);
+                      p->cp.ignorecase, p->cp.minmapsize, NULL);
 
   /* Put the columns into the proper gal_data_t. */
   size=cols->size;
diff --git a/bin/table/ui.c b/bin/table/ui.c
index f60e708..860d4ad 100644
--- a/bin/table/ui.c
+++ b/bin/table/ui.c
@@ -319,7 +319,7 @@ ui_preparations(struct tableparams *p)
 
   /* Read in the table columns. */
   p->table=gal_table_read(p->filename, cp->hdu, p->columns, cp->searchin,
-                          cp->ignorecase, cp->minmapsize);
+                          cp->ignorecase, cp->minmapsize, NULL);
 
   /* If there was no actual data in the file, then inform the user and
      abort. */
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 2a8af30..08fca58 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15633,6 +15633,13 @@ $ astmatch --aperture=5e-10 --ccol1=5 --ccol2=10 
in1.fits in2.txt
 ##  The number of values to these determines the dimensionality).
 $ astmatch --aperture=2 input1.txt input2.fits
 
+## Similar to before, but the output is created by merging various
+## columns from the two inputs: columns 1, RA, DEC from the first
+## input, followed by all columns starting with MAG and the 8th
+## column from second input and finaly the 10th from first input.
+$ astmatch --aperture=2 input1.txt input2.fits                   \
+           --outcols=a1,aRA,aDEC,b/^MAG/,bBRG,a10
+
 ## Match the two catalogs within an elliptical aperture of 1 and 2
 ## arcseconds along RA and Dec respectively.
 $ astmatch --aperture=1/3600,2/3600 in1.fits in2.txt
@@ -15644,31 +15651,32 @@ $ astmatch --ccol1=RA,DEC --ccol2=RA_D,DEC_D 
--aperture0.5/3600  \
 @end example
 
 Two inputs are necessary for Match to start processing. The inputs can be
-plain text tables or FITS tables, see @ref{Tables}. When @option{--quiet}
-is not called, Match will print the number of matches found in standard
-output (on the command-line). If no match was found, no output file will be
-created (table or log file). When matches are found, the output file(s)
-will be the re-arranged input tables such that the rows match each other:
-both output tables will have the same number of rows which are matched with
-each other. If the @option{--logasoutput} option is called, the output will
-be a single table with the contents of the log file, see below.
-
-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
-file, the common @option{--hdu} option (see @ref{Input output options})
-should be used to identify the extension. When the second input is FITS,
-the extension can be specified with @option{--hdu2}.
+plain text tables or FITS tables, 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 file, the common
address@hidden option (see @ref{Input output options}) should be used to
+identify the extension. When the second input is FITS, the extension must
+be specified with @option{--hdu2}.
+
+When @option{--quiet} is not called, Match will print the number of matches
+found in standard output (on the command-line). If no match was found, no
+output file will be created (table or log file). When matches are found, by
+default, the output file(s) will be the re-arranged input tables such that
+the rows match each other: both output tables will have the same number of
+rows which are matched with each other. If @option{--outcols} is called,
+the output is a single table with rows chosen from either of the two inputs
+in any order, see the description of @option{--outcols}. If the
address@hidden option is called, the output will be a single table
+with the contents of the log file, see below.
 
 If no output file name is given with the @option{--output} option, then
 automatic output @ref{Automatic output} will be used to determine the
-output names. Depending on @option{--tableformat} (see @ref{Input output
-options}), the output will then be a multi-extension FITS file or two plain
-text files.
-
-When @option{--output} is a FITS file (and @option{--logasoutput} is not
-called, see below), the re-arranged inputs will be two extensions of the
-output FITS file. If the output name is a text file, then two files will be
-created with a @file{_matched_1.txt} and @file{_matched_2.txt} suffix.
+output name(s). Depending on @option{--tableformat} (see @ref{Input output
+options}), the output will then be a (possibly multi-extension) FITS file
+or (possibly two) plain text file(s). When the output is a FITS file, the
+default re-arranged inputs will be two extensions of the output FITS
+file. With @option{--outcols} and @option{--logasoutput}, the FITS output
+will be a single table (in one extension).
 
 When the @option{--log} option is called (see @ref{Operating mode
 options}), Match will also create a file named @file{astmatch.fits} (or
@@ -15690,6 +15698,25 @@ The extension/HDU of the second input if it is a FITS 
file. When it isn't a
 FITS file, this option's value is ignored. For the first input, the common
 option @option{--hdu} must be used.
 
address@hidden --outcols=STR
+Columns from both inputs to write into a single matched table output. The
+value to @code{--outcols} must be a comma-separated list of strings, for
+example @option{--outcols=a1,bRA,bDEC}. The first character of each string
+specifies the input catalog: @option{a} for the first and @option{b} for
+the second. The rest of the characters of the string will be directly used
+to identify the proper column(s) in the respective table. See
address@hidden table columns} for how columns can be specified in
+Gnuastro. In this example, the output will have three columns: the first
+column of the first input and the @option{RA} and @option{DEC} columns of
+the second input.
+
+Another example is given in the one-line examples above. Compared to the
+default case (where two tables with all their columns) are printed, using
+this option is much faster: it will only read and re-arrange the necessary
+columns and it will write a single outputtable. Combined with regular
+expressions in large tables, this can be a very powerful and convenient way
+to retrieve your desired information and do the match at the same time.
+
 @item -l
 @itemx --logasoutput
 The output file will have the contents of the log file: indexs in the two
@@ -15701,7 +15728,10 @@ output behavior (two tables containing the re-arranged 
inputs) will be
 @item --notmatched
 Write the non-matching rows into the outputs, not the matched ones. Note
 that with this option, the two output tables will not necessarily have the
-same number of rows.
+same number of rows. Therefore, this option cannot be called with
address@hidden @option{--outcols} prints mixed columns from both
+inputs, so they must all have the same number of elements and must
+correspond to each other.
 
 @item -c INT/STR[,INT/STR]
 @itemx --ccol1=INT/STR[,INT/STR]
@@ -15711,7 +15741,7 @@ option. The values can be the column number (counting 
from 1), exact column
 name or a regular expression. For more, see @ref{Selecting table
 columns}. See the one-line examples above for some usages of this option.
 
address@hidden -c INT/STR[,INT/STR]
address@hidden -C INT/STR[,INT/STR]
 @itemx --ccol2=INT/STR[,INT/STR]
 The coordinate columns of the second input. See the example in
 @option{--ccol1} for more.
@@ -21942,7 +21972,7 @@ $ asttable --info table.fits
 @end example
 @end deftypefun
 
address@hidden {gal_data_t *} gal_table_read (char @code{*filename}, char 
@code{*hdu}, gal_list_str_t @code{*cols}, int @code{searchin}, int 
@code{ignorecase}, int @code{minmapsize})
address@hidden {gal_data_t *} gal_table_read (char @code{*filename}, char 
@code{*hdu}, gal_list_str_t @code{*cols}, int @code{searchin}, int 
@code{ignorecase}, int @code{minmapsize}, size_t @code{colmatch})
 Read the specified columns in a text file (named @code{filename}) into a
 linked list of data structures. If the file is FITS, then @code{hdu} will
 also be used, otherwise, @code{hdu} is ignored.
@@ -21963,6 +21993,10 @@ example from regular expressions), in this case, the 
order of output
 columns that correspond to that one input, are in order of the table (which
 column was read first). So the first requested column is the first popped
 data structure and so on.
+
+if @code{colmatch!=NULL}, it is assumed to be an array that has atleast the
+same number of elements as nodes in the @code{cols} list. The number of
+columns that matched each input column will be sored in each element.
 @end deftypefun
 
 @cindex Git
@@ -24250,7 +24284,7 @@ main(void)
 
   /* Read the desired columns. */
   columns = gal_table_read(inname, hdu, column_ids,
-                           GAL_TABLE_SEARCH_NAME, 1, -1);
+                           GAL_TABLE_SEARCH_NAME, 1, -1, NULL);
 
   /* Go over the columns, we'll assume that you don't know their type
    * a-priori, so we'll check  */
diff --git a/lib/gnuastro/table.h b/lib/gnuastro/table.h
index c080d4f..aea96c9 100644
--- a/lib/gnuastro/table.h
+++ b/lib/gnuastro/table.h
@@ -138,7 +138,8 @@ gal_table_print_info(gal_data_t *allcols, size_t numcols, 
size_t numrows);
 /************************************************************************/
 gal_data_t *
 gal_table_read(char *filename, char *hdu, gal_list_str_t *cols,
-               int searchin, int ignorecase, int minmapsize);
+               int searchin, int ignorecase, int minmapsize,
+               size_t *colmatch);
 
 
 
diff --git a/lib/table.c b/lib/table.c
index 71112e5..c917669 100644
--- a/lib/table.c
+++ b/lib/table.c
@@ -213,14 +213,14 @@ table_set_strcheck(gal_data_t *col, int searchin)
 static gal_list_sizet_t *
 make_list_of_indexs(gal_list_str_t *cols, gal_data_t *allcols,
                     size_t numcols, int searchin, int ignorecase,
-                    char *filename, char *hdu)
+                    char *filename, char *hdu, size_t *colmatch)
 {
   long tlong;
   int regreturn;
   regex_t *regex;
   gal_list_str_t *tmp;
-  size_t i, nummatch, len;
   gal_list_sizet_t *indexll=NULL;
+  size_t i, nummatch, colcount=0, len;
   char *str, *strcheck, *tailptr, *errorstring;
 
   /* Go over the given columns.  */
@@ -362,6 +362,10 @@ make_list_of_indexs(gal_list_str_t *cols, gal_data_t 
*allcols,
                      tmp->v, gal_tableintern_searchin_as_string(searchin));
             gal_tableintern_error_col_selection(filename, hdu, errorstring);
           }
+
+
+        /* Keep the value of `nummatch' if the user requested it. */
+        if(colmatch) colmatch[colcount++]=nummatch;
       }
 
   /* cols==NULL */
@@ -398,7 +402,8 @@ make_list_of_indexs(gal_list_str_t *cols, gal_data_t 
*allcols,
    on. */
 gal_data_t *
 gal_table_read(char *filename, char *hdu, gal_list_str_t *cols,
-               int searchin, int ignorecase, int minmapsize)
+               int searchin, int ignorecase, int minmapsize,
+               size_t *colmatch)
 {
   int tableformat;
   gal_list_sizet_t *indexll;
@@ -413,7 +418,7 @@ gal_table_read(char *filename, char *hdu, gal_list_str_t 
*cols,
 
   /* Get the list of indexs in the same order as the input list */
   indexll=make_list_of_indexs(cols, allcols, numcols, searchin,
-                              ignorecase, filename, hdu);
+                              ignorecase, filename, hdu, colmatch);
 
   /* Depending on the table format, read the columns into the output
      structure. Note that the functions here pop each index, read/store the
diff --git a/tests/Makefile.am b/tests/Makefile.am
index cf4c6b4..866486e 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -123,9 +123,10 @@ if COND_FITS
   fits/copyhdu.sh: fits/write.sh.log mkprof/mosaic2.sh.log
 endif
 if COND_MATCH
-  MAYBE_MATCH_TESTS = match/positions.sh
+  MAYBE_MATCH_TESTS = match/positions.sh match/merged-cols.sh
 
   match/positions.sh: prepconf.sh.log
+  match/merged-cols.sh: prepconf.sh.log
 endif
 if COND_MKCATALOG
   MAYBE_MKCATALOG_TESTS = mkcatalog/simple.sh mkcatalog/aperturephot.sh
diff --git a/tests/match/merged-cols.sh b/tests/match/merged-cols.sh
new file mode 100755
index 0000000..2af07da
--- /dev/null
+++ b/tests/match/merged-cols.sh
@@ -0,0 +1,53 @@
+# Match the two input catalogs and return merged output
+#
+# See the Tests subsection of the manual for a complete explanation
+# (in the Installing gnuastro section).
+#
+# Original author:
+#     Mohammad Akhlaghi <address@hidden>
+# Contributing author(s):
+#
+# Copying and distribution of this file, with or without modification,
+# are permitted in any medium without royalty provided the copyright
+# notice and this notice are preserved.  This file is offered as-is,
+# without any warranty.
+
+
+
+
+
+# Preliminaries
+# =============
+#
+# Set the variables (The executable is in the build tree). Do the
+# basic checks to see if the executable is made or if the defaults
+# file exists (basicchecks.sh is in the source tree).
+prog=match
+execname=../bin/$prog/ast$prog
+cat1=$topsrc/tests/$prog/positions-1.txt
+cat2=$topsrc/tests/$prog/positions-2.txt
+
+
+
+
+
+# Skip?
+# =====
+#
+# If the dependencies of the test don't exist, then skip it. There are two
+# types of dependencies:
+#
+#   - The executable was not made (for example due to a configure option),
+#
+#   - The input data was not made (for example the test that created the
+#     data file failed).
+if [ ! -f $execname ]; then echo "$execname not created."; exit 77; fi
+
+
+
+
+
+# Actual test script
+# ==================
+$execname $cat1 $cat2 --aperture=0.5 --log --output=match-positions.fits \
+          --outcols=a1,aEFGH,bACCU1,aIJKL,bACCU2 -omatch-merged-cols.txt
diff --git a/tests/match/positions-1.txt b/tests/match/positions-1.txt
index 5964218..b7e71b7 100644
--- a/tests/match/positions-1.txt
+++ b/tests/match/positions-1.txt
@@ -1,3 +1,6 @@
+# Column 1: ABCD
+# Column 2: EFGH
+# Column 3: IJKL
 1   1   1
 2   2   2
 3   3   3
diff --git a/tests/match/positions-2.txt b/tests/match/positions-2.txt
index 820dac8..cd41cbc 100644
--- a/tests/match/positions-2.txt
+++ b/tests/match/positions-2.txt
@@ -1,3 +1,6 @@
+# Column 1: ABCD
+# Column 2: ACCU1
+# Column 3: ACCU2
 1   8.20    7.90
 2   20.1    2.80
 3   4.80    5.20



reply via email to

[Prev in Thread] Current Thread [Next in Thread]