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

numpy arrays endianess is incorrect #730

Open
ilyasdc opened this issue Nov 20, 2023 · 2 comments
Open

numpy arrays endianess is incorrect #730

ilyasdc opened this issue Nov 20, 2023 · 2 comments
Labels
bug Something isn't working

Comments

@ilyasdc
Copy link
Contributor

ilyasdc commented Nov 20, 2023

Code for reproduction

from pycromanager import Studio
import numpy as np

h,w = 512,512
img = np.ones((h,w),dtype=np.int16)
mm = Studio(convert_camel_case=False)
mmimg = mm.data().createImage(img,
                  h,
                  w,
                  2,
                  1,
                  mm.data().coordsBuilder().build(),
                  mm.data().metadataBuilder().build())
print(mmimg.getIntensityAt(0,0),img[0,0])

Expected outcome
1 1

Actual outcome
256 1

Fix
The proposed fix is trivial but I don't know how to make it safe for any architecture/OS:

  • I don't think Java endianess changes between architectures ?
  • if it does, how does one check that the correct endianess is sent ?
diff --git a/bridge.py b/bridge_fix.py
index 8efbddd..9a86c4d 100644
--- a/bridge.py
+++ b/bridge_fix.py
@@ -804,11 +804,11 @@ def _serialize_arg(arg):
     if type(arg) in [bool, str, int, float]:
         return arg  # json handles serialization
     elif type(arg) == np.ndarray:
-        return arg.tobytes()
+        return arg.byteswap().tobytes()
     elif isinstance(arg, _JavaObjectShadow):
         return {"hash-code": arg._hash_code}
     else:
-        raise Exception("Unknown argumetn type")
+        raise Exception("Unknown argument type")
 
 
 def _check_single_method_spec(method_spec, fn_args):

PS: the iterate flag that I proposed and you merged while ago (cf #372) is not included in the signature of JavaObject

class JavaObject(_JavaObjectShadow):
"""
Instance of a an object on the Java side. Returns a Python "Shadow" of the object, which behaves
just like the object on the Java side (i.e. same methods, fields). Methods of the object can be inferred at
runtime using iPython autocomplete
"""
def __new__(
cls,
classpath,
args: list = None,
port=_Bridge.DEFAULT_PORT,
timeout=_Bridge.DEFAULT_TIMEOUT,
new_socket=False,
convert_camel_case=True,
debug=False,
):
"""
so you can't create Studio object with this argument, unless you create the bridge manually (which is not anymore the advised way if I'm correct)

@ilyasdc ilyasdc added the bug Something isn't working label Nov 20, 2023
@henrypinkard
Copy link
Member

  • I don't think Java endianess changes between architectures ?

I'm not sure.

  • if it does, how does one check that the correct endianess is sent ?

Seems like the safest way would be to check the endianness on the java side, and pass it along with binary data so it can be directly decoded on the python side

PS: the iterate flag that I proposed and you merged while ago (cf #372) is not included in the signature of JavaObject

I'm happy to merge a PR adding this to the signature (and/or anywhere else you think it is needed)

@ilyasdc
Copy link
Contributor Author

ilyasdc commented Nov 22, 2023

Ok thanks for your input, I will make a proper PR !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants