arvi 0.1.16__py3-none-any.whl → 0.1.19__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.

Potentially problematic release.


This version of arvi might be problematic. Click here for more details.

arvi/plots.py CHANGED
@@ -431,12 +431,16 @@ def plot_quantity(self, quantity, ax=None, show_masked=False, instrument=None,
431
431
  p = p.replace('_', '.')
432
432
  label = f'{i}-{p}'
433
433
 
434
- y = getattr(s, quantity)
434
+ y = getattr(s, quantity).copy()
435
435
  try:
436
- ye = getattr(s, quantity + '_err')
436
+ ye = getattr(s, quantity + '_err').copy()
437
437
  except AttributeError:
438
438
  ye = np.zeros_like(y)
439
439
 
440
+ if (nans := np.isnan(y)).any():
441
+ if self.verbose:
442
+ logger.warning(f'{nans.sum()} NaN values for {inst}')
443
+ ye[nans] = np.nan
440
444
 
441
445
  if np.isnan(y).all() or np.isnan(ye).all():
442
446
  lines, *_ = ax.errorbar([], [], [],
@@ -464,7 +468,7 @@ def plot_quantity(self, quantity, ax=None, show_masked=False, instrument=None,
464
468
  ax.minorticks_on()
465
469
 
466
470
  ylabel = {
467
- quantity: quantity,
471
+ quantity.lower(): quantity,
468
472
  'fwhm': f'FWHM [{self.units}]',
469
473
  'bispan': f'BIS [{self.units}]',
470
474
  'rhk': r"$\log$ R'$_{HK}$",
@@ -485,6 +489,7 @@ def plot_quantity(self, quantity, ax=None, show_masked=False, instrument=None,
485
489
 
486
490
  plot_fwhm = partialmethod(plot_quantity, quantity='fwhm')
487
491
  plot_bis = partialmethod(plot_quantity, quantity='bispan')
492
+ plot_contrast = partialmethod(plot_quantity, quantity='contrast')
488
493
  plot_rhk = partialmethod(plot_quantity, quantity='rhk')
489
494
  plot_berv = partialmethod(plot_quantity, quantity='berv')
490
495
 
@@ -518,7 +523,7 @@ def gls(self, ax=None, label=None, fap=True, instrument=None, adjust_means=confi
518
523
 
519
524
  if not self._did_adjust_means and not adjust_means:
520
525
  logger.warning('gls() called before adjusting instrument means, '
521
- 'consider using `adjust_means` argument')
526
+ 'consider using the `adjust_means` argument')
522
527
 
523
528
  if instrument is not None:
524
529
  strict = kwargs.pop('strict', False)
@@ -536,11 +541,11 @@ def gls(self, ax=None, label=None, fap=True, instrument=None, adjust_means=confi
536
541
  if adjust_means and not self._child:
537
542
  if self.verbose:
538
543
  logger.info('adjusting instrument means before gls')
539
- means = np.empty_like(y)
544
+ means = np.zeros_like(y)
540
545
  for i in instrument:
541
546
  mask = self.instrument_array[instrument_mask & self.mask] == i
542
547
  if len(y[mask]) > 0:
543
- means += wmean(y[mask], e[mask]) * mask
548
+ means = means + wmean(y[mask], e[mask]) * mask
544
549
  y = y - means
545
550
 
546
551
  else:
@@ -551,11 +556,11 @@ def gls(self, ax=None, label=None, fap=True, instrument=None, adjust_means=confi
551
556
  if adjust_means and not self._child:
552
557
  if self.verbose:
553
558
  logger.info('adjusting instrument means before gls')
554
- means = np.empty_like(y)
559
+ means = np.zeros_like(y)
555
560
  for i in self.instruments:
556
561
  mask = self.instrument_array[self.mask] == i
557
562
  if len(y[mask]) > 0:
558
- means += wmean(y[mask], e[mask]) * mask
563
+ means = means + wmean(y[mask], e[mask]) * mask
559
564
  y = y - means
560
565
 
561
566
  self._gls = gls = LombScargle(t, y, e)
@@ -623,31 +628,70 @@ def gls(self, ax=None, label=None, fap=True, instrument=None, adjust_means=confi
623
628
  return fig, ax
624
629
 
625
630
 
626
- @plot_fast
627
- def gls_quantity(self, quantity, ax=None, fap=True, picker=True):
631
+ # @plot_fast
632
+ def gls_quantity(self, quantity, ax=None, fap=True, instrument=None,
633
+ adjust_means=True, picker=True, **kwargs):
634
+
628
635
  if not hasattr(self, quantity):
629
- logger.error(f"cannot find '{quantity}' attribute")
636
+ if self.verbose:
637
+ logger.error(f"cannot find '{quantity}' attribute")
630
638
  return
631
639
 
632
- if ax is None:
633
- fig, ax = plt.subplots(1, 1, constrained_layout=True)
634
- else:
635
- fig = ax.figure
640
+ if self.N == 0:
641
+ if self.verbose:
642
+ logger.error('no data to compute gls')
643
+ return
644
+
645
+ if not self._did_adjust_means and not adjust_means:
646
+ logger.warning('gls() called before adjusting instrument means, '
647
+ 'consider using the `adjust_means` argument')
648
+
649
+ strict = kwargs.pop('strict', False)
650
+ instrument = self._check_instrument(instrument, strict=strict, log=True)
651
+ if instrument is None:
652
+ return
653
+
654
+ instrument_mask = np.isin(self.instrument_array, instrument)
655
+ final_mask = instrument_mask & self.mask
636
656
 
637
- t = self.mtime
638
- y = getattr(self, quantity)[self.mask]
657
+ t = self.time[final_mask].copy()
658
+ y = getattr(self, quantity)[final_mask].copy()
639
659
  try:
640
- ye = getattr(self, quantity + '_err')[self.mask]
660
+ ye = getattr(self, quantity + '_err')[final_mask].copy()
641
661
  except AttributeError:
642
662
  ye = None
643
663
 
644
- if np.isnan(y).any():
664
+ if self.verbose:
665
+ logger.info(f'calculating periodogram for instrument {instrument}')
666
+
667
+ nan_mask = np.isnan(y)
668
+ if nan_mask.any():
645
669
  if self.verbose:
646
670
  logger.warning(f'{quantity} contains NaNs, ignoring them')
647
- m = np.isnan(y)
648
- t = t[~m]
649
- y = y[~m]
650
- ye = ye[~m]
671
+
672
+ if adjust_means and not self._child:
673
+ if self.verbose:
674
+ logger.info('adjusting instrument means before gls')
675
+ means = np.zeros_like(y)
676
+ for i in instrument:
677
+ mask = (self.instrument_array[final_mask] == i) & ~nan_mask
678
+ if len(y[mask]) > 0:
679
+ # print(wmean(y[mask], ye[mask]))
680
+ means += wmean(y[mask], ye[mask]) * mask
681
+ y = y - means
682
+
683
+ t = t[~nan_mask]
684
+ y = y[~nan_mask]
685
+ ye = ye[~nan_mask]
686
+
687
+ if len(y) == 0:
688
+ logger.error('no data left to compute gls after removing NaNs')
689
+ return
690
+
691
+ if ax is None:
692
+ fig, ax = plt.subplots(1, 1, constrained_layout=True)
693
+ else:
694
+ fig = ax.figure
651
695
 
652
696
  gls = LombScargle(t, y, ye)
653
697
  freq, power = gls.autopower(maximum_frequency=1.0)
arvi/reports.py CHANGED
@@ -27,6 +27,29 @@ def sine_picker(event, self, fig, ax, ax1):
27
27
  fig.canvas.draw_idle()
28
28
 
29
29
 
30
+ def summary(self, add_ccf_mask=True, add_prog_id=False):
31
+ from .utils import pretty_print_table
32
+ rows = []
33
+ rows.append([self.star] + [''] * len(self.instruments))
34
+ rows.append([''] + self.instruments)
35
+ rows.append(['N'] + list(self.NN.values()))
36
+
37
+ if add_ccf_mask:
38
+ row = ['CCF mask']
39
+ for inst in self.instruments:
40
+ row.append(', '.join(np.unique(getattr(self, inst).ccf_mask)))
41
+ rows.append(row)
42
+
43
+ if add_prog_id:
44
+ row = ['prog ID']
45
+ for inst in self.instruments:
46
+ p = ', '.join(np.unique(getattr(self, inst).prog_id))
47
+ row.append(p)
48
+ rows.append(row)
49
+
50
+ pretty_print_table(rows)
51
+
52
+
30
53
  def report(self, save=None):
31
54
  import matplotlib.pyplot as plt
32
55
  import matplotlib.gridspec as gridspec
arvi/simbad_wrapper.py CHANGED
@@ -3,6 +3,8 @@ import requests
3
3
 
4
4
  import pysweetcat
5
5
 
6
+ from .translations import translate
7
+
6
8
  DATA_PATH = os.path.dirname(__file__)
7
9
  DATA_PATH = os.path.join(DATA_PATH, 'data')
8
10
 
@@ -98,7 +100,7 @@ class simbad:
98
100
  """
99
101
  from astropy.coordinates import SkyCoord
100
102
 
101
- self.star = star
103
+ self.star = translate(star, ngc=True, ic=True)
102
104
 
103
105
  if 'kobe' in self.star.lower():
104
106
  fname = os.path.join(DATA_PATH, 'KOBE-translate.csv')
@@ -108,19 +110,22 @@ class simbad:
108
110
  for line in f.readlines():
109
111
  kobe_id, catname = line.strip().split(',')
110
112
  kobe_translate[kobe_id] = catname
111
- self.star = star = kobe_translate[self.star]
113
+ try:
114
+ self.star = star = kobe_translate[self.star]
115
+ except KeyError:
116
+ raise ValueError(f'simbad query for {star} failed')
112
117
 
113
118
  # oid = run_query(query=OID_QUERY.format(star=star))
114
119
  # self.oid = str(oid.split()[-1])
115
120
 
116
121
  try:
117
- table1 = run_query(query=QUERY.format(star=star))
122
+ table1 = run_query(query=QUERY.format(star=self.star))
118
123
  cols, values = parse_table(table1)
119
124
 
120
- table2 = run_query(query=BV_QUERY.format(star=star))
125
+ table2 = run_query(query=BV_QUERY.format(star=self.star))
121
126
  cols, values = parse_table(table2, cols, values)
122
127
 
123
- table3 = run_query(query=IDS_QUERY.format(star=star))
128
+ table3 = run_query(query=IDS_QUERY.format(star=self.star))
124
129
  line = table3.splitlines()[2]
125
130
  self.ids = line.replace('"', '').replace(' ', ' ').replace(' ', ' ').replace(' ', ' ').split('|')
126
131
  except IndexError:
arvi/stellar.py CHANGED
@@ -1,22 +1,32 @@
1
+
1
2
  import numpy as np
2
3
 
3
4
  class prot_age_result:
4
- prot_n84: float
5
- prot_n84_err: float
6
- prot_m08: float
7
- prot_m08_err: float
8
- age_m08: float
9
- age_m08_err: float
5
+ prot_n84 = None #: float | np.ndarray
6
+ prot_n84_err = None #: float | np.ndarray
7
+ prot_m08 = None #: float | np.ndarray
8
+ prot_m08_err = None #: float | np.ndarray
9
+ age_m08 = None #: float | np.ndarray
10
+ age_m08_err = None #: float | np.ndarray
10
11
  def __init__(self):
11
12
  pass
12
13
  def __repr__(self):
13
- s = f'{self.prot_n84=:.2f} ± {self.prot_n84_err:.2f}, '
14
- s += f'{self.prot_m08=:.2f} ± {self.prot_m08_err:.2f}, '
15
- s += f'{self.age_m08=:.2f} ± {self.age_m08_err:.2f}'
14
+ if isinstance(self.prot_n84, np.ndarray):
15
+ s = f'{self.prot_n84.mean()=:.2f} ± {self.prot_n84_err.mean():.2f}, '
16
+ else:
17
+ s = f'{self.prot_n84=:.2f} ± {self.prot_n84_err:.2f}, '
18
+ if isinstance(self.prot_m08, np.ndarray):
19
+ s += f'{self.prot_m08.mean()=:.2f} ± {self.prot_m08_err.mean():.2f}, '
20
+ else:
21
+ s += f'{self.prot_m08=:.2f} ± {self.prot_m08_err:.2f}, '
22
+ if isinstance(self.age_m08, np.ndarray):
23
+ s += f'{self.age_m08.mean()=:.2f} ± {self.age_m08_err.mean():.2f}'
24
+ else:
25
+ s += f'{self.age_m08=:.2f} ± {self.age_m08_err:.2f}'
16
26
  return s.replace('self.', '')
17
27
 
18
28
 
19
- def calc_prot_age(self, bv=None):
29
+ def calc_prot_age(self, bv=None, array=False):
20
30
  """
21
31
  Calculate rotation period and age from logR'HK activity level, based on the
22
32
  empirical relations of Noyes et al. (1984) and Mamajek & Hillenbrand (2008).
@@ -46,7 +56,12 @@ def calc_prot_age(self, bv=None):
46
56
  Range of logR'HK-Prot relation: -5.5 < logR'HK < -4.3
47
57
  Range of Mamajek & Hillenbrand (2008) relation for ages: 0.5 < B-V < 0.9
48
58
  """
49
- log_rhk = np.nanmean(self.rhk[self.mask])
59
+
60
+ if array:
61
+ log_rhk = self.rhk[~np.isnan(self.rhk)]
62
+ else:
63
+ log_rhk = np.nanmean(self.rhk[self.mask])
64
+
50
65
  if bv is None:
51
66
  bv = self.simbad.B - self.simbad.V
52
67
 
@@ -60,9 +75,13 @@ def calc_prot_age(self, bv=None):
60
75
  prot_n84 = 0.324 - 0.400*(5 + log_rhk) - 0.283*(5 + log_rhk)**2 - 1.325*(5 + log_rhk)**3 + tau
61
76
  prot_n84 = 10**prot_n84
62
77
  prot_n84_err = np.log(10)*0.08*prot_n84
78
+ if array:
79
+ prot_n84_err = np.full_like(log_rhk, prot_n84_err)
63
80
 
64
81
  prot_m08 = (0.808 - 2.966*(log_rhk + 4.52))*10**tau
65
82
  prot_m08_err = 4.4*bv*1.7 - 1.7
83
+ if array:
84
+ prot_m08_err = np.full_like(log_rhk, prot_m08_err)
66
85
  else:
67
86
  prot_n84 = np.nan
68
87
  prot_n84_err = np.nan