GNU Astronomy Utilities



12.3.5 Library blank values (blank.h)

When the position of an element in a dataset is important (for example, a pixel in an image), a place-holder is necessary for the element if we do not have a value to fill it with (for example, the CCD cannot read those pixels). We cannot simply shift all the other pixels to fill in the one we have no value for. In other cases, it often occurs that the field of sky that you are studying is not a clean rectangle to nicely fit into the boundaries of an image. You need a way to separate the pixels outside your scientific field from those inside it. Blank values act as these place holders in a dataset. They have no usable value but they have a position.

Every type needs a corresponding blank value (see Numeric data types and Library data types (type.h)). Floating point types have a unique value identified by IEEE known as Not-a-Number (or NaN) which is a unique value that is recognized by the compiler. However, integer and string types do not have any standard value. For integers, in Gnuastro we take an extremum of the given type: for signed types (that allow negatives), the minimum possible value is used as blank and for unsigned types (that only accept positives), the maximum possible value is used. To be generic and easy to read/write we define a macro for these blank values and strongly encourage you only use these, and never make any assumption on the value of a type’s blank value.

The IEEE NaN blank value type is defined to fail on any comparison, so if you are dealing with floating point types, you cannot use equality (a NaN will not be equal to a NaN). If you know your dataset is floating point, you can use the isnan function in C’s math.h header. For a description of numeric data types see Numeric data types. For the constants identifying integers, please see Library data types (type.h).

Global integer: GAL_BLANK_UINT8

Blank value for an unsigned, 8-bit integer.

Global integer: GAL_BLANK_INT8

Blank value for a signed, 8-bit integer.

Global integer: GAL_BLANK_UINT16

Blank value for an unsigned, 16-bit integer.

Global integer: GAL_BLANK_INT16

Blank value for a signed, 16-bit integer.

Global integer: GAL_BLANK_UINT32

Blank value for an unsigned, 32-bit integer.

Global integer: GAL_BLANK_INT32

Blank value for a signed, 32-bit integer.

Global integer: GAL_BLANK_UINT64

Blank value for an unsigned, 64-bit integer.

Global integer: GAL_BLANK_INT64

Blank value for a signed, 64-bit integer.

Global integer: GAL_BLANK_INT

Blank value for int type (int16_t or int32_t depending on the system.

Global integer: GAL_BLANK_UINT

Blank value for int type (int16_t or int32_t depending on the system.

Global integer: GAL_BLANK_LONG

Blank value for long type (int32_t or int64_t in 32-bit or 64-bit systems).

Global integer: GAL_BLANK_ULONG

Blank value for unsigned long type (uint32_t or uint64_t in 32-bit or 64-bit systems).

Global integer: GAL_BLANK_SIZE_T

Blank value for size_t type (uint32_t or uint64_t in 32-bit or 64-bit systems).

Global integer: GAL_BLANK_FLOAT32

Blank value for a single precision, 32-bit floating point type (IEEE NaN value).

Global integer: GAL_BLANK_FLOAT64

Blank value for a double precision, 64-bit floating point type (IEEE NaN value).

Global integer: GAL_BLANK_STRING

Blank value for string types (this is itself a string, it is not the NULL pointer).

The functions below can be used to work with blank pixels.

Function:
void
gal_blank_write (void *pointer, uint8_t type)

Write the blank value for the given type into the space that pointer points to. This can be used when the space is already allocated (for example, one element in an array or a statically allocated variable).

Function:
void *
gal_blank_alloc_write (uint8_t type)

Allocate the space required to keep the blank for the given data type type, write the blank value into it and return the pointer to it.

Function:
void
gal_blank_initialize (gal_data_t *input)

Initialize all the elements in the input dataset to the blank value that corresponds to its type. If input is not a string, and is a tile over a larger dataset, only the region that the tile covers will be set to blank. For strings, the full dataset will be initialized.

Function:
void
gal_blank_initialize_array (void *array, size_t size, uint8_t type)

Initialize all the elements in the array to the blank value that corresponds to its type (identified with type), assuming the array has size elements.

Function:
char *
gal_blank_as_string (uint8_t type, int width)

Write the blank value for the given data type type into a string and return it. The space for the string is dynamically allocated so it must be freed after you are done with it. If width!=0, then the final string will be padded with white space characters to have the requested width if it is smaller.

Function:
int
gal_blank_is (void *pointer, uint8_t type)

Return 1 if the contents of pointer (assuming a type of type) is blank. Otherwise, return 0. Note that this function only works on one element of the given type. So if pointer is an array, only its first element will be checked. Therefore for strings, the type of pointer is assumed to be char *. To check if an array/dataset has blank elements or to find which elements in an array are blank, you can use gal_blank_present or gal_blank_flag respectively (described below).

Function:
int
gal_blank_present (gal_data_t *input, int updateflag)

Return 1 if the dataset has a blank value and zero if it does not. Before checking the dataset, this function will look at input’s flags. If the GAL_DATA_FLAG_BLANK_CH bit of input->flag is on, this function will not do any check and will just use the information in the flags. This can greatly speed up processing when a dataset needs to be checked multiple times.

When the dataset’s flags were not used and updateflags is non-zero, this function will set the flags appropriately to avoid having to re-check the dataset in future calls. When updateflags==0, this function has no side-effects on the dataset: it will not toggle the flags.

If you want to re-check a dataset with the blank-value-check flag already set (for example, if you have made changes to it), then explicitly set the GAL_DATA_FLAG_BLANK_CH bit to zero before calling this function. When there are no other flags, you can just set the flags to zero (input->flag=0), otherwise you can use this expression:

input->flag &= ~GAL_DATA_FLAG_BLANK_CH;
Function:
size_t
gal_blank_number (gal_data_t *input, int updateflag)

Return the number of blank elements in input. If updateflag!=0, then the dataset blank keyword flags will be updated. See the description of gal_blank_present (above) for more on these flags. If input==NULL, then this function will return GAL_BLANK_SIZE_T.

Function:
gal_data_t *
gal_blank_flag (gal_data_t *input)

Return a “flag” dataset with the same size as the input, but with an uint8_t type that has a value of 1 for data elements that are blank and 0 for those that are not.

Function:
gal_data_t *
gal_blank_flag_not (gal_data_t *input)

Return a “flag” dataset with the same size as the input, but with an uint8_t type that has a value of 1 for data elements that are not blank and 0 for those that are blank.

Function:
size_t *
gal_blank_not_minmax_coords (gal_data_t *input)

Find the minimum and maximum coordinates of the non-blank regions within the input dataset. The coordinates are in C order: starting from 0, and with the slowest dimension being first. The output is an allocated array (that should be freed later) with \(2\times N\) elements; where \(N\) is the number of dimensions. The first two elements contain the minimum and maximum of regions containing non-blank elements along the 0-th dimension (the slowest), the second two elements contain the next dimension’s extrema; and so on.

Function:
gal_data_t *
gal_blank_trim (gal_data_t *input, int inplace)

Trim all the outer layers of blank values from the input dataset. For example in the 2D image, “layers” would correspond to columns or rows that are fully blank and touching the edge of the image. For a more complete description, see the description of the trim operator in Dimensionality changing operators.

Function:
void
gal_blank_flag_apply (gal_data_t *input, gal_data_t *flag)

Set all non-zero and non-blank elements of flag to blank in input. flag has to have an unsigned 8-bit type and be the same size as input.

Function:
void
gal_blank_flag_remove (gal_data_t *input, gal_data_t *flag)

Remove all elements within input that are flagged, convert it to a 1D dataset and adjust the size properly (the number of non-flagged elements). In practice this function does notrealloc the input array (see gal_blank_remove_realloc for shrinking/re-allocating also), it just shifts the blank elements to the end and adjusts the size elements of the gal_data_t, see Generic data container (gal_data_t).

Note that elements that are blank, but not flagged will not be removed. This function will only remove flagged elements.

If all the elements were flagged, then input->size will be zero. This is thus a good parameter to check after calling this function to see if there actually were any non-flagged elements in the input or not and take the appropriate measure. This check is highly recommended because it will avoid strange bugs in later steps.

Function:
void
gal_blank_remove (gal_data_t *input)

Remove blank elements from a dataset, convert it to a 1D dataset, adjust the size properly (the number of non-blank elements), and toggle the blank-value-related bit-flags. In practice this function does notrealloc the input array (see gal_blank_remove_realloc for shrinking/re-allocating also), it just shifts the blank elements to the end and adjusts the size elements of the gal_data_t, see Generic data container (gal_data_t).

If all the elements were blank, then input->size will be zero. This is thus a good parameter to check after calling this function to see if there actually were any non-blank elements in the input or not and take the appropriate measure. This check is highly recommended because it will avoid strange bugs in later steps.

Function:
void
gal_blank_remove_realloc (gal_data_t *input)

Similar to gal_blank_remove, but also shrinks/re-allocates the dataset’s allocated memory.

Function:
gal_data_t *
gal_blank_remove_rows (gal_data_t *columns, gal_list_sizet_t *column_indexs, int onlydim0)

Remove (in place) any row that has at least one blank value in any of the input columns and return a “flag” dataset (that should be freed later). The input columns is a list of gal_data_ts (see List of gal_data_t). When onlydim0!=0 the vector columns (with 2 dimensions) will not be checked for the presence of blank values.

After this function, all the elements in columns will still have the same size as each other, but if any of the searched columns has blank elements, all their sizes will decrease together.

The returned flag dataset has the same size as the original input dataset, with a type of uint8_t. Every row that has been removed from the original dataset has a value of 1, and the rest have a value of 0.

When column_indexs!=NULL, only the columns whose index (counting from zero) is in column_indexs will be used to check for blank values (see List of size_t. Therefore, if you want to check all columns, just set this to NULL. In any case (no matter which columns are checked for blanks), the selected rows from all columns will be removed.