py-sphviewer2 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.1
2
+ Name: py-sphviewer2
3
+ Version: 1.0.0
4
+ Summary: A Python wrapper for SPH data rendering using the private smeshl C library.
5
+ Home-page: https://alejandrobll.github.io/content/sphviewer2/
6
+ Author: Alejandro Benitez-Llambay
7
+ Author-email: alejandro.benitezllambay@unimib.it
8
+ Project-URL: Bug Tracker, https://alejandrobll.github.io/content/sphviewer2/
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: Other/Proprietary License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
@@ -0,0 +1,13 @@
1
+ Metadata-Version: 2.1
2
+ Name: py-sphviewer2
3
+ Version: 1.0.0
4
+ Summary: A Python wrapper for SPH data rendering using the private smeshl C library.
5
+ Home-page: https://alejandrobll.github.io/content/sphviewer2/
6
+ Author: Alejandro Benitez-Llambay
7
+ Author-email: alejandro.benitezllambay@unimib.it
8
+ Project-URL: Bug Tracker, https://alejandrobll.github.io/content/sphviewer2/
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: Other/Proprietary License
11
+ Classifier: Operating System :: OS Independent
12
+ Requires-Python: >=3.6
13
+ Description-Content-Type: text/markdown
@@ -0,0 +1,8 @@
1
+ setup.py
2
+ py_sphviewer2.egg-info/PKG-INFO
3
+ py_sphviewer2.egg-info/SOURCES.txt
4
+ py_sphviewer2.egg-info/dependency_links.txt
5
+ py_sphviewer2.egg-info/requires.txt
6
+ py_sphviewer2.egg-info/top_level.txt
7
+ sphviewer2/__init__.py
8
+ sphviewer2/sphviewer2.py
@@ -0,0 +1 @@
1
+ numpy>=1.18.0
@@ -0,0 +1 @@
1
+ sphviewer2
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,31 @@
1
+ from setuptools import setup, find_packages
2
+ import os
3
+
4
+ # Read the long description from the README file
5
+ def read(fname):
6
+ return open(os.path.join(os.path.dirname(__file__), fname)).read()
7
+
8
+ setup(
9
+ name='py-sphviewer2', # Package name
10
+ version='1.0.0', # Initial version number
11
+ author='Alejandro Benitez-Llambay',
12
+ author_email='alejandro.benitezllambay@unimib.it',
13
+ description='A Python wrapper for SPH data rendering using the private smeshl C library.',
14
+ long_description='', # Make sure to have a README.md file in your directory
15
+ long_description_content_type='text/markdown',
16
+ url='https://alejandrobll.github.io/content/sphviewer2/', # Replace with your project repository link
17
+ packages=find_packages(), # Automatically finds all packages within the directory
18
+ include_package_data=True, # Include package data specified in MANIFEST.in
19
+ classifiers=[
20
+ 'Programming Language :: Python :: 3',
21
+ 'License :: Other/Proprietary License',
22
+ 'Operating System :: OS Independent',
23
+ ],
24
+ python_requires='>=3.6',
25
+ install_requires=[
26
+ 'numpy>=1.18.0',
27
+ ],
28
+ project_urls={
29
+ 'Bug Tracker': 'https://alejandrobll.github.io/content/sphviewer2/', # Replace with your repo issue tracker
30
+ },
31
+ )
@@ -0,0 +1 @@
1
+ from .sphviewer2 import sphviewer2
@@ -0,0 +1,171 @@
1
+ ###############################################################################
2
+ # Py-SPHViewer2 - Rendering Library Wrapper #
3
+ # #
4
+ # This Python module provides an interface for rendering images based on #
5
+ # Smoothed Particle Hydrodynamics (SPH) data using the private `smeshl` #
6
+ # library. The shared library is proprietary and was developed by Alejandro #
7
+ # Benitez-Llambay. It is not publicly available and must be obtained #
8
+ # from the link provided #
9
+ # #
10
+ # Author: Alejandro Benitez-Llambay #
11
+ # Email: alejandro.benitezllambay@unimib.it #
12
+ # License: Private #
13
+ # #
14
+ # This wrapper provides a Python interface to the `smeshl` library, which #
15
+ # must be compiled for your operating system (macOS/Linux). Ensure that the #
16
+ # appropriate shared library (.dylib/.so) is present in your system path. #
17
+ # #
18
+ # DISCLAIMER: #
19
+ # This software is provided "as is", without any warranty of any kind, either #
20
+ # expressed or implied, including but not limited to the warranties of #
21
+ # merchantability, fitness for a particular purpose, and non-infringement. #
22
+ # In no event shall the author be liable for any claim, damages, or other #
23
+ # liability, whether in an action of contract, tort, or otherwise, arising #
24
+ # from, out of, or in connection with the software or the use or other #
25
+ # dealings in the software. #
26
+ # #
27
+ # Users should NOT distribute this software, in whole or in part, #
28
+ # without prior written permission from the author. #
29
+ ###############################################################################
30
+
31
+ import ctypes as _ctypes
32
+ import numpy as _np
33
+ import platform as _platform
34
+
35
+ class sphviewer2:
36
+ """
37
+ A Python wrapper for rendering images using smeshl shared library.
38
+ """
39
+
40
+ def __init__(self):
41
+ """
42
+ Initializes the sphviewer2 instance and loads the shared C library.
43
+ Determines the platform-specific shared library extension and loads the corresponding shared library.
44
+
45
+ Raises:
46
+ OSError: If the operating system is unsupported or the shared library cannot be loaded.
47
+ """
48
+ library_name = "libsmeshl"
49
+ file_extension = self._get_shared_library_extension()
50
+
51
+ # Construct the library file path
52
+ library_file = f"{library_name}{file_extension}"
53
+
54
+ # Load the shared library
55
+ try:
56
+ self.lib = _ctypes.CDLL(library_file)
57
+ except OSError as e:
58
+ raise OSError(f"Failed to load the library: {library_file}") from e
59
+
60
+ # Define argument types and return type for the C function 'render'
61
+ self.lib.render.argtypes = [
62
+ _ctypes.POINTER(_ctypes.c_float), _ctypes.POINTER(_ctypes.c_float),
63
+ _ctypes.POINTER(_ctypes.c_float), _ctypes.POINTER(_ctypes.c_float),
64
+ _ctypes.c_int, _ctypes.c_float, _ctypes.c_float,
65
+ _ctypes.c_float, _ctypes.c_int, _ctypes.c_int,
66
+ _ctypes.POINTER(_ctypes.c_float)
67
+ ]
68
+ self.lib.render.restype = _ctypes.c_int
69
+
70
+ def render(self, x, y, m, h, xmin, ymin, Lbox, LevelMin, LevelMax, k=None):
71
+ """
72
+ Renders an image based on the SPH data passed as arguments.
73
+
74
+ Args:
75
+ x (np.ndarray or float): Array or scalar representing the x-coordinates of particles.
76
+ y (np.ndarray or float): Array or scalar representing the y-coordinates of particles.
77
+ m (np.ndarray or float): Array or scalar representing the mass of particles.
78
+ h (np.ndarray or float): Array or scalar representing the smoothing lengths of particles.
79
+ xmin (float): The minimum x-coordinate of the bounding box.
80
+ ymin (float): The minimum y-coordinate of the bounding box.
81
+ Lbox (float): The size of the bounding box.
82
+ LevelMin (int): The minimum refinement level.
83
+ LevelMax (int): The maximum refinement level (determines the image size as 2^LevelMax).
84
+ k (np.ndarray, optional): Indices to subset the particles. Defaults to None.
85
+
86
+ Returns:
87
+ np.ndarray: A 2D array representing the rendered image.
88
+
89
+ Raises:
90
+ RuntimeError: If the C function returns a non-zero error code.
91
+ ValueError: If any of the input parameters are invalid.
92
+ """
93
+ # Validate inputs
94
+ if not isinstance(LevelMax, int) or LevelMax < 1:
95
+ raise ValueError("LevelMax should be a positive integer.")
96
+ if not isinstance(xmin, (int, float)) or not isinstance(ymin, (int, float)):
97
+ raise ValueError("xmin and ymin must be numeric values.")
98
+
99
+ # Determine output image size based on LevelMax
100
+ size = 1 << LevelMax # size = 2^LevelMax
101
+ output_image = _np.zeros((size, size), dtype=_np.float32)
102
+
103
+ # Ensure x, y, m, h are arrays or convert scalars to arrays
104
+ x = self._ensure_array(x)
105
+ y = self._ensure_array(y)
106
+ m = self._ensure_array(m)
107
+ h = self._ensure_array(h)
108
+
109
+ # If k is provided, use it to subset the arrays
110
+ if k is not None:
111
+ x = x[k]
112
+ y = y[k]
113
+ m = m[k]
114
+ h = h[k]
115
+
116
+ Npart = len(x)
117
+
118
+ # Convert numpy arrays to ctypes pointers
119
+ x_ptr = x.ctypes.data_as(_ctypes.POINTER(_ctypes.c_float))
120
+ y_ptr = y.ctypes.data_as(_ctypes.POINTER(_ctypes.c_float))
121
+ m_ptr = m.ctypes.data_as(_ctypes.POINTER(_ctypes.c_float))
122
+ h_ptr = h.ctypes.data_as(_ctypes.POINTER(_ctypes.c_float))
123
+ output_ptr = output_image.ctypes.data_as(_ctypes.POINTER(_ctypes.c_float))
124
+
125
+ # Call the C function for rendering
126
+ result = self.lib.render(
127
+ x_ptr, y_ptr, m_ptr, h_ptr,
128
+ Npart, xmin, ymin,
129
+ Lbox, LevelMin, LevelMax,
130
+ output_ptr
131
+ )
132
+
133
+ # Check the result and raise an error if rendering failed
134
+ if result != 0:
135
+ raise RuntimeError(f"C function returned an error code: {result}")
136
+
137
+ return output_image
138
+
139
+ def _ensure_array(self, data):
140
+ """
141
+ Ensures that the input is an array. If the input is a scalar, it converts it into a 1-element numpy array.
142
+
143
+ Args:
144
+ data (float or np.ndarray): The input data to ensure as an array.
145
+
146
+ Returns:
147
+ np.ndarray: The input data as a numpy array.
148
+ """
149
+ if isinstance(data, _np.ndarray):
150
+ return data.astype(_np.float32)
151
+ else:
152
+ return _np.array([data], dtype=_np.float32)
153
+
154
+ def _get_shared_library_extension(self):
155
+ """
156
+ Returns the platform-specific extension for shared libraries.
157
+
158
+ Returns:
159
+ str: The file extension for the shared library (e.g., '.dylib' for macOS, '.so' for Linux).
160
+
161
+ Raises:
162
+ OSError: If the operating system is unsupported.
163
+ """
164
+ current_os = _platform.system()
165
+
166
+ if current_os == 'Darwin': # macOS
167
+ return '.dylib'
168
+ elif current_os == 'Linux':
169
+ return '.so'
170
+ else:
171
+ raise OSError(f"Unsupported operating system: {current_os}")