foscat 2025.9.4__py3-none-any.whl → 2025.9.5__py3-none-any.whl

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.
foscat/FoCUS.py CHANGED
@@ -36,7 +36,7 @@ class FoCUS:
36
36
  mpi_rank=0
37
37
  ):
38
38
 
39
- self.__version__ = "2025.09.4"
39
+ self.__version__ = "2025.09.5"
40
40
  # P00 coeff for normalization for scat_cov
41
41
  self.TMPFILE_VERSION = TMPFILE_VERSION
42
42
  self.P1_dic = None
foscat/Plot.py CHANGED
@@ -1065,28 +1065,69 @@ def _spectrum_polar_to_cartesian_core(
1065
1065
  valid = np.isfinite(radial_index)
1066
1066
  try:
1067
1067
  from scipy.ndimage import map_coordinates
1068
- order = 3 if method.lower() == "bicubic" else 1
1069
- coords = np.vstack([radial_index.ravel(), angular_index.ravel()])
1070
- eps = 1e-6
1071
- coords[0, :] = np.where(np.isfinite(coords[0, :]),
1072
- np.clip(coords[0, :], 0.0+eps, (ns-1)-eps), 0.0)
1073
- sampled = map_coordinates(
1074
- w, coords, order=order, mode="wrap", cval=fill_value, prefilter=True
1075
- ).reshape(n_pixels, n_pixels)
1076
- img = np.where(valid, sampled, fill_value)
1068
+
1069
+ if method.lower() == "bicubic":
1070
+ # ===== Bicubic with circular angular wrap =====
1071
+ # Pad the angular axis by K columns on both sides so that the cubic kernel
1072
+ # has valid neighbors across the 0°/360° seam. K=2 is enough for a cubic kernel.
1073
+ K = 2
1074
+ # w has shape (Nscale, Norient)
1075
+ w_pad = np.concatenate([w[:, -K:], w, w[:, :K]], axis=1) # (ns, no+2K)
1076
+
1077
+ # Build coordinates for map_coordinates on the padded array:
1078
+ # - radial index stays the same, clipped to [0, ns-1] (no wrap)
1079
+ # - angular index is shifted by +K and wrapped into [0, no) before querying
1080
+ order = 3
1081
+ coords = np.vstack([radial_index.ravel(), angular_index.ravel()])
1082
+
1083
+ # clip the radial coordinate to the valid [eps, ns-1-eps] band
1084
+ eps = 1e-6
1085
+ coords[0, :] = np.where(
1086
+ np.isfinite(coords[0, :]),
1087
+ np.clip(coords[0, :], 0.0 + eps, (ns - 1) - eps),
1088
+ 0.0,
1089
+ )
1090
+
1091
+ # wrap angular coordinate to [0, no) then shift by +K to address the padded array
1092
+ ang = np.mod(coords[1, :], float(no)) + K # [K, no+K)
1093
+ coords[1, :] = ang
1094
+
1095
+ # Now sample the padded array; 'nearest' mode is fine thanks to explicit padding
1096
+ sampled = map_coordinates(
1097
+ w_pad, coords, order=order, mode="nearest", cval=fill_value, prefilter=True
1098
+ ).reshape(n_pixels, n_pixels)
1099
+
1100
+ img = np.where(valid, sampled, fill_value)
1101
+
1102
+ else:
1103
+ # ===== Bilinear (or other) without special padding =====
1104
+ order = 1
1105
+ coords = np.vstack([radial_index.ravel(), angular_index.ravel()])
1106
+ eps = 1e-6
1107
+ coords[0, :] = np.where(
1108
+ np.isfinite(coords[0, :]),
1109
+ np.clip(coords[0, :], 0.0 + eps, (ns - 1) - eps),
1110
+ 0.0,
1111
+ )
1112
+ # For non-bicubic, SciPy's mode="wrap" is sufficient on the angular axis
1113
+ sampled = map_coordinates(
1114
+ w, coords, order=order, mode="wrap", cval=fill_value, prefilter=True
1115
+ ).reshape(n_pixels, n_pixels)
1116
+ img = np.where(valid, sampled, fill_value)
1117
+
1077
1118
  except Exception:
1078
- # bilinear fallback
1119
+ # ---- Vectorized bilinear fallback with explicit angular wrap ----
1079
1120
  r_idx = np.floor(radial_index).astype(np.int64)
1080
1121
  t_idx = np.floor(angular_index).astype(np.int64)
1081
- r_idx = np.clip(r_idx, 0, ns-2)
1122
+ r_idx = np.clip(r_idx, 0, ns - 2)
1082
1123
  t0 = np.mod(t_idx, no)
1083
- t1 = np.mod(t_idx+1, no)
1124
+ t1 = np.mod(t_idx + 1, no)
1084
1125
  tr = np.clip(radial_index - r_idx, 0.0, 1.0)
1085
1126
  ta = np.clip(angular_index - t_idx, 0.0, 1.0)
1086
1127
  f00 = w[r_idx, t0]
1087
1128
  f01 = w[r_idx, t1]
1088
- f10 = w[r_idx+1, t0]
1089
- f11 = w[r_idx+1, t1]
1129
+ f10 = w[r_idx + 1, t0]
1130
+ f11 = w[r_idx + 1, t1]
1090
1131
  g0 = (1.0 - ta) * f00 + ta * f01
1091
1132
  g1 = (1.0 - ta) * f10 + ta * f11
1092
1133
  img = (1.0 - tr) * g0 + tr * g1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foscat
3
- Version: 2025.9.4
3
+ Version: 2025.9.5
4
4
  Summary: Generate synthetic Healpix or 2D data using Cross Scattering Transform
5
5
  Author-email: Jean-Marc DELOUIS <jean.marc.delouis@ifremer.fr>
6
6
  Maintainer-email: Theo Foulquier <theo.foulquier@ifremer.fr>
@@ -4,12 +4,12 @@ foscat/BkTensorflow.py,sha256=iIdLx6VTOfOEocfZBOGyizQn5geDLTfdWWAwDeQr9YA,20056
4
4
  foscat/BkTorch.py,sha256=W3n3XkFw9oecmyfSWt2JbP5L5eKWn8AAu0RZx1yLQb0,31975
5
5
  foscat/CNN.py,sha256=4vky7jqTshL1aYLWsc-hQwf7gDjTVjL7I6HZiAsa6x4,5158
6
6
  foscat/CircSpline.py,sha256=CXi49FxF8ZoeZ17Ua8c1AZXe2B5ICEC9aCXb97atB3s,4028
7
- foscat/FoCUS.py,sha256=DFPzRMRHE7eUfXfqoqHiM0f4mAiOs_6GmUieipXplo4,105645
7
+ foscat/FoCUS.py,sha256=uK9ehVEOG2EeIwztCrH2B7oE0uV9C6tOwnLs4RpuMHk,105645
8
8
  foscat/GCNN.py,sha256=q7yWHCMJpP7-m3WvR3OQnp5taeYWaMxIY2hQ6SIb9gs,4487
9
9
  foscat/HOrientedConvol.py,sha256=xMaS-zzoUyXisBCPsHBVpn54tuA9Qv3na-tT86Cwn7U,38744
10
10
  foscat/HealBili.py,sha256=YRPk9PO5G8NdwKeb33xiJs3_pMPAgIv5phCs8GT6LN0,12943
11
11
  foscat/HealSpline.py,sha256=YRotJ1NQuXYFyFiM8fp6qkATIwRJ8lqIVo4vGXpHO-w,7472
12
- foscat/Plot.py,sha256=a_NKE91F82qBeLNL3gy0qE06GCL-JbHgeIQ2iwIRPjY,47326
12
+ foscat/Plot.py,sha256=IM4kHzOvaVDwKkfCy6NePPNq6lGBsMr5oXhrRsiMJHw,49144
13
13
  foscat/Softmax.py,sha256=UDZGrTroYtmGEyokGUVpwNO_cgbICi9QVuRr8Yx52_k,2917
14
14
  foscat/SphericalStencil.py,sha256=DFipxQWupYPBa_62CkuMe9K7HkLFiHteF7Q6lAs3TLQ,56714
15
15
  foscat/Spline1D.py,sha256=rKzzenduaZZ-yBDJd35it6Gyrj1spqb7hoIaUgISPzY,2983
@@ -31,8 +31,8 @@ foscat/scat_cov1D.py,sha256=XOxsZZ5TYq8f34i2tUgIfzyaqaTDlICB3HzD2l_puro,531
31
31
  foscat/scat_cov2D.py,sha256=pAm0fKw8wyXram0TFbtw8tGcc8QPKuPXpQk0kh10r4U,7078
32
32
  foscat/scat_cov_map.py,sha256=9MzpwT2g9S3dmnjHEMK7PPLQ27oGQg2VFVsP_TDUU5E,2869
33
33
  foscat/scat_cov_map2D.py,sha256=zaIIYshXCqAeZ04I158GhD-Op4aoMlLnLEy7rxckVYY,2842
34
- foscat-2025.9.4.dist-info/licenses/LICENSE,sha256=i0ukIr8ZUpkSY2sZaE9XZK-6vuSU5iG6IgX_3pjatP8,1505
35
- foscat-2025.9.4.dist-info/METADATA,sha256=MznoPNHG--ttgyql7lKM2YZrrYz3AiHLag3yn2C04iM,7215
36
- foscat-2025.9.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
- foscat-2025.9.4.dist-info/top_level.txt,sha256=AGySXBBAlJgb8Tj8af6m_F-aiNg2zNTcybCUPVOKjAg,7
38
- foscat-2025.9.4.dist-info/RECORD,,
34
+ foscat-2025.9.5.dist-info/licenses/LICENSE,sha256=i0ukIr8ZUpkSY2sZaE9XZK-6vuSU5iG6IgX_3pjatP8,1505
35
+ foscat-2025.9.5.dist-info/METADATA,sha256=SPqwTwuI7oY7UydSzlwdTUbWEjE3R2OeeU5UgmgLejs,7215
36
+ foscat-2025.9.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
37
+ foscat-2025.9.5.dist-info/top_level.txt,sha256=AGySXBBAlJgb8Tj8af6m_F-aiNg2zNTcybCUPVOKjAg,7
38
+ foscat-2025.9.5.dist-info/RECORD,,