arvi 0.1.28__tar.gz → 0.1.30__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 (59) hide show
  1. {arvi-0.1.28/arvi.egg-info → arvi-0.1.30}/PKG-INFO +4 -3
  2. {arvi-0.1.28 → arvi-0.1.30}/README.md +1 -1
  3. {arvi-0.1.28 → arvi-0.1.30}/arvi/dace_wrapper.py +46 -17
  4. {arvi-0.1.28 → arvi-0.1.30}/arvi/plots.py +49 -9
  5. {arvi-0.1.28 → arvi-0.1.30}/arvi/timeseries.py +11 -5
  6. {arvi-0.1.28 → arvi-0.1.30/arvi.egg-info}/PKG-INFO +4 -3
  7. {arvi-0.1.28 → arvi-0.1.30}/.github/dependabot.yml +0 -0
  8. {arvi-0.1.28 → arvi-0.1.30}/.github/workflows/docs-gh-pages.yml +0 -0
  9. {arvi-0.1.28 → arvi-0.1.30}/.github/workflows/install.yml +0 -0
  10. {arvi-0.1.28 → arvi-0.1.30}/.github/workflows/python-publish.yml +0 -0
  11. {arvi-0.1.28 → arvi-0.1.30}/.gitignore +0 -0
  12. {arvi-0.1.28 → arvi-0.1.30}/LICENSE +0 -0
  13. {arvi-0.1.28 → arvi-0.1.30}/arvi/HZ.py +0 -0
  14. {arvi-0.1.28 → arvi-0.1.30}/arvi/__init__.py +0 -0
  15. {arvi-0.1.28 → arvi-0.1.30}/arvi/ariadne_wrapper.py +0 -0
  16. {arvi-0.1.28 → arvi-0.1.30}/arvi/berv.py +0 -0
  17. {arvi-0.1.28 → arvi-0.1.30}/arvi/binning.py +0 -0
  18. {arvi-0.1.28 → arvi-0.1.30}/arvi/config.py +0 -0
  19. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/extra/HD86226_PFS1.rdb +0 -0
  20. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/extra/HD86226_PFS2.rdb +0 -0
  21. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/extra/metadata.json +0 -0
  22. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/info.svg +0 -0
  23. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/obs_affected_ADC_issues.dat +0 -0
  24. {arvi-0.1.28 → arvi-0.1.30}/arvi/data/obs_affected_blue_cryostat_issues.dat +0 -0
  25. {arvi-0.1.28 → arvi-0.1.30}/arvi/extra_data.py +0 -0
  26. {arvi-0.1.28 → arvi-0.1.30}/arvi/gaia_wrapper.py +0 -0
  27. {arvi-0.1.28 → arvi-0.1.30}/arvi/headers.py +0 -0
  28. {arvi-0.1.28 → arvi-0.1.30}/arvi/instrument_specific.py +0 -0
  29. {arvi-0.1.28 → arvi-0.1.30}/arvi/kima_wrapper.py +0 -0
  30. {arvi-0.1.28 → arvi-0.1.30}/arvi/lbl_wrapper.py +0 -0
  31. {arvi-0.1.28 → arvi-0.1.30}/arvi/nasaexo_wrapper.py +0 -0
  32. {arvi-0.1.28 → arvi-0.1.30}/arvi/programs.py +0 -0
  33. {arvi-0.1.28 → arvi-0.1.30}/arvi/reports.py +0 -0
  34. {arvi-0.1.28 → arvi-0.1.30}/arvi/setup_logger.py +0 -0
  35. {arvi-0.1.28 → arvi-0.1.30}/arvi/simbad_wrapper.py +0 -0
  36. {arvi-0.1.28 → arvi-0.1.30}/arvi/spectra.py +0 -0
  37. {arvi-0.1.28 → arvi-0.1.30}/arvi/stats.py +0 -0
  38. {arvi-0.1.28 → arvi-0.1.30}/arvi/stellar.py +0 -0
  39. {arvi-0.1.28 → arvi-0.1.30}/arvi/translations.py +0 -0
  40. {arvi-0.1.28 → arvi-0.1.30}/arvi/utils.py +0 -0
  41. {arvi-0.1.28 → arvi-0.1.30}/arvi.egg-info/SOURCES.txt +0 -0
  42. {arvi-0.1.28 → arvi-0.1.30}/arvi.egg-info/dependency_links.txt +0 -0
  43. {arvi-0.1.28 → arvi-0.1.30}/arvi.egg-info/requires.txt +0 -0
  44. {arvi-0.1.28 → arvi-0.1.30}/arvi.egg-info/top_level.txt +0 -0
  45. {arvi-0.1.28 → arvi-0.1.30}/docs/API.md +0 -0
  46. {arvi-0.1.28 → arvi-0.1.30}/docs/detailed.md +0 -0
  47. {arvi-0.1.28 → arvi-0.1.30}/docs/index.md +0 -0
  48. {arvi-0.1.28 → arvi-0.1.30}/docs/logo/detective.png +0 -0
  49. {arvi-0.1.28 → arvi-0.1.30}/docs/logo/logo.png +0 -0
  50. {arvi-0.1.28 → arvi-0.1.30}/mkdocs.yml +0 -0
  51. {arvi-0.1.28 → arvi-0.1.30}/pyproject.toml +0 -0
  52. {arvi-0.1.28 → arvi-0.1.30}/setup.cfg +0 -0
  53. {arvi-0.1.28 → arvi-0.1.30}/setup.py +0 -0
  54. {arvi-0.1.28 → arvi-0.1.30}/tests/HD10700-Bcor_ESPRESSO18.rdb +0 -0
  55. {arvi-0.1.28 → arvi-0.1.30}/tests/test_binning.py +0 -0
  56. {arvi-0.1.28 → arvi-0.1.30}/tests/test_create_RV.py +0 -0
  57. {arvi-0.1.28 → arvi-0.1.30}/tests/test_import_object.py +0 -0
  58. {arvi-0.1.28 → arvi-0.1.30}/tests/test_simbad.py +0 -0
  59. {arvi-0.1.28 → arvi-0.1.30}/tests/test_stats.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: arvi
3
- Version: 0.1.28
3
+ Version: 0.1.30
4
4
  Summary: The Automated RV Inspector
5
5
  Author-email: João Faria <joao.faria@unige.ch>
6
6
  License: MIT
@@ -20,6 +20,7 @@ Requires-Dist: loguru
20
20
  Requires-Dist: tqdm
21
21
  Requires-Dist: pySWEETCat
22
22
  Requires-Dist: kepmodel
23
+ Dynamic: license-file
23
24
 
24
25
  <p align="center">
25
26
  <img width = "140" src="https://github.com/j-faria/arvi/blob/main/docs/logo/logo.png?raw=true"/>
@@ -58,7 +59,7 @@ s = RV('HD1234', instrument='ESPRESSO')
58
59
 
59
60
  #### Current version
60
61
 
61
- ![PyPI - Version](https://img.shields.io/pypi/v/arvi)
62
+ [![PyPI - Version](https://img.shields.io/pypi/v/arvi?color=32c854)](https://pypi.org/project/arvi/)
62
63
 
63
64
  #### Actions
64
65
 
@@ -35,7 +35,7 @@ s = RV('HD1234', instrument='ESPRESSO')
35
35
 
36
36
  #### Current version
37
37
 
38
- ![PyPI - Version](https://img.shields.io/pypi/v/arvi)
38
+ [![PyPI - Version](https://img.shields.io/pypi/v/arvi?color=32c854)](https://pypi.org/project/arvi/)
39
39
 
40
40
  #### Actions
41
41
 
@@ -15,6 +15,7 @@ def load_spectroscopy(user=None) -> SpectroscopyClass:
15
15
  from .config import config
16
16
  # requesting as public
17
17
  if config.request_as_public:
18
+ logger.warning('requesting DACE data as public')
18
19
  with all_logging_disabled():
19
20
  dace = DaceClass(dace_rc_config_path='none')
20
21
  return SpectroscopyClass(dace_instance=dace)
@@ -300,26 +301,54 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
300
301
  msg = f'no {instrument} observations for {star}'
301
302
  raise ValueError(msg)
302
303
 
303
- # sort pipelines, being extra careful with HARPS pipeline names
304
- # (i.e. ensure that 3.x.x > 3.5)
304
+ # # sort pipelines, being extra careful with HARPS pipeline names
305
+ # # (i.e. ensure that 3.x.x > 3.5)
306
+ # from re import match
307
+ # def cmp(a, b):
308
+ # if a[0] in ('3.5', '3.5 EGGS') or 'EGGS' in a[0] and match(r'3.\d.\d', b[0]):
309
+ # return -1
310
+ # if b[0] in ('3.5', '3.5 EGGS') or 'EGGS' in b[0] and match(r'3.\d.\d', a[0]):
311
+ # return 1
312
+
313
+ # if a[0] == b[0]:
314
+ # return 0
315
+ # elif a[0] > b[0]:
316
+ # return 1
317
+ # else:
318
+ # return -1
319
+
320
+ # sort pipelines, must be extra careful with HARPS/HARPN pipeline version numbers
321
+ # got here with the help of DeepSeek
305
322
  from re import match
306
- def cmp(a, b):
307
- if a[0] in ('3.5', '3.5 EGGS') or 'EGGS' in a[0] and match(r'3.\d.\d', b[0]):
308
- return -1
309
- if b[0] in ('3.5', '3.5 EGGS') or 'EGGS' in b[0] and match(r'3.\d.\d', a[0]):
310
- return 1
311
-
312
- if a[0] == b[0]:
313
- return 0
314
- elif a[0] > b[0]:
315
- return 1
316
- else:
317
- return -1
318
-
319
- from functools import cmp_to_key
323
+ def custom_sort_key(s):
324
+ s = s[0]
325
+ print(s)
326
+ # Check for version number pattern (e.g., 3.2.5 or 3.2.5-EGGS)
327
+ version_match = match(r'^(\d+(?:\.\d+)*)(?:-(.*))?$', s)
328
+ if version_match:
329
+ version_parts = tuple(map(int, version_match.group(1).split('.')))
330
+ suffix = version_match.group(2)
331
+
332
+ if suffix is not None:
333
+ # Suffixed versions: sort in ascending order (3.2.5-HR11 < 3.3.1-HR11)
334
+ return (0, 0, version_parts, suffix)
335
+ else:
336
+ # Unsuffixed versions: sort in descending order (3.5 > 3.2.5)
337
+ return (0, 1, tuple(-x for x in version_parts))
338
+
339
+ # Check for scientific reference pattern (e.g., 2004A&A...)
340
+ year_match = match(r'^(\d{4})', s)
341
+ if year_match:
342
+ year = int(year_match.group(1))
343
+ return (1, year)
344
+
345
+ # For all other strings, sort alphabetically
346
+ return (2, s)
347
+
348
+ # from functools import cmp_to_key
320
349
  new_result = {}
321
350
  for inst in instruments:
322
- new_result[inst] = dict(sorted(result[inst].items(), key=cmp_to_key(cmp), reverse=True))
351
+ new_result[inst] = dict(sorted(result[inst].items(), key=custom_sort_key, reverse=True))
323
352
 
324
353
  if verbose:
325
354
  logger.info('RVs available from')
@@ -502,8 +502,8 @@ plot_berv = partialmethod(plot_quantity, quantity='berv')
502
502
 
503
503
 
504
504
  @plot_fast
505
- def gls(self, ax=None, label=None, fap=True, instrument=None,
506
- adjust_means=config.adjust_means_gls,
505
+ def gls(self, ax=None, label=None, instrument=None,
506
+ fap=True, fap_method='baluev', adjust_means=config.adjust_means_gls,
507
507
  picker=True, **kwargs):
508
508
  """
509
509
  Calculate and plot the Generalised Lomb-Scargle periodogram of the radial
@@ -515,11 +515,15 @@ def gls(self, ax=None, label=None, fap=True, instrument=None,
515
515
  created.
516
516
  label (str):
517
517
  The label to use for the plot.
518
- fap (bool):
519
- Whether to show the false alarm probability. Default is True.
520
518
  instrument (str or list):
521
519
  Which instruments' data to include in the periodogram. Default is
522
520
  all instruments.
521
+ fap (bool or float):
522
+ Whether to show the false alarm probability. A value (not a
523
+ percentage) can be provided to display a given FAP. Default is True.
524
+ fap_method (str):
525
+ Method used to estimate the FAP, passed directly to
526
+ `astropy.timeseries.LombScargle`. Default is 'baluev'.
523
527
  adjust_means (bool):
524
528
  Whether to adjust (subtract) the weighted means of each instrument.
525
529
  Default is `config.adjust_means_gls`.
@@ -597,8 +601,14 @@ def gls(self, ax=None, label=None, fap=True, instrument=None,
597
601
  fap_level = 0.01
598
602
  if isinstance(fap, float):
599
603
  fap_level = fap
600
- ax.axhline(gls.false_alarm_level(fap_level),
601
- color='k', alpha=0.2, zorder=-1)
604
+
605
+ fap = gls.false_alarm_level(fap_level, method=fap_method)
606
+
607
+ if fap > 0.05 and fap_method == 'baluev':
608
+ logger.warning('FAP is high (>5%), the analytical estimate may be underestimated. Using the bootstrap method instead.')
609
+ fap = gls.false_alarm_level(fap_level, method='bootstrap')
610
+
611
+ ax.axhline(fap, color='k', alpha=0.2, zorder=-1)
602
612
 
603
613
  ax.set(xlabel='Period [days]', ylabel='Normalized power', ylim=(0, None))
604
614
  ax.minorticks_on()
@@ -640,8 +650,32 @@ def gls(self, ax=None, label=None, fap=True, instrument=None,
640
650
 
641
651
 
642
652
  # @plot_fast
643
- def gls_quantity(self, quantity, ax=None, fap=True, instrument=None,
653
+ def gls_quantity(self, quantity, ax=None, instrument=None,
654
+ fap=True, fap_method='baluev',
644
655
  adjust_means=True, picker=True, **kwargs):
656
+ """
657
+ Calculate and plot the Generalised Lomb-Scargle periodogram of the given
658
+ quantity (e.g. fwhm, rhk, etc.)
659
+
660
+ Args:
661
+ quantity (str):
662
+ The quantity to calculate for which to compute the periodogram.
663
+ ax (matplotlib.axes.Axes):
664
+ The matplotlib axes to plot on. If None, a new figure will be
665
+ created.
666
+ instrument (str or list):
667
+ Which instruments' data to include in the periodogram. Default is
668
+ all instruments.
669
+ fap (bool or float):
670
+ Whether to show the false alarm probability. A value (not a
671
+ percentage) can be provided to display a given FAP. Default is True.
672
+ fap_method (str):
673
+ Method used to estimate the FAP, passed directly to
674
+ `astropy.timeseries.LombScargle`. Default is 'baluev'.
675
+ adjust_means (bool):
676
+ Whether to adjust (subtract) the weighted means of each instrument.
677
+ Default is `config.adjust_means_gls`.
678
+ """
645
679
 
646
680
  if not hasattr(self, quantity):
647
681
  if self.verbose:
@@ -715,8 +749,14 @@ def gls_quantity(self, quantity, ax=None, fap=True, instrument=None,
715
749
  fap_level = 0.01
716
750
  if isinstance(fap, float):
717
751
  fap_level = fap
718
- ax.axhline(gls.false_alarm_level(fap_level),
719
- color='k', alpha=0.2, zorder=-1)
752
+
753
+ fap = gls.false_alarm_level(fap_level, method=fap_method)
754
+
755
+ if fap > 0.05 and fap_method == 'baluev':
756
+ logger.warning('FAP is high (>5%), the analytical estimate may be underestimated. Using the bootstrap method instead.')
757
+ fap = gls.false_alarm_level(fap_level, method='bootstrap')
758
+
759
+ ax.axhline(fap, color='k', alpha=0.2, zorder=-1)
720
760
 
721
761
  ax.set(xlabel='Period [days]', ylabel='Normalized power', ylim=(0, None))
722
762
  ax.minorticks_on()
@@ -765,13 +765,19 @@ class RV:
765
765
  if isinstance(files, str):
766
766
  files = [files]
767
767
 
768
- CCFs = iCCF.from_file(files)
768
+ hdu_number = kwargs.pop('hdu_number', 1)
769
+ data_index = kwargs.pop('data_index', -1)
770
+ CCFs = iCCF.from_file(files, hdu_number=hdu_number, data_index=data_index)
769
771
 
770
772
  if not isinstance(CCFs, list):
771
773
  CCFs = [CCFs]
772
774
 
773
- objects = np.unique([i.HDU[0].header['OBJECT'].replace(' ', '') for i in CCFs])
774
- if objects.size != 1:
775
+ try:
776
+ objects = [i.OBJECT for i in CCFs]
777
+ except AttributeError:
778
+ objects = np.unique([i.HDU[0].header['OBJECT'].replace(' ', '') for i in CCFs])
779
+
780
+ if len(objects) != 1:
775
781
  logger.warning(f'found {objects.size} different stars in the CCF files, '
776
782
  'choosing the first one')
777
783
  star = objects[0]
@@ -808,7 +814,7 @@ class RV:
808
814
 
809
815
  _s.mask = np.full_like(_s.time, True, dtype=bool)
810
816
 
811
- _s.drs_qc = np.array([i.HDU[0].header['HIERARCH ESO QC SCIRED CHECK'] for i in CCFs], dtype=bool)
817
+ _s.drs_qc = np.array([i.HDU[0].header['*QC SCIRED CHECK'][0] for i in CCFs], dtype=bool)
812
818
  # mask out drs_qc = False
813
819
  if not _s.drs_qc.all():
814
820
  n = (~ _s.drs_qc).sum()
@@ -859,7 +865,7 @@ class RV:
859
865
  fits_file = f'{star}_RVs.fits'
860
866
 
861
867
  local_exists = os.path.exists(local_targz_file)
862
- local_recent = os.path.getmtime(local_targz_file) > pytime() - 60*60*2
868
+ local_recent = local_exists and os.path.getmtime(local_targz_file) > pytime() - 60*60*2
863
869
 
864
870
  if os.path.exists(os.path.join(directory, fits_file)):
865
871
  logger.info(f'found file "{fits_file}" in "{directory}"')
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: arvi
3
- Version: 0.1.28
3
+ Version: 0.1.30
4
4
  Summary: The Automated RV Inspector
5
5
  Author-email: João Faria <joao.faria@unige.ch>
6
6
  License: MIT
@@ -20,6 +20,7 @@ Requires-Dist: loguru
20
20
  Requires-Dist: tqdm
21
21
  Requires-Dist: pySWEETCat
22
22
  Requires-Dist: kepmodel
23
+ Dynamic: license-file
23
24
 
24
25
  <p align="center">
25
26
  <img width = "140" src="https://github.com/j-faria/arvi/blob/main/docs/logo/logo.png?raw=true"/>
@@ -58,7 +59,7 @@ s = RV('HD1234', instrument='ESPRESSO')
58
59
 
59
60
  #### Current version
60
61
 
61
- ![PyPI - Version](https://img.shields.io/pypi/v/arvi)
62
+ [![PyPI - Version](https://img.shields.io/pypi/v/arvi?color=32c854)](https://pypi.org/project/arvi/)
62
63
 
63
64
  #### Actions
64
65
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes