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 don’t 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 don’t 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 if 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).
Blank value for an unsigned, 8-bit integer.
Blank value for a signed, 8-bit integer.
Blank value for an unsigned, 16-bit integer.
Blank value for a signed, 16-bit integer.
Blank value for an unsigned, 32-bit integer.
Blank value for a signed, 32-bit integer.
Blank value for an unsigned, 64-bit integer.
Blank value for a signed, 64-bit integer.
Blank value for
size_t type (
32-bit or 64-bit systems).
Blank value for a single precision, 32-bit floating point type (IEEE NaN value).
Blank value for a double precision, 64-bit floating point type (IEEE NaN value).
Blank value for string types (this is itself a string, it isn’t the
The functions below can be used to work with blank pixels.
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
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.
Initialize all the elements in the
input dataset to the blank value
that corresponds to its type. If
input is a tile over a larger
dataset, only the region that the tile covers will be set to blank.
Return 1 if the contents of
pointer (assuming a type of
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
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_flag respectively (described
Return 1 if the dataset has a blank value and zero if it doesn’t. Before
checking the dataset, this function will look at
input’s flags. If
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->flags=0), otherwise you can use this expression:
input->flags &= ~GAL_DATA_FLAG_BLANK_CH;
Create a dataset of the the same size as the input, but with an
uint8_t type that has a value of 1 for data that are blank and 0 for
those that aren’t.
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 doesn’t
realloc the input array, it just shifts the blank elements to the
end and adjusts the size elements of the
Generic data container (
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.
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.