Basic math operations on WolfArray

The following math operations are supported on WolfArray objects:

  • addition (+)

  • subtraction (-)

  • multiplication (*)

  • division (/)

  • exponentiation (**)

The results of these operations are also WolfArray objects. The operations are performed element-wise, and the dimensions of the arrays must be compatible for the operation to succeed.

If you want to multiply a WolfArray by a scalar, you can use the * operator but the scaler must be the second operand. For example, wolf_array * 2 will work, but 2 * wolf_array will not. This is because the * operator is overloaded to perform element-wise multiplication when the first operand is a WolfArray.

[ ]:
import _add_path # This is a hack to add the parent directory to the path - debug only
from wolfhece.wolf_array import WolfArray, header_wolf
import numpy as np

Examples of math operations

[2]:
h = header_wolf()
h.shape = (10,10)
h.set_resolution(1.,1.)

a = WolfArray(srcheader= h)

a.array[:,:] = 10.0

b = a * 200.0 # This should be a copy of a, but with all values multiplied by 200.0
print(b.array[0,0]) # Should be 2000.0
2000.0
[4]:
c = a+b

print(c.array[0,0]) # Should be 2010.0
2010.0
[ ]:
u = WolfArray(srcheader= h)
h = WolfArray(srcheader= h)

u.array[:,:] = 1.0
h.array[:,:] = 2.0

Froude = u / (h * 9.81)**0.5 # Evaluation of the Froude number

print(Froude.array[0,0]) # Should be 1 / (2 * 9.81)**0.5 = 0.225761820...
0.2257618

Working with Masked Arrays

WolfArray objects are Numpy masked arrays, so the same rules and behaviors apply. Operations on WolfArray will automatically ignore the masked values and only process the unmasked values.

Key Points to Remember:

  • Masked values are excluded from calculations, ensuring that invalid or missing data does not affect the results.

  • Masks with different structures or distributions can lead to unexpected results, so always verify the mask alignment before performing operations.

  • Refer to the Numpy Masked Arrays Documentation for detailed information on their behavior and usage.

Best Practices:

  • Always check the mask status of your arrays before performing operations.

  • Be cautious when combining arrays with different masks, as this can lead to unintended outcomes.

  • Use debugging tools to inspect the data and mask status of your WolfArray objects to ensure correctness.

[37]:
a = WolfArray(srcheader= h)
a.array[:,:] = np.arange(0,100).reshape((10,10))
a.array[0,0] = -1.

b = WolfArray(srcheader= h)
b.array[:,:] = np.arange(100,200).reshape((10,10))

a.mask_greater(50.0) # Mask all values greater than 50.0
b.mask_lower(110.0)  # Mask all values lower than 110.0

print(a.nbnotnull) # Should be 51 (0 to 50 inclusive)
print(b.nbnotnull) # Should be 90 (110 to 200 inclusive)

c = a+b

print(a.array.mask[0,0]) # Should be False (not masked value)
print(b.array.mask[0,0]) # Should be True (masked value)
print(c.array.data[0,0]) # Should be 0.0 (masked value)

print(c.nbnotnull) # Should be 41 (51 - 10 values masked in b)
51
90
False
True
-1.0
41

Is a masked value equivalent to NoData/NullValue ?

No, a masked value is not equivalent to NoData or NullValue.

A masked value is simply a value that has been marked as invalid or missing, while NoData or NullValue are specific values that indicate the absence of data.

In WolfArray, masked values are used to indicate that a value should be ignored in calculations/plotting operation.

If you want to impose a Nodata value on masked cells, you can use the set_nullvalue_in_mask method. This will set the Nodata value for the WolfArray object, and any masked values will be replaced with the specified Nodata value.

[38]:
print('Data associated to a masked cell : ', a.array.data[0,0])
print('Maks status of a the cell : ', a.array.mask[0,0]) # Should be True (masked value)

print('Data associated to a masked cell : ', b.array.data[0,0])
print('Maks status of a the cell : ', b.array.mask[0,0]) # Should be True (masked value)

print('Data associated to a masked cell : ', c.array.data[0,0])
print('Maks status of a the cell : ', c.array.mask[0,0]) # Should be True (masked value) but its data is -1.0 (from a) -- operation not done as b[0,0] is masked

c.set_nullvalue_in_mask()
print('Data associated to a masked cell : ', c.array.data[0,0]) # Should be 0.0 (masked value)
Data associated to a masked cell :  -1.0
Maks status of a the cell :  False
Data associated to a masked cell :  100.0
Maks status of a the cell :  True
Data associated to a masked cell :  -1.0
Maks status of a the cell :  True
Data associated to a masked cell :  0.0