gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 4ceecbb2: Library (kdtree.h and match.h): can


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 4ceecbb2: Library (kdtree.h and match.h): can account for inputs with no data
Date: Thu, 13 Oct 2022 07:50:40 -0400 (EDT)

branch: master
commit 4ceecbb2fc475c77403d61a3ec57512e07780688
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    Library (kdtree.h and match.h): can account for inputs with no data
    
    Until now, 'gal_kdtree_create' always assumed that the input coordinates
    dataset has atleast one element. Therefore, when it was given a dataset
    with no rows (can happen in a pipeline!), it would create a segmentation
    fault.
    
    With this commit, 'gal_kdtree_create' now returns the NULL pointer in such
    cases, and the 'gal_match_kdtree' function will also return NULL when the
    input k-d tree is empty. Therefore when an empty table is given to the
    Match program, it won't crash, it will just return a no-match output.
    
    This bug was reported by Sepideh Eskandarlou.
    
    This fixes bug #63207.
---
 NEWS              |  2 ++
 doc/gnuastro.texi |  2 ++
 lib/kdtree.c      |  3 +++
 lib/match.c       | 17 +++++++++--------
 4 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/NEWS b/NEWS
index 6a0c4493..99a1db09 100644
--- a/NEWS
+++ b/NEWS
@@ -279,6 +279,8 @@ See the end of the file for license conditions.
               found and fixed by Raul Infante-Sainz.
   bug #63189: MakeProfiles custom profiles become NaN with a single row
               being NaN, reported by Nafise Sedighi.
+  bug #63207: Match crashes when one input has no rows. Found by Sepideh
+              Eskandarlou.
 
 
 
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 62b19df8..7e7c7812 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -35272,6 +35272,7 @@ This function returns two @code{gal_data_t}s connected 
as a list, see descriptio
 The first dataset contains the indexes of left and right nodes of the subtrees 
for each input node.
 The index of the root node is written into the memory that @code{root} points 
to.
 @code{coords_raw} is the list of the input points (one @code{gal_data_t} per 
dimension, see above).
+If the input dataset has no data (@code{coords_raw->size==0}), this function 
will return a @code{NULL} pointer.
 
 For example, assume you have the simple set of points below (from the 
visualized example at the start of this section) in a plain-text file called 
@file{coordinates.txt}:
 
@@ -35549,6 +35550,7 @@ If internal allocation is necessary and the space is 
larger than @code{minmapsiz
 Use the k-d tree concept for finding matches between two catalogs, optionally 
in parallel (on @code{numthreads} threads).
 The k-d tree of the first input (@code{coord1_kdtree}), and its root index 
(@code{kdtree_root}), should be constructed and found before calling this 
function, to do this, you can use the @code{gal_kdtree_create} of @ref{K-d 
tree}.
 The desired @code{aperture} array is the same as @code{gal_match_sort_based} 
and described at the top of this section.
+If @code{coord1_kdtree==NULL},  this function will return a @code{NULL} 
pointer and write a value of @code{0} in the space that @code{nummatched} 
points to.
 
 The final number of matches is returned in @code{nummatched} and the format of 
the returned dataset (three columns) is described above.
 If internal allocation is necessary and the space is larger than 
@code{minmapsize}, the space will be not allocated in the RAM, but in a file, 
see description of @option{--minmapsize} and @code{--quietmmap} in 
@ref{Processing options}.
diff --git a/lib/kdtree.c b/lib/kdtree.c
index b4de5f46..a84054a7 100644
--- a/lib/kdtree.c
+++ b/lib/kdtree.c
@@ -447,6 +447,9 @@ gal_kdtree_create(gal_data_t *coords_raw, size_t *root)
 {
   struct kdtree_params p={0};
 
+  /* If there are no coordinates, just return NULL. */
+  if(coords_raw->size==0) return NULL;
+
   /* Initialise the params structure. */
   kdtree_prepare(&p, coords_raw);
 
diff --git a/lib/match.c b/lib/match.c
index b4c750cf..d232841b 100644
--- a/lib/match.c
+++ b/lib/match.c
@@ -387,9 +387,8 @@ match_rearrange(gal_data_t *A, gal_data_t *B, struct 
match_sfll **bina)
 
 /* The matching has been done, write the output. */
 static gal_data_t *
-gal_match_output(gal_data_t *A, gal_data_t *B, size_t *A_perm,
-                 size_t *B_perm, struct match_sfll **bina,
-                 size_t minmapsize, int quietmmap)
+match_output(gal_data_t *A, gal_data_t *B, size_t *A_perm, size_t *B_perm,
+             struct match_sfll **bina, size_t minmapsize, int quietmmap)
 {
   float r;
   double *rval;
@@ -398,7 +397,7 @@ gal_match_output(gal_data_t *A, gal_data_t *B, size_t 
*A_perm,
   size_t ai, bi, nummatched=0;
   size_t *aind, *bind, match_i, nomatch_i;
 
-  /* Find how many matches there were in total */
+  /* Find how many matches there were in total. */
   for(ai=0;ai<A->size;++ai) if(bina[ai]) ++nummatched;
 
 
@@ -925,8 +924,7 @@ gal_match_sort_based(gal_data_t *coord1, gal_data_t *coord2,
 
 
   /* The match is done, write the output. */
-  out=gal_match_output(A, B, A_perm, B_perm, bina, minmapsize,
-                       quietmmap);
+  out=match_output(A, B, A_perm, B_perm, bina, minmapsize, quietmmap);
 
 
   /* Clean up. */
@@ -1347,6 +1345,10 @@ gal_match_kdtree(gal_data_t *coord1, gal_data_t *coord2,
   gal_data_t *out=NULL;
   struct match_kdtree_params p;
 
+  /* In case the 'k-d' tree is empty, just return a NULL pointer and the
+     number of matches to zero. */
+  if(coord1_kdtree==NULL) { *nummatched=0; return NULL; }
+
   /* Write the parameters into the structure. */
   p.A=coord1;
   p.B=coord2;
@@ -1365,8 +1367,7 @@ gal_match_kdtree(gal_data_t *coord1, gal_data_t *coord2,
   match_rearrange(p.A, p.B, p.bina);
 
   /* The match is done, write the output. */
-  out=gal_match_output(p.A, p.B, NULL, NULL, p.bina, minmapsize,
-                       quietmmap);
+  out=match_output(p.A, p.B, NULL, NULL, p.bina, minmapsize, quietmmap);
 
   /* Set 'nummatched' and return output. */
   *nummatched = out ?  out->next->next->size : 0;



reply via email to

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