asteroid_spinprops 0.2.32__py3-none-any.whl → 1.0.1__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.
- asteroid_spinprops/ssolib/dataprep.py +0 -346
- asteroid_spinprops/ssolib/modelfit.py +143 -252
- asteroid_spinprops/ssolib/periodest.py +126 -158
- asteroid_spinprops/ssolib/utils.py +164 -211
- asteroid_spinprops-1.0.1.dist-info/METADATA +186 -0
- asteroid_spinprops-1.0.1.dist-info/RECORD +10 -0
- asteroid_spinprops/ssolib/.ruff_cache/.gitignore +0 -2
- asteroid_spinprops/ssolib/.ruff_cache/0.13.2/1980339045096230685 +0 -0
- asteroid_spinprops/ssolib/.ruff_cache/CACHEDIR.TAG +0 -1
- asteroid_spinprops/ssolib/pipetools.py +0 -167
- asteroid_spinprops/ssolib/testing/atlas_x_ztf_testing/test_pqfile_1.parquet +0 -0
- asteroid_spinprops/ssolib/testing/atlas_x_ztf_testing/test_pqfile_2.parquet +0 -0
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2000 WL152 +0 -1702
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2001 PC +0 -94
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2001 SG276 +0 -111
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2008 GX32 +0 -93
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2009 BE185 +0 -130
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2011 EY17 +0 -101
- asteroid_spinprops/ssolib/testing/ephemeris_testing/2134 T-1 +0 -352
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Bellmore +0 -2657
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Dermott +0 -2971
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Duke +0 -2026
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Izenberg +0 -2440
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Lermontov +0 -2760
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Poullain +0 -1272
- asteroid_spinprops/ssolib/testing/ephemeris_testing/Sonneberga +0 -2756
- asteroid_spinprops/ssolib/testing/testing_ssoname_keys.pkl +0 -0
- asteroid_spinprops-0.2.32.dist-info/METADATA +0 -77
- asteroid_spinprops-0.2.32.dist-info/RECORD +0 -31
- {asteroid_spinprops-0.2.32.dist-info → asteroid_spinprops-1.0.1.dist-info}/WHEEL +0 -0
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import numpy as np
|
|
2
2
|
import pandas as pd
|
|
3
|
-
import matplotlib.pyplot as plt
|
|
4
|
-
import sys
|
|
5
|
-
import os
|
|
6
3
|
from asteroid_spinprops.ssolib.modelfit import (
|
|
7
4
|
get_fit_params,
|
|
8
5
|
get_residuals,
|
|
@@ -251,346 +248,3 @@ def lightcurve_filtering(data, window=10, maglim=0.6):
|
|
|
251
248
|
data = utils.sort_by_cjd(data)
|
|
252
249
|
|
|
253
250
|
return data, rejects
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
def plot_filtering(
|
|
257
|
-
clean_data, rejects, lc_filtering=False, iter_filtering=True, xaxis="Phase"
|
|
258
|
-
):
|
|
259
|
-
if xaxis == "Date":
|
|
260
|
-
coll = "cjd"
|
|
261
|
-
if xaxis == "Phase":
|
|
262
|
-
coll = "Phase"
|
|
263
|
-
errorbar_rejects, projection_rejects, iterative_rejects, lightcurve_rejects = (
|
|
264
|
-
rejects[0],
|
|
265
|
-
rejects[1],
|
|
266
|
-
rejects[2],
|
|
267
|
-
rejects[3],
|
|
268
|
-
)
|
|
269
|
-
|
|
270
|
-
fig, ax = plt.subplots(2, 2, figsize=(12, 6))
|
|
271
|
-
|
|
272
|
-
filter_names = ["ZTF g", "ZTF r", "ATLAS orange", "ATLAS cyan"]
|
|
273
|
-
|
|
274
|
-
for i, f in enumerate(np.unique(clean_data["cfid"].values[0])):
|
|
275
|
-
if f in [1, 2]:
|
|
276
|
-
row = 0
|
|
277
|
-
if f in [3, 4]:
|
|
278
|
-
row = 1
|
|
279
|
-
|
|
280
|
-
if i % 2 != 0:
|
|
281
|
-
col = 1
|
|
282
|
-
else:
|
|
283
|
-
col = 0
|
|
284
|
-
|
|
285
|
-
filter_mask = np.array(clean_data["cfid"].values[0]) == f
|
|
286
|
-
filter_mask_r1 = np.array(errorbar_rejects["cfid"].values[0]) == f
|
|
287
|
-
filter_mask_r2 = np.array(projection_rejects["cfid"].values[0]) == f
|
|
288
|
-
|
|
289
|
-
if iter_filtering is True:
|
|
290
|
-
filter_mask_r3 = np.array(iterative_rejects["cfid"].values[0]) == f
|
|
291
|
-
else:
|
|
292
|
-
filter_mask_r3 = None
|
|
293
|
-
|
|
294
|
-
if lc_filtering is True:
|
|
295
|
-
filter_mask_r4 = np.array(lightcurve_rejects["cfid"].values[0]) == f
|
|
296
|
-
else:
|
|
297
|
-
filter_mask_r4 = None
|
|
298
|
-
|
|
299
|
-
ax[row, col].errorbar(
|
|
300
|
-
x=clean_data[coll].values[0][filter_mask],
|
|
301
|
-
y=clean_data["cmred"].values[0][filter_mask],
|
|
302
|
-
yerr=clean_data["csigmapsf"].values[0][filter_mask],
|
|
303
|
-
fmt=".",
|
|
304
|
-
capsize=2,
|
|
305
|
-
ms=5,
|
|
306
|
-
elinewidth=1,
|
|
307
|
-
label="Valid points",
|
|
308
|
-
)
|
|
309
|
-
|
|
310
|
-
ax[row, col].errorbar(
|
|
311
|
-
x=errorbar_rejects[coll].values[0][filter_mask_r1],
|
|
312
|
-
y=errorbar_rejects["cmred"].values[0][filter_mask_r1],
|
|
313
|
-
yerr=errorbar_rejects["csigmapsf"].values[0][filter_mask_r1],
|
|
314
|
-
fmt="x",
|
|
315
|
-
capsize=2,
|
|
316
|
-
ms=15,
|
|
317
|
-
elinewidth=1,
|
|
318
|
-
c="tab:red",
|
|
319
|
-
label=r"$\delta m > 3\sigma_{LCDB}$",
|
|
320
|
-
)
|
|
321
|
-
|
|
322
|
-
ax[row, col].errorbar(
|
|
323
|
-
x=projection_rejects[coll].values[0][filter_mask_r2],
|
|
324
|
-
y=projection_rejects["cmred"].values[0][filter_mask_r2],
|
|
325
|
-
yerr=projection_rejects["csigmapsf"].values[0][filter_mask_r2],
|
|
326
|
-
fmt="+",
|
|
327
|
-
capsize=2,
|
|
328
|
-
ms=15,
|
|
329
|
-
elinewidth=1,
|
|
330
|
-
c="tab:green",
|
|
331
|
-
label=r"$\substack{m > \bar{m} + 3\sigma_m \\ m < \bar{m} - 3\sigma_m}$",
|
|
332
|
-
)
|
|
333
|
-
if iter_filtering is True:
|
|
334
|
-
ax[row, col].errorbar(
|
|
335
|
-
x=iterative_rejects[coll].values[0][filter_mask_r3],
|
|
336
|
-
y=iterative_rejects["cmred"].values[0][filter_mask_r3],
|
|
337
|
-
yerr=iterative_rejects["csigmapsf"].values[0][filter_mask_r3],
|
|
338
|
-
fmt=">",
|
|
339
|
-
capsize=2,
|
|
340
|
-
ms=7,
|
|
341
|
-
elinewidth=1,
|
|
342
|
-
label=r"sHG$_1$G$_2$ filtering",
|
|
343
|
-
)
|
|
344
|
-
if lc_filtering is True:
|
|
345
|
-
ax[row, col].errorbar(
|
|
346
|
-
x=lightcurve_rejects[coll].values[0][filter_mask_r4],
|
|
347
|
-
y=lightcurve_rejects["cmred"].values[0][filter_mask_r4],
|
|
348
|
-
yerr=lightcurve_rejects["csigmapsf"].values[0][filter_mask_r4],
|
|
349
|
-
fmt="P",
|
|
350
|
-
capsize=2,
|
|
351
|
-
ms=7,
|
|
352
|
-
elinewidth=1,
|
|
353
|
-
c="black",
|
|
354
|
-
label="Lightcurve",
|
|
355
|
-
)
|
|
356
|
-
|
|
357
|
-
ax[row, col].invert_yaxis()
|
|
358
|
-
ax[row, col].text(
|
|
359
|
-
0.05,
|
|
360
|
-
0.05,
|
|
361
|
-
filter_names[i],
|
|
362
|
-
transform=ax[row, col].transAxes,
|
|
363
|
-
va="bottom",
|
|
364
|
-
ha="left",
|
|
365
|
-
bbox=dict(
|
|
366
|
-
facecolor="white",
|
|
367
|
-
edgecolor="black",
|
|
368
|
-
boxstyle="round,pad=0.3",
|
|
369
|
-
alpha=0.8,
|
|
370
|
-
),
|
|
371
|
-
)
|
|
372
|
-
if xaxis == "Phase":
|
|
373
|
-
ax[1, 0].set_xlabel("Phase / deg")
|
|
374
|
-
ax[1, 1].set_xlabel("Phase / deg")
|
|
375
|
-
if xaxis == "Date":
|
|
376
|
-
ax[1, 0].set_xlabel("JD")
|
|
377
|
-
ax[1, 1].set_xlabel("JD")
|
|
378
|
-
ax[0, 0].set_ylabel("Reduced magnitude")
|
|
379
|
-
ax[1, 0].set_ylabel("Reduced magnitude")
|
|
380
|
-
|
|
381
|
-
ax[0, 1].legend(loc="upper right")
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
def filter_sso_data(
|
|
385
|
-
sso_name,
|
|
386
|
-
path_to_data,
|
|
387
|
-
pqdict,
|
|
388
|
-
compute_ephemerides=False,
|
|
389
|
-
ephem_path=None,
|
|
390
|
-
mlimit=0.7928,
|
|
391
|
-
lc_maglim=0.6,
|
|
392
|
-
lc_filtering=False,
|
|
393
|
-
iter_filtering=True,
|
|
394
|
-
):
|
|
395
|
-
"""
|
|
396
|
-
Filters data for a given SSO.
|
|
397
|
-
Applies errorbar, projections, iterative sigma-clipping and lightcurve filtering.
|
|
398
|
-
|
|
399
|
-
Parameters
|
|
400
|
-
----------
|
|
401
|
-
sso_name : str
|
|
402
|
-
The name of the solar system object to filter.
|
|
403
|
-
path_to_data : str
|
|
404
|
-
Path to the data files.
|
|
405
|
-
pqdict : dict
|
|
406
|
-
Dictionary linking parquet filename to SSO.
|
|
407
|
-
ephem_path : str | None
|
|
408
|
-
Path to the ephemeris data.
|
|
409
|
-
mlimit : float, optional
|
|
410
|
-
Magnitude limit for errorbar filtering (default is 0.7928).
|
|
411
|
-
lc_filtering : bool, optional
|
|
412
|
-
Whether to apply lightcurve filtering (default is True).
|
|
413
|
-
iter_filtering : bool, optional
|
|
414
|
-
Whether to apply iterative filtering (default is True).
|
|
415
|
-
|
|
416
|
-
Returns
|
|
417
|
-
-------
|
|
418
|
-
clean_data : pd.DataFrame
|
|
419
|
-
Cleaned data
|
|
420
|
-
rejects : list
|
|
421
|
-
List of rejected data points from each filtering step.
|
|
422
|
-
|
|
423
|
-
Examples
|
|
424
|
-
---------
|
|
425
|
-
|
|
426
|
-
>>> from asteroid_spinprops.ssolib.dataprep import prepare_sso_data, filter_sso_data
|
|
427
|
-
>>> from asteroid_spinprops.ssolib.dataprep import __file__
|
|
428
|
-
>>> import os
|
|
429
|
-
>>> import pickle
|
|
430
|
-
|
|
431
|
-
>>> wpath = os.path.dirname(__file__)
|
|
432
|
-
|
|
433
|
-
>>> ephem_path = os.path.join(wpath, "testing/ephemeris_testing")
|
|
434
|
-
>>> data_path = os.path.join(wpath, "testing/atlas_x_ztf_testing")
|
|
435
|
-
>>> pq_keys = os.path.join(wpath, "testing/testing_ssoname_keys.pkl")
|
|
436
|
-
>>> available_ssos = os.listdir(ephem_path)
|
|
437
|
-
|
|
438
|
-
>>> with open(pq_keys, "rb") as f:
|
|
439
|
-
... pqload = pickle.load(f)
|
|
440
|
-
|
|
441
|
-
>>> path_args = [data_path, pqload, ephem_path]
|
|
442
|
-
|
|
443
|
-
>>> for name in available_ssos:
|
|
444
|
-
... origin_data = prepare_sso_data(name, *path_args)
|
|
445
|
-
... cdata, rejects = filter_sso_data(name, *path_args)
|
|
446
|
-
... clean_p_rejects = cdata["cmred"].values[0].size
|
|
447
|
-
... for n in range(4):
|
|
448
|
-
... clean_p_rejects += rejects[n]["cmred"].values[0].size
|
|
449
|
-
|
|
450
|
-
>>> assert origin_data["cmred"].values[0].size == clean_p_rejects
|
|
451
|
-
"""
|
|
452
|
-
if compute_ephemerides is False:
|
|
453
|
-
clean_data = read_sso_data(
|
|
454
|
-
sso_name=sso_name, path_to_data=path_to_data, pqdict=pqdict
|
|
455
|
-
)
|
|
456
|
-
else:
|
|
457
|
-
clean_data = prepare_sso_data(
|
|
458
|
-
sso_name=sso_name,
|
|
459
|
-
path_to_data=path_to_data,
|
|
460
|
-
pqdict=pqdict,
|
|
461
|
-
ephem_path=ephem_path,
|
|
462
|
-
)
|
|
463
|
-
|
|
464
|
-
clean_data, errorbar_rejects = errorbar_filtering(data=clean_data, mlimit=mlimit)
|
|
465
|
-
clean_data, projection_rejects = projection_filtering(data=clean_data)
|
|
466
|
-
if iter_filtering is True:
|
|
467
|
-
clean_data, iterative_rejects = iterative_filtering(clean_data)
|
|
468
|
-
else:
|
|
469
|
-
iterative_rejects = None
|
|
470
|
-
|
|
471
|
-
if lc_filtering is True:
|
|
472
|
-
clean_data, lightcurve_rejects = lightcurve_filtering(
|
|
473
|
-
clean_data, maglim=lc_maglim
|
|
474
|
-
)
|
|
475
|
-
else:
|
|
476
|
-
lightcurve_rejects = None
|
|
477
|
-
|
|
478
|
-
return clean_data, [
|
|
479
|
-
errorbar_rejects,
|
|
480
|
-
projection_rejects,
|
|
481
|
-
iterative_rejects,
|
|
482
|
-
lightcurve_rejects,
|
|
483
|
-
]
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
def prepare_sso_data(
|
|
487
|
-
sso_name,
|
|
488
|
-
path_to_data,
|
|
489
|
-
pqdict,
|
|
490
|
-
ephem_path,
|
|
491
|
-
):
|
|
492
|
-
"""
|
|
493
|
-
Load and prepare observational and ephemeris data for a given solar system object (SSO).
|
|
494
|
-
|
|
495
|
-
- Locates the appropriate pqfile containing the SSO & loads its photometric data
|
|
496
|
-
- Retrieves or generates the corresponding ephemeris and appends SSO-Sun & SSO-Obs distances, phase angle, RA/Dec, elongation, reduced magnitude
|
|
497
|
-
- The resulting DataFrame is sorted by Julian date
|
|
498
|
-
|
|
499
|
-
Parameters
|
|
500
|
-
-----------------------------
|
|
501
|
-
sso_name : str
|
|
502
|
-
The name of the solar system object to retrieve data for.
|
|
503
|
-
path_to_data : str
|
|
504
|
-
Path to the directory containing pqfiles in Parquet format.
|
|
505
|
-
pqdict : dict
|
|
506
|
-
Dictionary mapping pqfile names to lists of SSOs they contain.
|
|
507
|
-
ephem_path : str | None
|
|
508
|
-
Path to the directory containing cached ephemeris files.
|
|
509
|
-
|
|
510
|
-
Returns
|
|
511
|
-
-----------------------------
|
|
512
|
-
data_extra : pd.DataFrame
|
|
513
|
-
A DataFrame containing observational data and appended ephemeris-related quantities:
|
|
514
|
-
- 'Dobs': observer-centric distance [au]
|
|
515
|
-
- 'Dhelio': heliocentric distance [au]
|
|
516
|
-
- 'Phase': phase angle [deg]
|
|
517
|
-
- 'ra', 'dec': right ascension and declination [deg]
|
|
518
|
-
- 'Elongation': solar elongation angle [deg]
|
|
519
|
-
- 'cmred': reduced magnitude
|
|
520
|
-
The data is sorted chronologically by Julian date.
|
|
521
|
-
"""
|
|
522
|
-
file_name = utils.find_sso_in_pqdict(sso_name=sso_name, pqdict=pqdict)
|
|
523
|
-
file_path = os.path.join(path_to_data, file_name)
|
|
524
|
-
|
|
525
|
-
pdf = pd.read_parquet(file_path)
|
|
526
|
-
|
|
527
|
-
cond_name = pdf["name"] == sso_name
|
|
528
|
-
data_extra = pdf[cond_name].copy().reset_index(drop=True)
|
|
529
|
-
|
|
530
|
-
ephemeris = utils.get_atlas_ephem(
|
|
531
|
-
pdf=pdf, name=sso_name, path_to_cached_ephems=ephem_path
|
|
532
|
-
)
|
|
533
|
-
|
|
534
|
-
Dobs = ephemeris["Dobs"].values
|
|
535
|
-
|
|
536
|
-
Dhelio = ephemeris["Dhelio"].values
|
|
537
|
-
Phase = ephemeris["Phase"].values
|
|
538
|
-
Elongation = ephemeris["Elong."].values
|
|
539
|
-
dRA = ephemeris["dRAcosDEC"].values
|
|
540
|
-
dDec = ephemeris["dDEC"].values
|
|
541
|
-
|
|
542
|
-
# px, py, pz = ephemeris["px"], ephemeris["py"], ephemeris["pz"]
|
|
543
|
-
ra, dec = ra, dec = utils.sexa_to_deg(
|
|
544
|
-
ephemeris["RA"].values, ephemeris["DEC"].values
|
|
545
|
-
)
|
|
546
|
-
|
|
547
|
-
data_extra[
|
|
548
|
-
["Dobs", "Dhelio", "Phase", "ra", "dec", "Elongation", "dRA", "dDec"]
|
|
549
|
-
] = pd.DataFrame(
|
|
550
|
-
[[Dobs, Dhelio, Phase, ra, dec, Elongation, dRA, dDec]],
|
|
551
|
-
index=data_extra.index,
|
|
552
|
-
)
|
|
553
|
-
|
|
554
|
-
data_extra["cmred"] = [
|
|
555
|
-
utils.calculate_reduced_magnitude(
|
|
556
|
-
magnitude=data_extra["cmagpsf"].values[0],
|
|
557
|
-
D_observer=data_extra["Dobs"].values[0],
|
|
558
|
-
D_sun=data_extra["Dhelio"].values[0],
|
|
559
|
-
)
|
|
560
|
-
]
|
|
561
|
-
data_extra = utils.sort_by_cjd(data_extra)
|
|
562
|
-
return data_extra
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
def read_sso_data(
|
|
566
|
-
sso_name,
|
|
567
|
-
path_to_data,
|
|
568
|
-
pqdict,
|
|
569
|
-
):
|
|
570
|
-
file_name = utils.find_sso_in_pqdict(sso_name=sso_name, pqdict=pqdict)
|
|
571
|
-
file_path = os.path.join(path_to_data, file_name)
|
|
572
|
-
|
|
573
|
-
pdf = pd.read_parquet(file_path)
|
|
574
|
-
|
|
575
|
-
cond_name = pdf["name"] == sso_name
|
|
576
|
-
data_extra = pdf[cond_name].copy().reset_index(drop=True)
|
|
577
|
-
|
|
578
|
-
data_extra["cmred"] = [
|
|
579
|
-
utils.calculate_reduced_magnitude(
|
|
580
|
-
magnitude=data_extra["cmagpsf"].values[0],
|
|
581
|
-
D_observer=data_extra["Dobs"].values[0],
|
|
582
|
-
D_sun=data_extra["Dhelio"].values[0],
|
|
583
|
-
)
|
|
584
|
-
]
|
|
585
|
-
|
|
586
|
-
data_extra = data_extra.rename(columns={"RA": "ra", "DEC": "dec"})
|
|
587
|
-
|
|
588
|
-
data_extra = utils.sort_by_cjd(data_extra)
|
|
589
|
-
|
|
590
|
-
return data_extra
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
if __name__ == "__main__":
|
|
594
|
-
import doctest
|
|
595
|
-
|
|
596
|
-
sys.exit(doctest.testmod()[0])
|