[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[gnuastro-commits] master 06dac74 1/2: New Arithmetic operator: invert
From: |
Mohammad Akhlaghi |
Subject: |
[gnuastro-commits] master 06dac74 1/2: New Arithmetic operator: invert |
Date: |
Tue, 10 Apr 2018 20:07:01 -0400 (EDT) |
branch: master
commit 06dac74aa221649d4949a35eca7cd1aab47adf7d
Author: Mohammad Akhlaghi <address@hidden>
Commit: Mohammad Akhlaghi <address@hidden>
New Arithmetic operator: invert
A new operator was added to arithmetic to easily invert (subtract the
maximum value of the type from each pixel) a given unsigned integer
dataset.
---
NEWS | 10 ++++++---
bin/arithmetic/arithmetic.c | 49 ++++++++++++++++++++++++++++++++++++++++++++-
bin/arithmetic/arithmetic.h | 1 +
doc/gnuastro.texi | 13 ++++++++++++
4 files changed, 69 insertions(+), 4 deletions(-)
diff --git a/NEWS b/NEWS
index 4dae408..e5b7772 100644
--- a/NEWS
+++ b/NEWS
@@ -6,16 +6,20 @@ GNU Astronomy Utilities NEWS -*-
outline -*-
** New features
All programs:
- - Input datasets can now be given in any of the formats recognized by
- Gnuastro (and with libraries available on the system).
+ - Input image dataset(s) can be in any of the formats recognized by
+ Gnuastro (e.g., FITS, TIFF, JPEG), provided that their libraries
+ (optional dependencies) were present at installation time.
New program:
- - Segment: new program in charge of segmentation over detections.
+ - Segment: new program in charge of segmentation over detections. This
+ operation was previously done by NoiseChisel. NoiseChisel is now ONLY
+ in charge of detection.
Arithmetic:
- connected-components: label the connected elements of the input.
- filter-sigclip-mean: sigma-clipped, mean filter operator.
- filter-sigclip-median: sigma-clipped, median filter operator.
+ - invert: subtract the maximum of unsigned types (absorption to emission).
ConvertType:
- TIFF images can also be used as input.
diff --git a/bin/arithmetic/arithmetic.c b/bin/arithmetic/arithmetic.c
index c8b25af..baef282 100644
--- a/bin/arithmetic/arithmetic.c
+++ b/bin/arithmetic/arithmetic.c
@@ -539,11 +539,19 @@ arithmetic_connected_components(struct arithmeticparams
*p, char *token)
conn=gal_data_copy_to_new_type_free(conn, GAL_TYPE_INT32);
conn_int = *((int32_t *)(conn->array));
if(conn_int>in->ndim)
- error(EXIT_FAILURE, 0, "the first0popped operand to "
+ error(EXIT_FAILURE, 0, "the first popped operand of "
"`connected-components' (%d) is larger than the number of "
"dimensions in the second-popped operand (%zu)", conn_int,
in->ndim);
+ /* Make sure the array has an unsigned 8-bit type. */
+ if(in->type!=GAL_TYPE_UINT8)
+ error(EXIT_FAILURE, 0, "the second popped operand of "
+ "`connected-components' doesn't have an 8-bit unsigned "
+ "integer type. It must be a binary dataset (only being equal "
+ "to zero is checked). You can use the `uint8' operator to "
+ "convert the type of this operand.");
+
/* Do the connected components labeling. */
gal_binary_connected_components(in, &out, 1);
@@ -559,6 +567,39 @@ arithmetic_connected_components(struct arithmeticparams
*p, char *token)
+static void
+arithmetic_invert(struct arithmeticparams *p, char *token)
+{
+ gal_data_t *in = operands_pop(p, token);
+
+ uint8_t *u8 = in->array, *u8f = u8 + in->size;
+ uint8_t *u16 = in->array, *u16f = u16 + in->size;
+ uint8_t *u32 = in->array, *u32f = u32 + in->size;
+ uint8_t *u64 = in->array, *u64f = u64 + in->size;
+
+ /* Do the inversion based on type. */
+ switch(in->type)
+ {
+ case GAL_TYPE_UINT8: do *u8 = UINT8_MAX-*u8; while(++u8<u8f); break;
+ case GAL_TYPE_UINT16: do *u16 = UINT16_MAX-*u16; while(++u16<u16f); break;
+ case GAL_TYPE_UINT32: do *u32 = UINT32_MAX-*u32; while(++u32<u32f); break;
+ case GAL_TYPE_UINT64: do *u64 = UINT64_MAX-*u64; while(++u64<u64f); break;
+ default:
+ error(EXIT_FAILURE, 0, "`invert' operand has %s type. `invert' can "
+ "only take unsigned integer types.\n\nYou can use any of the "
+ "`uint8', `uint16', `uint32', or `uint64' operators to chage "
+ "the type before calling `invert'",
+ gal_type_name(in->type, 1));
+ }
+
+ /* Push the result onto the stack. */
+ operands_add(p, NULL, in);
+}
+
+
+
+
+
@@ -739,6 +780,8 @@ reversepolish(struct arithmeticparams *p)
{ op=ARITHMETIC_OP_FILTER_SIGCLIP_MEDIAN; nop=0; }
else if (!strcmp(token->v, "connected-components"))
{ op=ARITHMETIC_OP_CONNECTED_COMPONENTS; nop=0; }
+ else if (!strcmp(token->v, "invert"))
+ { op=ARITHMETIC_OP_INVERT; nop=0; }
/* Finished checks with known operators */
@@ -817,6 +860,10 @@ reversepolish(struct arithmeticparams *p)
arithmetic_connected_components(p, token->v);
break;
+ case ARITHMETIC_OP_INVERT:
+ arithmetic_invert(p, token->v);
+ break;
+
default:
error(EXIT_FAILURE, 0, "%s: a bug! please contact us at "
"%s to fix the problem. The code %d is not "
diff --git a/bin/arithmetic/arithmetic.h b/bin/arithmetic/arithmetic.h
index da37fa1..59b2170 100644
--- a/bin/arithmetic/arithmetic.h
+++ b/bin/arithmetic/arithmetic.h
@@ -36,6 +36,7 @@ enum arithmetic_prog_operators
ARITHMETIC_OP_FILTER_SIGCLIP_MEAN,
ARITHMETIC_OP_FILTER_SIGCLIP_MEDIAN,
ARITHMETIC_OP_CONNECTED_COMPONENTS,
+ ARITHMETIC_OP_INVERT,
};
diff --git a/doc/gnuastro.texi b/doc/gnuastro.texi
index 848625a..55036c7 100644
--- a/doc/gnuastro.texi
+++ b/doc/gnuastro.texi
@@ -10120,6 +10120,19 @@ If your input dataset doesn't have a binary type, but
you know all its
values are 0 or 1, you can use the @code{uint8} operator (below) to convert
it to binary.
address@hidden invert
+Invert an unsigned integer dataset. This is the only operator that ignores
+blank values (which are set to be the maximum values in the unsigned
+integer types).
+
+This is useful in cases where the target(s) has(have) been imaged in
+absorption as raw formats (which are unsigned integer types). With this
+option, the maximum value for the given type will be subtracted from each
+pixel value, thus ``inverting'' the image, so the target(s) can be treated
+as emission. This can be useful when the higher-level analysis
+methods/tools only work on emission (positive skew in the noise, not
+negative).
+
@item lt
Less than: If the second popped (or left operand in infix notation, see
@ref{Reverse polish notation}) value is smaller than the first popped