[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.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [gnuastro-commits] master 2e1deec: MakeCatalog: return position of pixel with minimum/maximum value,
Mohammad Akhlaghi <=