Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weighted concatenation fails due to negative integer powers not allowed #39

Closed
joakimsk opened this issue Jun 28, 2024 · 3 comments
Closed

Comments

@joakimsk
Copy link
Contributor

Hello,

While trying to concatenate all pings in an xtf, xtf_io.py line 228 raises a ValueError exception:

Traceback (most recent call last):
File "c:\dev\pyxtf\examples\plot_sonar_bathy.py", line 39, in
np_chan1 = concatenate_channel(p[XTFHeaderType.sonar], file_header=fh, channel=0, weighted=True)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "c:\dev\pyxtf\pyxtf\xtf_io.py", line 228, in concatenate_channel
out_array *= (2 ** -np.array(weight_factors)).astype(out_array.dtype)[:, np.newaxis]
~~^^~~~~~~~~~~~~~~~~~~~~~~~~~~
ValueError: Integers to negative integer powers are not allowed.

My xtf has positive integer weights defined for each ping.
The xtf_io.py:203 out_array datatype is uint16 by default
The xtf_io.py:228 weight_factors are also integers
The xtf_io.py:229 results involve element-wise negative power, but numpy does not allow this, as the result will be float

I "fixed" this by ensuring xtf_io.py:203 out_array was np.float32 and that xtf_io.py:228 weighted_factors cast the Weight to float as-well, but not sure this is the cleanest way to handle this. The output out_array will thus be float32, instead of uint16.

xtf_io.py:227:
if weighted:
weight_factors = [float(ping.ping_chan_headers[channel].Weight) for ping in pings[::-1]]
convertedArray = out_array.astype(np.float32)
convertedArray *= (2 ** -np.array(weight_factors)).astype(convertedArray.dtype)[:, np.newaxis]
return convertedArray

Anyone got a better suggestion?

@oysstu
Copy link
Owner

oysstu commented Jun 28, 2024

I believe this worked back in the day because numpy was more willing to do automatic type coercion. Negative powers are only permitted for floating point numbers. Try to change the type of the exponent to float32, that might work. Not sure if the output array needs to be float as well.

@joakimsk
Copy link
Contributor Author

Thanks @oysstu, I used np.multiply instead of *= and also used np.power with 2.0 instead of 2; this seems to work ok. I also cast it to dtype of out_array, as original. I think it is as you suggest, the output does not need to be float. I hope this works with other xtf input as-well, do you have some to test it out on?

if weighted:
    weight_factors = [ping.ping_chan_headers[channel].Weight for ping in pings[::-1]]
    out_array = np.multiply(out_array, np.power(2.0, -np.array(weight_factors))[:, np.newaxis]).astype(out_array.dtype)

@oysstu
Copy link
Owner

oysstu commented Jul 3, 2024

Solved by #41

@oysstu oysstu closed this as completed Jul 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants