foscat 2025.5.2__tar.gz → 2025.6.3__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.
Files changed (37) hide show
  1. {foscat-2025.5.2/src/foscat.egg-info → foscat-2025.6.3}/PKG-INFO +1 -1
  2. {foscat-2025.5.2 → foscat-2025.6.3}/pyproject.toml +1 -1
  3. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/BkTorch.py +11 -12
  4. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/CNN.py +31 -30
  5. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/FoCUS.py +784 -780
  6. foscat-2025.6.3/src/foscat/GCNN.py +137 -0
  7. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/Softmax.py +1 -0
  8. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/alm.py +2 -2
  9. foscat-2025.6.3/src/foscat/heal_NN.py +451 -0
  10. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat_cov.py +186 -155
  11. {foscat-2025.5.2 → foscat-2025.6.3/src/foscat.egg-info}/PKG-INFO +1 -1
  12. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat.egg-info/SOURCES.txt +1 -0
  13. foscat-2025.5.2/src/foscat/GCNN.py +0 -239
  14. {foscat-2025.5.2 → foscat-2025.6.3}/LICENSE +0 -0
  15. {foscat-2025.5.2 → foscat-2025.6.3}/README.md +0 -0
  16. {foscat-2025.5.2 → foscat-2025.6.3}/setup.cfg +0 -0
  17. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/BkBase.py +0 -0
  18. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/BkNumpy.py +0 -0
  19. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/BkTensorflow.py +0 -0
  20. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/CircSpline.py +0 -0
  21. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/Spline1D.py +0 -0
  22. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/Synthesis.py +0 -0
  23. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/__init__.py +0 -0
  24. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/backend.py +0 -0
  25. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/backend_tens.py +0 -0
  26. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/loss_backend_tens.py +0 -0
  27. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/loss_backend_torch.py +0 -0
  28. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat.py +0 -0
  29. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat1D.py +0 -0
  30. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat2D.py +0 -0
  31. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat_cov1D.py +0 -0
  32. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat_cov2D.py +0 -0
  33. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat_cov_map.py +0 -0
  34. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat/scat_cov_map2D.py +0 -0
  35. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat.egg-info/dependency_links.txt +0 -0
  36. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat.egg-info/requires.txt +0 -0
  37. {foscat-2025.5.2 → foscat-2025.6.3}/src/foscat.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: foscat
3
- Version: 2025.5.2
3
+ Version: 2025.6.3
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>
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "foscat"
3
- version = "2025.05.2"
3
+ version = "2025.06.3"
4
4
  description = "Generate synthetic Healpix or 2D data using Cross Scattering Transform"
5
5
  readme = "README.md"
6
6
  license = { text = "BSD-3-Clause" }
@@ -149,11 +149,7 @@ class BkTorch(BackendBase.BackendBase):
149
149
  # -- BACKEND DEFINITION --
150
150
  # ---------------------------------------------−---------
151
151
  def bk_SparseTensor(self, indice, w, dense_shape=[]):
152
- return (
153
- self.backend.sparse_coo_tensor(indice.T, w, dense_shape)
154
- .to_sparse_csr()
155
- .to(self.torch_device)
156
- )
152
+ return self.backend.sparse_coo_tensor(indice.T, w, dense_shape).to_sparse_csr().to(self.torch_device)
157
153
 
158
154
  def bk_stack(self, list, axis=0):
159
155
  return self.backend.stack(list, axis=axis).to(self.torch_device)
@@ -246,13 +242,13 @@ class BkTorch(BackendBase.BackendBase):
246
242
  xr = self.bk_real(x)
247
243
  # xi = self.bk_imag(x)
248
244
 
249
- r = self.backend.sign(xr) * self.backend.sqrt(self.backend.sign(xr) * xr)
245
+ r = self.backend.sign(xr) * self.backend.sqrt(self.backend.sign(xr) * xr + 1E-16)
250
246
  # return r
251
247
  # i = self.backend.sign(xi) * self.backend.sqrt(self.backend.sign(xi) * xi)
252
248
 
253
249
  return r
254
250
  else:
255
- return self.backend.sign(x) * self.backend.sqrt(self.backend.sign(x) * x)
251
+ return self.backend.sign(x) * self.backend.sqrt(self.backend.sign(x) * x + 1E-16)
256
252
 
257
253
  def bk_square_comp(self, x):
258
254
  if x.dtype == self.all_cbk_type:
@@ -391,9 +387,9 @@ class BkTorch(BackendBase.BackendBase):
391
387
  return self.backend.argmax(data)
392
388
 
393
389
  def bk_reshape(self, data, shape):
394
- if isinstance(data, np.ndarray):
395
- return data.reshape(shape)
396
- return data.view(shape)
390
+ #if isinstance(data, np.ndarray):
391
+ # return data.reshape(shape)
392
+ return data.reshape(shape)
397
393
 
398
394
  def bk_repeat(self, data, nn, axis=0):
399
395
  return self.backend.repeat_interleave(data, repeats=nn, dim=axis)
@@ -429,6 +425,7 @@ class BkTorch(BackendBase.BackendBase):
429
425
  xr = self.backend.concat(
430
426
  [self.bk_real(data[k]) for k in range(ndata)], axis=axis
431
427
  )
428
+
432
429
  xi = self.backend.concat(
433
430
  [self.bk_imag(data[k]) for k in range(ndata)], axis=axis
434
431
  )
@@ -440,7 +437,9 @@ class BkTorch(BackendBase.BackendBase):
440
437
  return self.backend.zeros(shape, dtype=dtype).to(self.torch_device)
441
438
 
442
439
  def bk_gather(self, data, idx, axis=0):
443
- if axis == 0:
440
+ if axis == -1:
441
+ return data[...,idx]
442
+ elif axis == 0:
444
443
  return data[idx]
445
444
  elif axis == 1:
446
445
  return data[:, idx]
@@ -448,7 +447,7 @@ class BkTorch(BackendBase.BackendBase):
448
447
  return data[:, :, idx]
449
448
  elif axis == 3:
450
449
  return data[:, :, :, idx]
451
- return data[:, :, :, :, idx]
450
+ return data[idx,...]
452
451
 
453
452
  def bk_reverse(self, data, axis=0):
454
453
  return self.backend.flip(data, dims=[axis])
@@ -9,13 +9,12 @@ class CNN:
9
9
 
10
10
  def __init__(
11
11
  self,
12
- scat_operator=None,
13
12
  nparam=1,
14
- nscale=1,
13
+ KERNELSZ=3,
14
+ NORIENT=4,
15
15
  chanlist=[],
16
16
  in_nside=1,
17
17
  n_chan_in=1,
18
- nbatch=1,
19
18
  SEED=1234,
20
19
  filename=None,
21
20
  ):
@@ -31,31 +30,30 @@ class CNN:
31
30
  self.in_nside = outlist[4]
32
31
  self.nbatch = outlist[1]
33
32
  self.n_chan_in = outlist[8]
33
+ self.NORIENT = outlist[9]
34
34
  self.x = self.scat_operator.backend.bk_cast(outlist[6])
35
35
  self.out_nside = self.in_nside // (2**self.nscale)
36
36
  else:
37
- self.nscale = nscale
38
- self.nbatch = nbatch
37
+ self.nscale = len(chanlist)-1
39
38
  self.npar = nparam
40
39
  self.n_chan_in = n_chan_in
41
40
  self.scat_operator = scat_operator
42
- if len(chanlist) != nscale + 1:
43
- print(
44
- "len of chanlist (here %d) should of nscale+1 (here %d)"
45
- % (len(chanlist), nscale + 1)
46
- )
47
- return None
41
+ if self.scat_operator is None:
42
+ self.scat_operator = sc.funct(
43
+ KERNELSZ=KERNELSZ,
44
+ NORIENT=NORIENT)
48
45
 
49
46
  self.chanlist = chanlist
50
- self.KERNELSZ = scat_operator.KERNELSZ
51
- self.all_type = scat_operator.all_type
47
+ self.KERNELSZ = self.scat_operator.KERNELSZ
48
+ self.NORIENT = self.scat_operator.NORIENT
49
+ self.all_type = self.scat_operator.all_type
52
50
  self.in_nside = in_nside
53
51
  self.out_nside = self.in_nside // (2**self.nscale)
54
-
52
+ self.backend = self.scat_operator.backend
55
53
  np.random.seed(SEED)
56
- self.x = scat_operator.backend.bk_cast(
57
- np.random.randn(self.get_number_of_weights())
58
- / (self.KERNELSZ * self.KERNELSZ)
54
+ self.x = self.scat_operator.backend.bk_cast(
55
+ np.random.rand(self.get_number_of_weights())
56
+ / (self.KERNELSZ * (self.KERNELSZ//2+1)*self.NORIENT)
59
57
  )
60
58
 
61
59
  def save(self, filename):
@@ -70,6 +68,7 @@ class CNN:
70
68
  self.get_weights().numpy(),
71
69
  self.all_type,
72
70
  self.n_chan_in,
71
+ self.NORIENT,
73
72
  ]
74
73
 
75
74
  myout = open("%s.pkl" % (filename), "wb")
@@ -82,8 +81,8 @@ class CNN:
82
81
  totnchan = totnchan + self.chanlist[i] * self.chanlist[i + 1]
83
82
  return (
84
83
  self.npar * 12 * self.out_nside**2 * self.chanlist[self.nscale]
85
- + totnchan * self.KERNELSZ * self.KERNELSZ
86
- + self.KERNELSZ * self.KERNELSZ * self.n_chan_in * self.chanlist[0]
84
+ + totnchan * self.KERNELSZ * (self.KERNELSZ//2+1)
85
+ + self.KERNELSZ * (self.KERNELSZ//2+1) * self.n_chan_in * self.chanlist[0]
87
86
  )
88
87
 
89
88
  def set_weights(self, x):
@@ -95,30 +94,32 @@ class CNN:
95
94
  def eval(self, im, indices=None, weights=None):
96
95
 
97
96
  x = self.x
98
- ww = self.scat_operator.backend.bk_reshape(
99
- x[0 : self.KERNELSZ * self.KERNELSZ * self.n_chan_in * self.chanlist[0]],
100
- [self.KERNELSZ * self.KERNELSZ, self.n_chan_in, self.chanlist[0]],
97
+ ww = self.backend.bk_reshape(
98
+ x[0 : self.KERNELSZ * (self.KERNELSZ//2+1) * self.n_chan_in * self.chanlist[0]],
99
+ [self.n_chan_in, self.KERNELSZ * (self.KERNELSZ//2+1), self.chanlist[0]],
101
100
  )
102
- nn = self.KERNELSZ * self.KERNELSZ * self.n_chan_in * self.chanlist[0]
101
+ nn = self.KERNELSZ * (self.KERNELSZ//2+1) * self.n_chan_in * self.chanlist[0]
103
102
 
104
103
  im = self.scat_operator.healpix_layer(im, ww)
105
- im = self.scat_operator.backend.bk_relu(im)
104
+ im = self.backend.bk_relu(im)
105
+
106
+ im = self.backend.bk_reduce_mean(self.backend.bk_reshape(im,[im.shape[0],im.shape[1],im.shape[2]//4,4]),3)
106
107
 
107
108
  for k in range(self.nscale):
108
109
  ww = self.scat_operator.backend.bk_reshape(
109
110
  x[
110
111
  nn : nn
111
112
  + self.KERNELSZ
112
- * self.KERNELSZ
113
+ * (self.KERNELSZ//2+1)
113
114
  * self.chanlist[k]
114
115
  * self.chanlist[k + 1]
115
116
  ],
116
- [self.KERNELSZ * self.KERNELSZ, self.chanlist[k], self.chanlist[k + 1]],
117
+ [self.chanlist[k], self.KERNELSZ * (self.KERNELSZ//2+1), self.chanlist[k + 1]],
117
118
  )
118
119
  nn = (
119
120
  nn
120
121
  + self.KERNELSZ
121
- * self.KERNELSZ
122
+ * (self.KERNELSZ//2)
122
123
  * self.chanlist[k]
123
124
  * self.chanlist[k + 1]
124
125
  )
@@ -129,7 +130,7 @@ class CNN:
129
130
  im, ww, indices=indices[k], weights=weights[k]
130
131
  )
131
132
  im = self.scat_operator.backend.bk_relu(im)
132
- im = self.scat_operator.ud_grade_2(im, axis=0)
133
+ im = self.backend.bk_reduce_mean(self.backend.bk_reshape(im,[im.shape[0],im.shape[1],im.shape[2]//4,4]),3)
133
134
 
134
135
  ww = self.scat_operator.backend.bk_reshape(
135
136
  x[
@@ -141,11 +142,11 @@ class CNN:
141
142
 
142
143
  im = self.scat_operator.backend.bk_matmul(
143
144
  self.scat_operator.backend.bk_reshape(
144
- im, [1, 12 * self.out_nside**2 * self.chanlist[self.nscale]]
145
+ im, [im.shape[0], im.shape[1] * im.shape[2]]
145
146
  ),
146
147
  ww,
147
148
  )
148
- im = self.scat_operator.backend.bk_reshape(im, [self.npar])
149
+ #im = self.scat_operator.backend.bk_reshape(im, [self.npar])
149
150
  im = self.scat_operator.backend.bk_relu(im)
150
151
 
151
152
  return im