asteroid_spinprops 1.1.2__tar.gz → 1.2.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.
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/PKG-INFO +1 -1
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/modelfit.py +68 -4
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/utils.py +54 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/pyproject.toml +1 -1
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/README.md +0 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/__init__.py +0 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/__init__.py +0 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/dataprep.py +0 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/periodest.py +0 -0
- {asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/ssptools.py +0 -0
|
@@ -2,6 +2,7 @@ import numpy as np
|
|
|
2
2
|
import pandas as pd
|
|
3
3
|
|
|
4
4
|
import asteroid_spinprops.ssolib.utils as utils
|
|
5
|
+
import asteroid_spinprops.ssolib.periodest as periodest
|
|
5
6
|
|
|
6
7
|
from fink_utils.sso.spins import (
|
|
7
8
|
estimate_sso_params,
|
|
@@ -21,6 +22,7 @@ def get_fit_params(
|
|
|
21
22
|
p0=None,
|
|
22
23
|
alt_spin=False,
|
|
23
24
|
period_in=None,
|
|
25
|
+
period_quality_flag=False,
|
|
24
26
|
terminator=False,
|
|
25
27
|
):
|
|
26
28
|
"""
|
|
@@ -128,6 +130,10 @@ def get_fit_params(
|
|
|
128
130
|
residuals_dataframe, p_min=pmin, p_max=pmax, k_free=True
|
|
129
131
|
)
|
|
130
132
|
)
|
|
133
|
+
if period_quality_flag:
|
|
134
|
+
_, Nbs = periodest.perform_residual_resampling(
|
|
135
|
+
resid_df=residuals_dataframe, p_min=pmin, p_max=pmax, k=int(k_val)
|
|
136
|
+
)
|
|
131
137
|
except KeyError:
|
|
132
138
|
# If more than 10 terms are required switch to fast rotator:
|
|
133
139
|
pmin, pmax = 5e-3, 5e-2
|
|
@@ -137,6 +143,10 @@ def get_fit_params(
|
|
|
137
143
|
residuals_dataframe, p_min=pmin, p_max=pmax, k_free=True
|
|
138
144
|
)
|
|
139
145
|
)
|
|
146
|
+
if period_quality_flag:
|
|
147
|
+
_, Nbs = periodest.perform_residual_resampling(
|
|
148
|
+
resid_df=residuals_dataframe, p_min=pmin, p_max=pmax, k=int(k_val)
|
|
149
|
+
)
|
|
140
150
|
except Exception:
|
|
141
151
|
SOCCA_opt = {"Failed at period search after": 4}
|
|
142
152
|
return SOCCA_opt
|
|
@@ -153,16 +163,55 @@ def get_fit_params(
|
|
|
153
163
|
)
|
|
154
164
|
|
|
155
165
|
ra0, dec0 = shg1g2_params["alpha0"], shg1g2_params["delta0"]
|
|
156
|
-
|
|
166
|
+
|
|
157
167
|
if pole_blind is True:
|
|
158
168
|
ra_init, dec_init = utils.generate_initial_points(
|
|
159
169
|
ra0, dec0, dec_shift=45
|
|
160
170
|
)
|
|
161
171
|
|
|
162
172
|
else:
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
173
|
+
rarange = np.arange(0, 360, 10)
|
|
174
|
+
decrange = np.arange(-90, 90, 5)
|
|
175
|
+
rms_landscape = np.ones(shape=(len(rarange), len(decrange)))
|
|
176
|
+
|
|
177
|
+
for i, ra0 in enumerate(rarange):
|
|
178
|
+
for j, dec0 in enumerate(decrange):
|
|
179
|
+
|
|
180
|
+
all_residuals = []
|
|
181
|
+
|
|
182
|
+
for ff in np.unique(data["cfid"].values[0]):
|
|
183
|
+
cond_ff = data["cfid"].values[0] == ff
|
|
184
|
+
|
|
185
|
+
pha = [np.radians(data["Phase"].values[0][cond_ff]),
|
|
186
|
+
np.radians(data["ra"].values[0][cond_ff]),
|
|
187
|
+
np.radians(data["dec"].values[0][cond_ff])]
|
|
188
|
+
|
|
189
|
+
H = shg1g2_params[f"H_{ff}"]
|
|
190
|
+
G1 = shg1g2_params[f"G1_{ff}"]
|
|
191
|
+
G2 = shg1g2_params[f"G2_{ff}"]
|
|
192
|
+
R = shg1g2_params["R"]
|
|
193
|
+
|
|
194
|
+
C = func_hg1g2_with_spin(pha, H, G1, G2, R,
|
|
195
|
+
np.radians(ra0), np.radians(dec0))
|
|
196
|
+
|
|
197
|
+
O = data["cmred"].values[0][cond_ff]
|
|
198
|
+
|
|
199
|
+
all_residuals.append(O - C)
|
|
200
|
+
|
|
201
|
+
all_residuals = np.concatenate(all_residuals)
|
|
202
|
+
rms_landscape[j, i] = np.sqrt(np.mean(all_residuals**2))
|
|
203
|
+
|
|
204
|
+
interp_vals = utils.gaussian_interpolate(rms_landscape, factor=4, sigma=1.0)
|
|
205
|
+
ny, nx = interp_vals.shape
|
|
206
|
+
[rarange[0], rarange[-1], decrange[0], decrange[-1]]
|
|
207
|
+
ra_vals = np.linspace(rarange.min(), rarange.max(), nx)
|
|
208
|
+
dec_vals = np.linspace(decrange.min(), decrange.max(), ny)
|
|
209
|
+
ys, xs = utils.detect_local_minima(interp_vals)
|
|
210
|
+
ra_minima = ra_vals[xs]
|
|
211
|
+
dec_minima = dec_vals[ys]
|
|
212
|
+
|
|
213
|
+
ra_init = ra_minima
|
|
214
|
+
dec_init = dec_minima
|
|
166
215
|
|
|
167
216
|
H_key = next(
|
|
168
217
|
(f"H_{i}" for i in range(1, 7) if f"H_{i}" in shg1g2_params),
|
|
@@ -198,6 +247,21 @@ def get_fit_params(
|
|
|
198
247
|
try:
|
|
199
248
|
rms = np.array(rms)
|
|
200
249
|
SOCCA_opt = model[rms.argmin()]
|
|
250
|
+
if period_quality_flag:
|
|
251
|
+
try:
|
|
252
|
+
DeltaF1 = signal_peaks[1] - signal_peaks[2]
|
|
253
|
+
f_obs = 2 / period_sy
|
|
254
|
+
y_trumpet = utils.trumpet(
|
|
255
|
+
DeltaF1, 1, f_obs
|
|
256
|
+
)
|
|
257
|
+
alias_flag = (DeltaF1 - y_trumpet) * 100
|
|
258
|
+
if alias_flag < 1:
|
|
259
|
+
SOCCA_opt["Period_class"] = "true"
|
|
260
|
+
else:
|
|
261
|
+
SOCCA_opt["Period_class"] = "alias"
|
|
262
|
+
SOCCA_opt["Nbs"] = Nbs
|
|
263
|
+
except Exception:
|
|
264
|
+
SOCCA_opt["Period_class"] = "class_error"
|
|
201
265
|
except Exception:
|
|
202
266
|
SOCCA_opt = {"Failed at SOCCA inversion": 5}
|
|
203
267
|
return SOCCA_opt
|
|
@@ -418,3 +418,57 @@ def generate_initial_points(ra, dec, dec_shift=45):
|
|
|
418
418
|
ra_list.append(wrap_longitude(temp_ra + offset))
|
|
419
419
|
dec_list.append(shifted_dec)
|
|
420
420
|
return ra_list, dec_list
|
|
421
|
+
|
|
422
|
+
def gaussian_interpolate(data, factor=4, sigma=1.0):
|
|
423
|
+
"""
|
|
424
|
+
Reproduce matplotlib's `interpolation="gaussian"` effect.
|
|
425
|
+
factor : upsampling factor
|
|
426
|
+
sigma : Gaussian smoothing strength
|
|
427
|
+
"""
|
|
428
|
+
from scipy.ndimage import zoom, gaussian_filter
|
|
429
|
+
|
|
430
|
+
# Step 1: upsample (mimics interpolation grid)
|
|
431
|
+
up = zoom(data, factor, order=1) # bilinear before smoothing
|
|
432
|
+
|
|
433
|
+
# Step 2: apply gaussian smoothing
|
|
434
|
+
smoothed = gaussian_filter(up, sigma=sigma)
|
|
435
|
+
|
|
436
|
+
return smoothed
|
|
437
|
+
|
|
438
|
+
def detect_local_minima(arr):
|
|
439
|
+
import scipy.ndimage.filters as filters
|
|
440
|
+
import scipy.ndimage.morphology as morphology
|
|
441
|
+
|
|
442
|
+
# https://stackoverflow.com/questions/3684484/peak-detection-in-a-2d-array/3689710#3689710
|
|
443
|
+
# https://stackoverflow.com/questions/3986345/how-to-find-the-local-minima-of-a-smooth-multidimensional-array-in-numpy
|
|
444
|
+
"""
|
|
445
|
+
Takes an array and detects the troughs using the local maximum filter.
|
|
446
|
+
Returns a boolean mask of the troughs (i.e. 1 when
|
|
447
|
+
the pixel's value is the neighborhood maximum, 0 otherwise)
|
|
448
|
+
"""
|
|
449
|
+
neighborhood = morphology.generate_binary_structure(len(arr.shape),2)
|
|
450
|
+
|
|
451
|
+
footprint = np.ones((15, 15))
|
|
452
|
+
local_min = filters.minimum_filter(arr, footprint=footprint) == arr
|
|
453
|
+
|
|
454
|
+
background = (arr==0)
|
|
455
|
+
eroded_background = morphology.binary_erosion(
|
|
456
|
+
background, structure=neighborhood, border_value=1)
|
|
457
|
+
|
|
458
|
+
detected_minima = local_min ^ eroded_background
|
|
459
|
+
return np.where(detected_minima)
|
|
460
|
+
|
|
461
|
+
def trumpet(peak_diff_1, f_feat, f_obs):
|
|
462
|
+
if peak_diff_1 > 0 and f_obs > f_feat:
|
|
463
|
+
return 2 * f_feat
|
|
464
|
+
|
|
465
|
+
elif peak_diff_1 < 0 and f_obs < f_feat:
|
|
466
|
+
return -2 * f_obs
|
|
467
|
+
|
|
468
|
+
elif peak_diff_1 > 0 and f_obs < f_feat:
|
|
469
|
+
return 2 * f_obs
|
|
470
|
+
|
|
471
|
+
elif peak_diff_1 < 0 and f_obs > f_feat:
|
|
472
|
+
return -2 * f_feat
|
|
473
|
+
|
|
474
|
+
return 0.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "asteroid_spinprops"
|
|
3
|
-
version = "1.
|
|
3
|
+
version = "1.2.0"
|
|
4
4
|
description = "Collection of tools used for fitting sHG1G2 and SOCCA photometric models to sparse asteroid photometry"
|
|
5
5
|
authors = [
|
|
6
6
|
{name = "Odysseas",email = "odysseas.xenos@proton.me"}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{asteroid_spinprops-1.1.2 → asteroid_spinprops-1.2.0}/asteroid_spinprops/ssolib/periodest.py
RENAMED
|
File without changes
|
|
File without changes
|