gnuastro-commits
[Top][All Lists]
Advanced

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

[gnuastro-commits] master 2e1deec: MakeCatalog: return position of pixel


From: Mohammad Akhlaghi
Subject: [gnuastro-commits] master 2e1deec: MakeCatalog: return position of pixel with minimum/maximum value
Date: Fri, 2 Oct 2020 00:16:27 -0400 (EDT)

branch: master
commit 2e1deec62b29d0506895e6f942306418ab6aeeca
Author: Mohammad Akhlaghi <mohammad@akhlaghi.org>
Commit: Mohammad Akhlaghi <mohammad@akhlaghi.org>

    MakeCatalog: return position of pixel with minimum/maximum value
    
    Until now, we would return positions only based on averaged properties of
    the object/clump labels. But in some scenarios, we explicity want the
    position of the minimum/maximum value of the object/clump.
    
    With this commit, six new columns have been added to MakeCatalog precisely
    for this purpose.
---
 NEWS                    |   5 ++
 bin/mkcatalog/args.h    |  96 +++++++++++++++++++--
 bin/mkcatalog/columns.c | 123 ++++++++++++++++++++------
 bin/mkcatalog/main.h    |  12 +++
 bin/mkcatalog/parse.c   | 225 +++++++++++++++++++++++++++++++++++++-----------
 bin/mkcatalog/ui.c      |  12 +++
 bin/mkcatalog/ui.h      |   6 ++
 doc/gnuastro.texi       |  23 ++++-
 8 files changed, 419 insertions(+), 83 deletions(-)

diff --git a/NEWS b/NEWS
index 39378a6..32fe210 100644
--- a/NEWS
+++ b/NEWS
@@ -41,6 +41,11 @@ See the end of the file for license conditions.
      'astquery' option, to easily search the contents of external databases
      within the image.
 
+  MakeCatalog:
+   - New columns to return the position of pixel with minimum or maximum
+     value: '--minvx', '--maxvx', '--minvy', '--maxvy', '--minvz',
+     '--maxvz'.
+
   Table:
    - New '--noblank' option will remove all rows in output table that have
      atleast one blank value in the specified columns. For example if
diff --git a/bin/mkcatalog/args.h b/bin/mkcatalog/args.h
index a8e7010..03018df 100644
--- a/bin/mkcatalog/args.h
+++ b/bin/mkcatalog/args.h
@@ -564,11 +564,95 @@ struct argp_option program_options[] =
       ui_column_codes_ll
     },
     {
+      "minvx",
+      UI_KEY_MINVX,
+      0,
+      0,
+      "Minimum value's X 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
+    },
+    {
+      "maxvx",
+      UI_KEY_MAXVX,
+      0,
+      0,
+      "Maximum value's X 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
+    },
+    {
+      "minvy",
+      UI_KEY_MINVY,
+      0,
+      0,
+      "Minimum value's Y 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
+    },
+    {
+      "maxvy",
+      UI_KEY_MAXVY,
+      0,
+      0,
+      "Maximum value's Y 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
+    },
+    {
+      "minvz",
+      UI_KEY_MINVZ,
+      0,
+      0,
+      "Minimum value's Z 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
+    },
+    {
+      "maxvz",
+      UI_KEY_MAXVZ,
+      0,
+      0,
+      "Maximum value's Z 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
+    },
+    {
       "minx",
       UI_KEY_MINX,
       0,
       0,
-      "Minimum first FITS axis position.",
+      "Minimum X axis position.",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
@@ -582,7 +666,7 @@ struct argp_option program_options[] =
       UI_KEY_MAXX,
       0,
       0,
-      "Maximum first FITS axis position.",
+      "Maximum X axis position.",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
@@ -596,7 +680,7 @@ struct argp_option program_options[] =
       UI_KEY_MINY,
       0,
       0,
-      "Minimum second FITS axis position.",
+      "Minimum Y axis position.",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
@@ -610,7 +694,7 @@ struct argp_option program_options[] =
       UI_KEY_MAXY,
       0,
       0,
-      "Maximum second FITS axis position.",
+      "Maximum Y axis position.",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
@@ -624,7 +708,7 @@ struct argp_option program_options[] =
       UI_KEY_MINZ,
       0,
       0,
-      "Minimum third FITS axis position.",
+      "Minimum Z axis position",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
@@ -638,7 +722,7 @@ struct argp_option program_options[] =
       UI_KEY_MAXZ,
       0,
       0,
-      "Maximum third FITS axis position.",
+      "Maximum Z axis position.",
       UI_GROUP_COLUMNS_POSITION_PIXEL,
       0,
       GAL_TYPE_INVALID,
diff --git a/bin/mkcatalog/columns.c b/bin/mkcatalog/columns.c
index 00bc599..f79d5a5 100644
--- a/bin/mkcatalog/columns.c
+++ b/bin/mkcatalog/columns.c
@@ -675,6 +675,84 @@ columns_define_alloc(struct mkcatalogparams *p)
           disp_precision = 3;
           oiflag[ OCOL_C_GZ ] = 1;
 
+        case UI_KEY_MINVX:
+          name           = "MIN_V_X";
+          unit           = "pixel";
+          ocomment       = "Minimum value's X pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MINVX ] = ciflag[ CCOL_MINVX ] = 1;
+          break;
+
+        case UI_KEY_MAXVX:
+          name           = "MAX_V_X";
+          unit           = "pixel";
+          ocomment       = "Maximum value's X pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MAXVX ] = ciflag[ CCOL_MAXVX ] = 1;
+          break;
+
+        case UI_KEY_MINVY:
+          name           = "MIN_V_Y";
+          unit           = "pixel";
+          ocomment       = "Minimum value's Y pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MINVY ] = ciflag[ CCOL_MINVY ] = 1;
+          break;
+
+        case UI_KEY_MAXVY:
+          name           = "MAX_V_Y";
+          unit           = "pixel";
+          ocomment       = "Maximum value's Y pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MAXVY ] = ciflag[ CCOL_MAXVY ] = 1;
+          break;
+
+        case UI_KEY_MINVZ:
+          name           = "MIN_V_Z";
+          unit           = "pixel";
+          ocomment       = "Minimum value's Z pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MINVZ ] = ciflag[ CCOL_MINVZ ] = 1;
+          break;
+
+        case UI_KEY_MAXVZ:
+          name           = "MAX_V_Z";
+          unit           = "pixel";
+          ocomment       = "Maximum value's Z pixel position.";
+          ccomment       = ocomment;
+          otype          = GAL_TYPE_UINT32;
+          ctype          = GAL_TYPE_UINT32;
+          disp_fmt       = 0;
+          disp_width     = 10;
+          disp_precision = 0;
+          oiflag[ OCOL_MAXVZ ] = ciflag[ CCOL_MAXVZ ] = 1;
+          break;
+
         case UI_KEY_MINX:
           name           = "MIN_X";
           unit           = "pixel";
@@ -1811,7 +1889,8 @@ columns_clump_brightness(double *ci)
 
 /* Measure the minimum and maximum positions. */
 static uint32_t
-columns_xy_extrema(struct mkcatalog_passparams *pp, double *oi, size_t *coord, 
int key)
+columns_xy_extrema(struct mkcatalog_passparams *pp, double *oi,
+                   size_t *coord, int key)
 {
   size_t ndim=pp->tile->ndim;
   gal_data_t *tile=pp->tile, *block=tile->block;
@@ -2032,6 +2111,13 @@ columns_fill(struct mkcatalog_passparams *pp)
           ((float *)colarr)[oind] = MKC_RATIO( oi[OCOL_C_GZ],
                                                oi[OCOL_C_NUMALL] );
 
+        case UI_KEY_MINVX: ((uint32_t *)colarr)[oind] = oi[OCOL_MINVX]; break;
+        case UI_KEY_MAXVX: ((uint32_t *)colarr)[oind] = oi[OCOL_MAXVX]; break;
+        case UI_KEY_MINVY: ((uint32_t *)colarr)[oind] = oi[OCOL_MINVY]; break;
+        case UI_KEY_MAXVY: ((uint32_t *)colarr)[oind] = oi[OCOL_MAXVY]; break;
+        case UI_KEY_MINVZ: ((uint32_t *)colarr)[oind] = oi[OCOL_MINVZ]; break;
+        case UI_KEY_MAXVZ: ((uint32_t *)colarr)[oind] = oi[OCOL_MAXVZ]; break;
+
         case UI_KEY_MINX:
         case UI_KEY_MAXX:
         case UI_KEY_MINY:
@@ -2301,29 +2387,18 @@ columns_fill(struct mkcatalog_passparams *pp)
             ((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_MINZ:
-            ((uint32_t *)colarr)[cind] = ci[CCOL_MINZ];
-            break;
-
-          case UI_KEY_MAXZ:
-            ((uint32_t *)colarr)[cind] = ci[CCOL_MAXZ];
-            break;
+          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_MINZ:  ((uint32_t *)colarr)[cind] = ci[CCOL_MINZ];  
break;
+          case UI_KEY_MAXZ:  ((uint32_t *)colarr)[cind] = ci[CCOL_MAXZ];  
break;
+          case UI_KEY_MINVX: ((uint32_t *)colarr)[cind] = ci[CCOL_MINVX]; 
break;
+          case UI_KEY_MAXVX: ((uint32_t *)colarr)[cind] = ci[CCOL_MAXVX]; 
break;
+          case UI_KEY_MINVY: ((uint32_t *)colarr)[cind] = ci[CCOL_MINVY]; 
break;
+          case UI_KEY_MAXVY: ((uint32_t *)colarr)[cind] = ci[CCOL_MAXVY]; 
break;
+          case UI_KEY_MINVZ: ((uint32_t *)colarr)[cind] = ci[CCOL_MINVZ]; 
break;
+          case UI_KEY_MAXVZ: ((uint32_t *)colarr)[cind] = ci[CCOL_MAXVZ]; 
break;
 
           case UI_KEY_W1:
           case UI_KEY_W2:
diff --git a/bin/mkcatalog/main.h b/bin/mkcatalog/main.h
index 95ed39a..195f004 100644
--- a/bin/mkcatalog/main.h
+++ b/bin/mkcatalog/main.h
@@ -87,6 +87,12 @@ enum objectcols
     OCOL_VXX,            /* Sum of (value-sky) * x * x.               */
     OCOL_VYY,            /* Sum of (value-sky) * y * y.               */
     OCOL_VXY,            /* Sum of (value-sky) * x * y.               */
+    OCOL_MINVX,          /* X of minimum pixel in values file.        */
+    OCOL_MAXVX,          /* X of maximum pixel in values file.        */
+    OCOL_MINVY,          /* Y of minimum pixel in values file.        */
+    OCOL_MAXVY,          /* Y of maximum pixel in values file.        */
+    OCOL_MINVZ,          /* Z of minimum pixel in values file.        */
+    OCOL_MAXVZ,          /* Z of maximum pixel in values file.        */
     OCOL_SUMSKY,         /* Sum of sky value on this object.          */
     OCOL_NUMSKY,         /* Number of sky value on this object.       */
     OCOL_SUMVAR,         /* Sum of sky variance value on this object. */
@@ -140,6 +146,12 @@ enum clumpcols
     CCOL_VXX,            /* Sum of flux*x*x of this clump.            */
     CCOL_VYY,            /* Sum of flux*y*y of this clump.            */
     CCOL_VXY,            /* Sum of flux*x*y of this clump.            */
+    CCOL_MINVX,          /* X of minimum pixel in values array.       */
+    CCOL_MAXVX,          /* X of maximum pixel in values array.       */
+    CCOL_MINVY,          /* Y of minimum pixel in values array.       */
+    CCOL_MAXVY,          /* Y of maximum pixel in values array.       */
+    CCOL_MINVZ,          /* Z of minimum pixel in values array.       */
+    CCOL_MAXVZ,          /* Z of maximum pixel in values array.       */
     CCOL_SUMSKY,         /* Sum of sky value on this clump.           */
     CCOL_NUMSKY,         /* Number of sky value on this clump.        */
     CCOL_SUMVAR,         /* Sum of sky variance value on this clump.  */
diff --git a/bin/mkcatalog/parse.c b/bin/mkcatalog/parse.c
index b584ffa..66b9ab3 100644
--- a/bin/mkcatalog/parse.c
+++ b/bin/mkcatalog/parse.c
@@ -440,12 +440,16 @@ parse_objects(struct mkcatalog_passparams *pp)
 
   double *oi=pp->oi;
   gal_data_t *xybin=NULL;
+  size_t maxima_c[3]={0,0,0};
   size_t *tsize=pp->tile->dsize;
   uint8_t *u, *uf, goodvalue, *xybinarr=NULL;
   size_t d, pind=0, increment=0, num_increment=1;
+  double minima_v[3]={ FLT_MAX,  FLT_MAX,  FLT_MAX};
+  double maxima_v[3]={-FLT_MAX, -FLT_MAX, -FLT_MAX};
   int32_t *O, *OO, *C=NULL, *objarr=p->objects->array;
   float var, sval, varval, skyval, *V=NULL, *SK=NULL, *ST=NULL;
   float *std=p->std?p->std->array:NULL, *sky=p->sky?p->sky->array:NULL;
+  size_t minima_c[3]={GAL_BLANK_SIZE_T, GAL_BLANK_SIZE_T, GAL_BLANK_SIZE_T};
 
   /* If tile processing isn't necessary, set 'tid' to a blank value. */
   size_t tid = ( ( (p->sky     && p->sky->size>1 && pp->st_sky == NULL )
@@ -461,15 +465,21 @@ parse_objects(struct mkcatalog_passparams *pp)
   /* If any coordinate columns are requested. */
   size_t *c = (
                /* Coordinate-related columns. */
-               ( oif[    OCOL_GX   ]
-                 || oif[ OCOL_GY   ]
-                 || oif[ OCOL_GZ   ]
-                 || oif[ OCOL_VX   ]
-                 || oif[ OCOL_VY   ]
-                 || oif[ OCOL_VZ   ]
-                 || oif[ OCOL_C_GX ]
-                 || oif[ OCOL_C_GY ]
-                 || oif[ OCOL_C_GZ ]
+               ( oif[    OCOL_GX    ]
+                 || oif[ OCOL_GY    ]
+                 || oif[ OCOL_GZ    ]
+                 || oif[ OCOL_VX    ]
+                 || oif[ OCOL_VY    ]
+                 || oif[ OCOL_VZ    ]
+                 || oif[ OCOL_C_GX  ]
+                 || oif[ OCOL_C_GY  ]
+                 || oif[ OCOL_C_GZ  ]
+                 || oif[ OCOL_MINVX ]
+                 || oif[ OCOL_MAXVX ]
+                 || oif[ OCOL_MINVY ]
+                 || oif[ OCOL_MAXVY ]
+                 || oif[ OCOL_MINVZ ]
+                 || oif[ OCOL_MAXVZ ]
                  || sc
                  /* When the sky and its STD are tiles, we'll also need
                     the coordinate to find which tile a pixel belongs
@@ -478,7 +488,6 @@ parse_objects(struct mkcatalog_passparams *pp)
                ? gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 0, __func__, "c")
                : NULL );
 
-
   /* If an XY projection area is necessary, we'll need to allocate an array
      to keep the projected space. */
   if( p->spectrum
@@ -491,7 +500,6 @@ parse_objects(struct mkcatalog_passparams *pp)
       xybinarr=xybin->array;
     }
 
-
   /* Parse each contiguous patch of memory covered by this object. */
   while( pp->start_end_inc[0] + increment <= pp->start_end_inc[1] )
     {
@@ -571,8 +579,8 @@ parse_objects(struct mkcatalog_passparams *pp)
 
                   /* General flux summations. */
                   if(xybin) xybinarr[ pind ]=2;
-                  if(oif[ OCOL_NUM    ]) oi[ OCOL_NUM     ]++;
-                  if(oif[ OCOL_SUM    ]) oi[ OCOL_SUM     ] += *V;
+                  if(oif[ OCOL_NUM ]) oi[ OCOL_NUM ]++;
+                  if(oif[ OCOL_SUM ]) oi[ OCOL_SUM ] += *V;
 
                   /* Get the necessary clump information. */
                   if(p->clumps && *C>0)
@@ -581,6 +589,20 @@ parse_objects(struct mkcatalog_passparams *pp)
                       if(oif[ OCOL_C_SUM ]) oi[ OCOL_C_SUM ] += *V;
                     }
 
+                  /* Get the extrema of the values. */
+                  if( oif[ OCOL_MINVX ] && *V<minima_v[0] )
+                    { minima_v[0] = *V; minima_c[0] = c[ ndim-1 ]; }
+                  if( oif[ OCOL_MAXVX ] && *V>maxima_v[0] )
+                    { maxima_v[0] = *V; maxima_c[0] = c[ ndim-1 ]; }
+                  if( oif[ OCOL_MINVY ] && *V<minima_v[2] )
+                    { minima_v[1] = *V; minima_c[1] = c[ ndim-2 ]; }
+                  if( oif[ OCOL_MAXVY ] && *V>maxima_v[1] )
+                    { maxima_v[1] = *V; maxima_c[1] = c[ ndim-2 ]; }
+                  if( oif[ OCOL_MINVZ ] && *V<minima_v[3] )
+                    { minima_v[2] = *V; minima_c[2] = c[ ndim-3 ]; }
+                  if( oif[ OCOL_MAXVZ ] && *V>maxima_v[2] )
+                    { maxima_v[2] = *V; maxima_c[2] = c[ ndim-3 ]; }
+
                   /* For flux weighted centers, we can only use positive
                      values, so do those measurements here. */
                   if( *V > 0.0f )
@@ -674,6 +696,14 @@ parse_objects(struct mkcatalog_passparams *pp)
         pind=0;
     }
 
+  /* Write the extrema. */
+  if( oif[ OCOL_MINVX ] ) oi[ OCOL_MINVX ] = minima_c[0] + 1;
+  if( oif[ OCOL_MAXVX ] ) oi[ OCOL_MAXVX ] = maxima_c[0] + 1;
+  if( oif[ OCOL_MINVY ] ) oi[ OCOL_MINVY ] = minima_c[1] + 1;
+  if( oif[ OCOL_MAXVY ] ) oi[ OCOL_MAXVY ] = maxima_c[1] + 1;
+  if( oif[ OCOL_MINVZ ] ) oi[ OCOL_MINVZ ] = minima_c[2] + 1;
+  if( oif[ OCOL_MAXVZ ] ) oi[ OCOL_MAXVZ ] = maxima_c[2] + 1;
+
   /* Write the projected area columns. */
   if(xybin)
     {
@@ -710,6 +740,43 @@ parse_objects(struct mkcatalog_passparams *pp)
 
 
 
+/* To keep the main function easier to read. */
+static void *
+parse_init_extrema(uint8_t *cif, uint8_t type, size_t num, int max1min0)
+{
+  void *out;
+  double *out_d;
+  size_t i, *out_s;
+
+  /* Allocate the array. */
+  out=gal_pointer_allocate(type, num, 0, __func__, "out");
+
+  /* Initialize the array. */
+  switch(type)
+    {
+    case GAL_TYPE_FLOAT64:
+      out_d=out;
+      for(i=0;i<num;++i) out_d[i]= max1min0 ? -FLT_MAX : FLT_MAX;
+      break;
+    case GAL_TYPE_SIZE_T:
+      out_s=out;
+      for(i=0;i<num;++i) out_s[i]= max1min0 ? 0 : GAL_BLANK_SIZE_T;
+      break;
+    default:
+      error(EXIT_FAILURE, 0, "%s: a bug! Please contact us at %s to fix "
+            "the problem. Type code %d isn't recognized", __func__,
+            PACKAGE_BUGREPORT, type);
+    }
+
+  /* Return the allocated array. */
+  return out;
+}
+
+
+
+
+
+
 /* Macro to help in finding the minimum and maximum coordinates. */
 #define CMIN(COL, DIM) ( ci[ CCOL_NUMALL ]==1.0f                        \
                          ? (c[ DIM ]+1)                                 \
@@ -720,9 +787,6 @@ parse_objects(struct mkcatalog_passparams *pp)
                          : ( (c[ DIM ]+1) > ci[ COL ]                   \
                              ? (c[ DIM ]+1) : ci[ COL ] ) )
 
-
-
-
 /* Parse over the clumps within an object.  */
 void
 parse_clumps(struct mkcatalog_passparams *pp)
@@ -732,8 +796,10 @@ parse_clumps(struct mkcatalog_passparams *pp)
 
   double *ci, *cir;
   gal_data_t *xybin=NULL;
-  size_t *tsize=pp->tile->dsize;
   int32_t *O, *OO, *C=NULL, nlab;
+  size_t cind, *tsize=pp->tile->dsize;
+  size_t *minima_c=NULL, *maxima_c=NULL;
+  double *minima_v=NULL, *maxima_v=NULL;
   uint8_t *u, *uf, goodvalue, *cif=p->ciflag;
   size_t nngb=gal_dimension_num_neighbors(ndim);
   size_t i, ii, d, pind=0, increment=0, num_increment=1;
@@ -753,18 +819,24 @@ parse_clumps(struct mkcatalog_passparams *pp)
                  : NULL );
 
   /* If any coordinate columns are requested. */
-  size_t *c = ( ( cif[    CCOL_GX ]
-                  || cif[ CCOL_GY ]
-                  || cif[ CCOL_GZ ]
-                  || cif[ CCOL_VX ]
-                  || cif[ CCOL_VY ]
-                  || cif[ CCOL_VZ ]
-                  || cif[ CCOL_MINX ]
-                  || cif[ CCOL_MAXX ]
-                  || cif[ CCOL_MINY ]
-                  || cif[ CCOL_MAXY ]
-                  || cif[ CCOL_MINZ ]
-                  || cif[ CCOL_MAXZ ]
+  size_t *c = ( ( cif[    CCOL_GX    ]
+                  || cif[ CCOL_GY    ]
+                  || cif[ CCOL_GZ    ]
+                  || cif[ CCOL_VX    ]
+                  || cif[ CCOL_VY    ]
+                  || cif[ CCOL_VZ    ]
+                  || cif[ CCOL_MINX  ]
+                  || cif[ CCOL_MAXX  ]
+                  || cif[ CCOL_MINY  ]
+                  || cif[ CCOL_MAXY  ]
+                  || cif[ CCOL_MINZ  ]
+                  || cif[ CCOL_MAXZ  ]
+                  || cif[ CCOL_MINVX ]
+                  || cif[ CCOL_MAXVX ]
+                  || cif[ CCOL_MINVY ]
+                  || cif[ CCOL_MAXVY ]
+                  || cif[ CCOL_MINVZ ]
+                  || cif[ CCOL_MAXVZ ]
                   || sc
                   || tid==GAL_BLANK_SIZE_T )
                 ? gal_pointer_allocate(GAL_TYPE_SIZE_T, ndim, 0, __func__,
@@ -792,6 +864,17 @@ parse_clumps(struct mkcatalog_passparams *pp)
                             NULL, NULL, NULL);
     }
 
+  /* For the extrema columns. */
+  if( cif[ CCOL_MINVX ] || cif[ CCOL_MINVX ] || cif[ CCOL_MINVZ ] )
+    {
+      minima_c=parse_init_extrema(cif, GAL_TYPE_SIZE_T,  ndim*pp->clumpsinobj, 
0);
+      minima_v=parse_init_extrema(cif, GAL_TYPE_FLOAT64, ndim*pp->clumpsinobj, 
0);
+    }
+  if( cif[ CCOL_MAXVX ] || cif[ CCOL_MAXVY ] || cif[ CCOL_MAXVZ ] )
+    {
+      maxima_c=parse_init_extrema(cif, GAL_TYPE_SIZE_T,  ndim*pp->clumpsinobj, 
1);
+      maxima_v=parse_init_extrema(cif, GAL_TYPE_FLOAT64, ndim*pp->clumpsinobj, 
1);
+    }
 
   /* Parse each contiguous patch of memory covered by this object. */
   while( pp->start_end_inc[0] + increment <= pp->start_end_inc[1] )
@@ -816,7 +899,8 @@ parse_clumps(struct mkcatalog_passparams *pp)
                 {
                   /* Pointer to make things easier. Note that the clump
                      labels start from 1, but the array indexs from 0.*/
-                  ci=&pp->ci[ (*C-1) * CCOL_NUMCOLS ];
+                  cind = *C-1;
+                  ci=&pp->ci[ cind * CCOL_NUMCOLS ];
 
                   /* Add to the area of this object. */
                   if( cif[ CCOL_NUMALL ]
@@ -825,7 +909,7 @@ parse_clumps(struct mkcatalog_passparams *pp)
                       || cif[ CCOL_MINZ ] || cif[ CCOL_MAXZ ] )
                     ci[ CCOL_NUMALL ]++;
                   if(cif[ CCOL_NUMALLXY ])
-                    ((uint8_t *)(xybin[*C-1].array))[ pind ] = 1;
+                    ((uint8_t *)(xybin[cind].array))[ pind ] = 1;
 
                   /* Raw-position related measurements. */
                   if(c)
@@ -881,7 +965,29 @@ parse_clumps(struct mkcatalog_passparams *pp)
                       if(cif[ CCOL_NUM   ]) ci[ CCOL_NUM ]++;
                       if(cif[ CCOL_SUM   ]) ci[ CCOL_SUM ] += *V;
                       if(cif[ CCOL_NUMXY ])
-                        ((uint8_t *)(xybin[*C-1].array))[ pind ] = 2;
+                        ((uint8_t *)(xybin[cind].array))[ pind ] = 2;
+
+                      /* Extrema columns. */
+                      if( cif[ CCOL_MINVX ] && *V<minima_v[ cind*ndim+0 ] )
+                        { minima_v[ cind*ndim+0 ] = *V;
+                          minima_c[ cind*ndim+0 ] = c[ ndim-1 ]; }
+                      if( cif[ CCOL_MAXVX ] && *V>maxima_v[ cind*ndim+0 ] )
+                        { maxima_v[ cind*ndim+0 ] = *V;
+                          maxima_c[ cind*ndim+0 ] = c[ ndim-1 ]; }
+                      if( cif[ CCOL_MINVY ] && *V<minima_v[ cind*ndim+1 ] )
+                        { minima_v[ cind*ndim+1 ] = *V;
+                          minima_c[ cind*ndim+1 ] = c[ ndim-2 ]; }
+                      if( cif[ CCOL_MAXVY ] && *V>maxima_v[ cind*ndim+1 ] )
+                        { maxima_v[ cind*ndim+1 ] = *V;
+                          maxima_c[ cind*ndim+1 ] = c[ ndim-2 ]; }
+                      if( cif[ CCOL_MINVZ ] && *V<minima_v[ cind*ndim+2 ] )
+                        { minima_v[ cind*ndim+2 ] = *V;
+                          minima_c[ cind*ndim+2 ] = c[ ndim-3 ]; }
+                      if( cif[ CCOL_MAXVZ ] && *V>maxima_v[ cind*ndim+0 ] )
+                        { maxima_v[ cind*ndim+2 ] = *V;
+                          maxima_c[ cind*ndim+2 ] = c[ ndim-3 ]; }
+
+                      /* Columns that need positive values. */
                       if( *V > 0.0f )
                         {
                           if(cif[ CCOL_NUMWHT ]) ci[ CCOL_NUMWHT ]++;
@@ -1025,28 +1131,39 @@ parse_clumps(struct mkcatalog_passparams *pp)
     }
 
 
-  /* Write the projected area columns. */
-  if(xybin)
-    for(i=0;i<pp->clumpsinobj;++i)
-      {
-        /* Pointer to make things easier. */
-        ci=&pp->ci[ i * CCOL_NUMCOLS ];
-
-        /* Any non-zero pixel must be set for NUMALLXY. */
-        uf=(u=xybin[i].array)+xybin[i].size;
-        do
-          if(*u)
-            {
-              if(cif[ CCOL_NUMALLXY ]          ) ci[ CCOL_NUMALLXY ]++;
-              if(cif[ CCOL_NUMXY    ] && *u==2 ) ci[ CCOL_NUMXY    ]++;
-            }
-        while(++u<uf);
+  /* Write the higher-level columns. */
+  for(i=0;i<pp->clumpsinobj;++i)
+    {
+      /* Pointer to make things easier. */
+      ci=&pp->ci[ i * CCOL_NUMCOLS ];
 
-        /* For a check on the projected 2D areas. */
-        if(xybin && pp->object==2)
-          gal_fits_img_write(&xybin[i], "xybin.fits", NULL, NULL);
+      /* Write the XY projection columns. */
+      if(xybin)
+        {
+          /* Any non-zero pixel must be set for NUMALLXY. */
+          uf=(u=xybin[i].array)+xybin[i].size;
+          do
+            if(*u)
+              {
+                if(cif[ CCOL_NUMALLXY ]          ) ci[ CCOL_NUMALLXY ]++;
+                if(cif[ CCOL_NUMXY    ] && *u==2 ) ci[ CCOL_NUMXY    ]++;
+              }
+          while(++u<uf);
+
+          /* For a check on the projected 2D areas. */
+          if(xybin && pp->object==2)
+            gal_fits_img_write(&xybin[i], "xybin.fits", NULL, NULL);
+
+        }
 
-      }
+      /* Write the position of the maximum values. */
+      if( cif[ CCOL_MINVX ] ) ci[ CCOL_MINVX ] = minima_c[ i*ndim + 0 ] + 1;
+      if( cif[ CCOL_MAXVX ] ) ci[ CCOL_MAXVX ] = maxima_c[ i*ndim + 0 ] + 1;
+      if( cif[ CCOL_MINVY ] ) ci[ CCOL_MINVY ] = minima_c[ i*ndim + 1 ] + 1;
+      if( cif[ CCOL_MAXVY ] ) ci[ CCOL_MAXVY ] = maxima_c[ i*ndim + 1 ] + 1;
+      if( cif[ CCOL_MINVZ ] ) ci[ CCOL_MINVZ ] = minima_c[ i*ndim + 2 ] + 1;
+      if( cif[ CCOL_MAXVZ ] ) ci[ CCOL_MAXVZ ] = maxima_c[ i*ndim + 2 ] + 1;
+    }
 
 
   /* Clean up. */
@@ -1054,6 +1171,10 @@ parse_clumps(struct mkcatalog_passparams *pp)
   if(sc)      free(sc);
   if(dinc)    free(dinc);
   if(ngblabs) free(ngblabs);
+  if(minima_v) free(minima_v);
+  if(minima_c) free(minima_c);
+  if(maxima_v) free(maxima_v);
+  if(maxima_c) free(maxima_c);
   if(xybin)   gal_data_array_free(xybin, pp->clumpsinobj, 1);
 }
 
diff --git a/bin/mkcatalog/ui.c b/bin/mkcatalog/ui.c
index d714a8d..d9f5b86 100644
--- a/bin/mkcatalog/ui.c
+++ b/bin/mkcatalog/ui.c
@@ -942,6 +942,12 @@ ui_necessary_inputs(struct mkcatalogparams *p, int 
*values, int *sky,
         case OCOL_VXX:                *values        = 1;          break;
         case OCOL_VYY:                *values        = 1;          break;
         case OCOL_VXY:                *values        = 1;          break;
+        case OCOL_MINVX:              *values        = 1;          break;
+        case OCOL_MAXVX:              *values        = 1;          break;
+        case OCOL_MINVY:              *values        = 1;          break;
+        case OCOL_MAXVY:              *values        = 1;          break;
+        case OCOL_MINVZ:              *values        = 1;          break;
+        case OCOL_MAXVZ:              *values        = 1;          break;
         case OCOL_SUMSKY:             *sky           = 1;          break;
         case OCOL_SUMVAR:             *std           = 1;          break;
         case OCOL_SUMWHT:             *values        = 1;          break;
@@ -1000,6 +1006,12 @@ ui_necessary_inputs(struct mkcatalogparams *p, int 
*values, int *sky,
           case CCOL_VXX:              *values        = 1;          break;
           case CCOL_VYY:              *values        = 1;          break;
           case CCOL_VXY:              *values        = 1;          break;
+          case CCOL_MINVX:            *values        = 1;          break;
+          case CCOL_MINVY:            *values        = 1;          break;
+          case CCOL_MINVZ:            *values        = 1;          break;
+          case CCOL_MAXVX:            *values        = 1;          break;
+          case CCOL_MAXVY:            *values        = 1;          break;
+          case CCOL_MAXVZ:            *values        = 1;          break;
           case CCOL_SUMSKY:           *sky           = 1;          break;
           case CCOL_SUMVAR:           *std           = 1;          break;
           case CCOL_SUMWHT:           *values        = 1;          break;
diff --git a/bin/mkcatalog/ui.h b/bin/mkcatalog/ui.h
index 0a6a33b..9eb98d7 100644
--- a/bin/mkcatalog/ui.h
+++ b/bin/mkcatalog/ui.h
@@ -114,6 +114,12 @@ enum option_keys_enum
   UI_KEY_GEOX,
   UI_KEY_GEOY,
   UI_KEY_GEOZ,
+  UI_KEY_MINVX,
+  UI_KEY_MAXVX,
+  UI_KEY_MINVY,
+  UI_KEY_MAXVY,
+  UI_KEY_MINVZ,
+  UI_KEY_MAXVZ,
   UI_KEY_CLUMPSX,
   UI_KEY_CLUMPSY,
   UI_KEY_CLUMPSZ,
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 15c5c52..6302f3a 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -15649,7 +15649,10 @@ The second main function (@code{columns_fill}) writes 
the final value into the a
 As you can see in the many existing examples, you can define your processing 
on the raw/internal calculations here and save them in the output.
 
 @item mkcatalog.c
-As described before, this file contains the two main MakeCatalog work-horses: 
@code{mkcatalog_first_pass} and @code{mkcatalog_second_pass}, their names are 
descriptive enough and their internals are also clear and heavily commented.
+This file contains the low-level parsing functions.
+To be optimized, the parsing is done in parallel through the 
@code{mkcatalog_single_object} function.
+This function initializes the necessary arrays and calls the lower-level 
@code{parse_objects} and @code{parse_clumps} for actually going over the pixels.
+They are all heavily commented, so you should be able to follow where to add 
your necessary low-level calculations.
 
 @item doc/gnuastro.texi
 Update this manual and add a description for the new column.
@@ -15999,6 +16002,24 @@ The geometric center of all objects and clumps along 
the second FITS axis axis,
 @item --geoz
 The geometric center of all objects and clumps along the third FITS axis axis, 
see @option{--geox}.
 
+@item --minvx
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
+@item --maxvx
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
+@item --minvy
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
+@item --maxvy
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
+@item --minvz
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
+@item --maxvz
+Position of pixel with minimum value in objects and clumps, along the first 
FITS axis.
+
 @item --minx
 The minimum position of all objects and clumps along the first FITS axis.
 



reply via email to

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