arvi 0.1.5__tar.gz → 0.1.6__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.
Potentially problematic release.
This version of arvi might be problematic. Click here for more details.
- {arvi-0.1.5 → arvi-0.1.6}/PKG-INFO +1 -13
- {arvi-0.1.5 → arvi-0.1.6}/README.md +1 -13
- {arvi-0.1.5 → arvi-0.1.6}/arvi/dace_wrapper.py +9 -1
- {arvi-0.1.5 → arvi-0.1.6}/arvi/plots.py +1 -1
- {arvi-0.1.5 → arvi-0.1.6}/arvi/timeseries.py +105 -47
- {arvi-0.1.5 → arvi-0.1.6}/arvi.egg-info/PKG-INFO +1 -13
- {arvi-0.1.5 → arvi-0.1.6}/pyproject.toml +1 -1
- {arvi-0.1.5 → arvi-0.1.6}/.github/workflows/docs-gh-pages.yml +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/.github/workflows/install.yml +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/.github/workflows/python-publish.yml +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/.gitignore +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/LICENSE +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/__init__.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/binning.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/config.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/data/info.svg +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/data/obs_affected_ADC_issues.dat +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/data/obs_affected_blue_cryostat_issues.dat +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/instrument_specific.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/lbl_wrapper.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/nasaexo_wrapper.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/programs.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/reports.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/setup_logger.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/simbad_wrapper.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/stats.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/translations.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi/utils.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi.egg-info/SOURCES.txt +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi.egg-info/dependency_links.txt +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi.egg-info/requires.txt +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/arvi.egg-info/top_level.txt +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/docs/API.md +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/docs/detailed.md +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/docs/index.md +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/docs/logo/detective.png +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/docs/logo/logo.png +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/mkdocs.yml +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/setup.cfg +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/setup.py +0 -0
- {arvi-0.1.5 → arvi-0.1.6}/tests/test_import_object.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: arvi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: The Automated RV Inspector
|
|
5
5
|
Author-email: João Faria <joao.faria@unige.ch>
|
|
6
6
|
License: MIT
|
|
@@ -29,18 +29,6 @@ Requires-Dist: kepmodel
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
## Goals
|
|
33
|
-
|
|
34
|
-
- _Fast_:
|
|
35
|
-
all `arvi` operations must be completed in under **1 second**
|
|
36
|
-
|
|
37
|
-
- _Reproducible_:
|
|
38
|
-
**everyone** must be able to use `arvi`
|
|
39
|
-
|
|
40
|
-
- _Accurate_:
|
|
41
|
-
`arvi` must always provide the **correct result**
|
|
42
|
-
|
|
43
|
-
|
|
44
32
|
#### Actions
|
|
45
33
|
|
|
46
34
|
[](https://github.com/j-faria/arvi/actions/workflows/docs-gh-pages.yml)
|
|
@@ -4,20 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
## Goals
|
|
8
|
-
|
|
9
|
-
- _Fast_:
|
|
10
|
-
all `arvi` operations must be completed in under **1 second**
|
|
11
|
-
|
|
12
|
-
- _Reproducible_:
|
|
13
|
-
**everyone** must be able to use `arvi`
|
|
14
|
-
|
|
15
|
-
- _Accurate_:
|
|
16
|
-
`arvi` must always provide the **correct result**
|
|
17
|
-
|
|
18
|
-
|
|
19
7
|
#### Actions
|
|
20
8
|
|
|
21
9
|
[](https://github.com/j-faria/arvi/actions/workflows/docs-gh-pages.yml)
|
|
22
10
|
[](https://github.com/j-faria/arvi/actions/workflows/install.yml)
|
|
23
|
-
[](https://github.com/j-faria/arvi/actions/workflows/python-publish.yml)
|
|
11
|
+
[](https://github.com/j-faria/arvi/actions/workflows/python-publish.yml)
|
|
@@ -152,14 +152,22 @@ def get_observations(star, instrument=None, save_rdb=False, verbose=True):
|
|
|
152
152
|
|
|
153
153
|
def check_existing(output_directory, files, type):
|
|
154
154
|
existing = [
|
|
155
|
-
f.partition('
|
|
155
|
+
f.partition('.fits')[0] for f in os.listdir(output_directory)
|
|
156
156
|
if type in f
|
|
157
157
|
]
|
|
158
|
+
if os.name == 'nt': # on Windows, be careful with ':' in filename
|
|
159
|
+
import re
|
|
160
|
+
existing = [re.sub(r'T(\d+)_(\d+)_(\d+)', r'T\1:\2:\3', f) for f in existing]
|
|
161
|
+
|
|
162
|
+
# remove type of file (e.g. _CCF_A)
|
|
163
|
+
existing = [f.partition('_')[0] for f in existing]
|
|
164
|
+
|
|
158
165
|
missing = []
|
|
159
166
|
for file in files:
|
|
160
167
|
if any(other in file for other in existing):
|
|
161
168
|
continue
|
|
162
169
|
missing.append(file)
|
|
170
|
+
|
|
163
171
|
return np.array(missing)
|
|
164
172
|
|
|
165
173
|
def download(files, type, output_directory):
|
|
@@ -272,7 +272,7 @@ def gls(self, ax=None, label=None, fap=True, picker=True, instrument=None, **kwa
|
|
|
272
272
|
y = self.vrad[self.mask]
|
|
273
273
|
e = self.svrad[self.mask]
|
|
274
274
|
|
|
275
|
-
gls = LombScargle(t, y, e)
|
|
275
|
+
self._gls = gls = LombScargle(t, y, e)
|
|
276
276
|
freq, power = gls.autopower(maximum_frequency=1.0, samples_per_peak=10)
|
|
277
277
|
ax.semilogx(1/freq, power, picker=picker, label=label, **kwargs)
|
|
278
278
|
|
|
@@ -294,9 +294,9 @@ class RV:
|
|
|
294
294
|
star, timestamp = file.replace('.pkl', '').split('_')
|
|
295
295
|
else:
|
|
296
296
|
try:
|
|
297
|
-
file = sorted(glob(f'{star}*.pkl'))[-1]
|
|
297
|
+
file = sorted(glob(f'{star}_*.pkl'))[-1]
|
|
298
298
|
except IndexError:
|
|
299
|
-
raise ValueError(f'cannot find any file matching {star}*.pkl')
|
|
299
|
+
raise ValueError(f'cannot find any file matching {star}_*.pkl')
|
|
300
300
|
star, timestamp = file.replace('.pkl', '').split('_')
|
|
301
301
|
|
|
302
302
|
dt = datetime.fromtimestamp(float(timestamp))
|
|
@@ -314,7 +314,7 @@ class RV:
|
|
|
314
314
|
logger.info(f'assuming star is {star_[0]}')
|
|
315
315
|
star = star_[0]
|
|
316
316
|
|
|
317
|
-
instruments = np.
|
|
317
|
+
instruments = np.array([os.path.splitext(f)[0].split('_')[1] for f in files])
|
|
318
318
|
logger.info(f'assuming instruments: {instruments}')
|
|
319
319
|
|
|
320
320
|
if instruments.size == 1 and len(files) > 1:
|
|
@@ -508,18 +508,19 @@ class RV:
|
|
|
508
508
|
extracted_files = do_download_s2d(files[:limit], directory)
|
|
509
509
|
|
|
510
510
|
|
|
511
|
-
from .plots import plot, plot_fwhm, plot_bis, plot_rhk
|
|
511
|
+
from .plots import plot, plot_fwhm, plot_bis, plot_rhk, plot_quantity
|
|
512
512
|
from .plots import gls, gls_fwhm, gls_bis, gls_rhk
|
|
513
513
|
from .reports import report
|
|
514
514
|
|
|
515
515
|
from .instrument_specific import known_issues
|
|
516
516
|
|
|
517
517
|
|
|
518
|
-
def remove_instrument(self, instrument):
|
|
518
|
+
def remove_instrument(self, instrument, strict=False):
|
|
519
519
|
""" Remove all observations from one instrument
|
|
520
520
|
|
|
521
521
|
Args:
|
|
522
522
|
instrument (str): The instrument for which to remove observations.
|
|
523
|
+
strict (bool): Whether to match `instrument` exactly
|
|
523
524
|
|
|
524
525
|
Note:
|
|
525
526
|
A common name can be used to remove observations for several subsets
|
|
@@ -538,34 +539,37 @@ class RV:
|
|
|
538
539
|
|
|
539
540
|
will remove observations from the specific subset.
|
|
540
541
|
"""
|
|
541
|
-
|
|
542
|
+
instruments = self._check_instrument(instrument, strict)
|
|
543
|
+
|
|
544
|
+
if instruments is None:
|
|
542
545
|
logger.error(f"No data from instrument '{instrument}'")
|
|
543
546
|
logger.info(f'available: {self.instruments}')
|
|
544
547
|
return
|
|
545
548
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
549
|
+
for instrument in instruments:
|
|
550
|
+
ind = self.instruments.index(instrument) + 1
|
|
551
|
+
remove = np.where(self.obs == ind)
|
|
552
|
+
self.obs = np.delete(self.obs, remove)
|
|
553
|
+
self.obs[self.obs > ind] -= 1
|
|
554
|
+
#
|
|
555
|
+
self.time = np.delete(self.time, remove)
|
|
556
|
+
self.vrad = np.delete(self.vrad, remove)
|
|
557
|
+
self.svrad = np.delete(self.svrad, remove)
|
|
558
|
+
#
|
|
559
|
+
self.mask = np.delete(self.mask, remove)
|
|
560
|
+
#
|
|
561
|
+
# all other quantities
|
|
562
|
+
for q in self._quantities:
|
|
563
|
+
if q not in ('rjd', 'rv', 'rv_err'):
|
|
564
|
+
new = np.delete(getattr(self, q), remove)
|
|
565
|
+
setattr(self, q, new)
|
|
566
|
+
#
|
|
567
|
+
self.instruments.remove(instrument)
|
|
568
|
+
#
|
|
569
|
+
delattr(self, instrument)
|
|
566
570
|
|
|
567
|
-
|
|
568
|
-
|
|
571
|
+
if self.verbose:
|
|
572
|
+
logger.info(f"Removed observations from '{instrument}'")
|
|
569
573
|
|
|
570
574
|
if return_self:
|
|
571
575
|
return self
|
|
@@ -610,6 +614,30 @@ class RV:
|
|
|
610
614
|
if getattr(self, inst).mtime.size == 1:
|
|
611
615
|
self.remove_instrument(inst)
|
|
612
616
|
|
|
617
|
+
def remove_prog_id(self, prog_id):
|
|
618
|
+
from glob import has_magic
|
|
619
|
+
if has_magic(prog_id):
|
|
620
|
+
from fnmatch import filter
|
|
621
|
+
matching = np.unique(filter(self.prog_id, prog_id))
|
|
622
|
+
mask = np.full_like(self.time, False, dtype=bool)
|
|
623
|
+
for m in matching:
|
|
624
|
+
mask |= np.isin(self.prog_id, m)
|
|
625
|
+
ind = np.where(mask)[0]
|
|
626
|
+
self.remove_point(ind)
|
|
627
|
+
else:
|
|
628
|
+
if prog_id in self.prog_id:
|
|
629
|
+
ind = np.where(self.prog_id == prog_id)[0]
|
|
630
|
+
self.remove_point(ind)
|
|
631
|
+
else:
|
|
632
|
+
if self.verbose:
|
|
633
|
+
logger.warning(f'no observations for prog_id "{prog_id}"')
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
def remove_after_bjd(self, bjd):
|
|
637
|
+
if (self.time > bjd).any():
|
|
638
|
+
ind = np.where(self.time > bjd)[0]
|
|
639
|
+
self.remove_point(ind)
|
|
640
|
+
|
|
613
641
|
|
|
614
642
|
def _propagate_mask_changes(self):
|
|
615
643
|
""" link self.mask with each self.`instrument`.mask """
|
|
@@ -763,31 +791,38 @@ class RV:
|
|
|
763
791
|
bad_quantities = []
|
|
764
792
|
|
|
765
793
|
for q in s._quantities:
|
|
794
|
+
Q = getattr(s, q)
|
|
795
|
+
|
|
766
796
|
# treat date_night specially, basically doing a group-by
|
|
767
797
|
if q == 'date_night':
|
|
768
798
|
inds = binRV(s.mtime, None, None, binning_indices=True)
|
|
769
|
-
setattr(s, q,
|
|
799
|
+
setattr(s, q, Q[s.mask][inds])
|
|
770
800
|
continue
|
|
771
801
|
|
|
772
|
-
if
|
|
802
|
+
if Q.dtype != np.float64:
|
|
773
803
|
bad_quantities.append(q)
|
|
774
804
|
all_bad_quantities.append(q)
|
|
775
805
|
continue
|
|
776
806
|
|
|
777
|
-
if np.isnan(
|
|
807
|
+
if np.isnan(Q).all():
|
|
778
808
|
yb = np.full_like(tb, np.nan)
|
|
779
809
|
setattr(s, q, yb)
|
|
810
|
+
|
|
780
811
|
elif q + '_err' in s._quantities:
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
812
|
+
Qerr = getattr(s, q + '_err')
|
|
813
|
+
if (Qerr == 0.0).all():
|
|
814
|
+
_, yb = binRV(s.mtime, Q[s.mask], stat='mean', tstat='mean')
|
|
815
|
+
else:
|
|
816
|
+
_, yb, eb = binRV(s.mtime, Q[s.mask], Qerr[s.mask])
|
|
817
|
+
setattr(s, q + '_err', eb)
|
|
818
|
+
|
|
784
819
|
setattr(s, q, yb)
|
|
785
|
-
|
|
820
|
+
|
|
786
821
|
elif not q.endswith('_err'):
|
|
787
822
|
with warnings.catch_warnings():
|
|
788
823
|
warnings.filterwarnings('ignore', category=RuntimeWarning)
|
|
789
824
|
try:
|
|
790
|
-
_, yb = binRV(s.mtime,
|
|
825
|
+
_, yb = binRV(s.mtime, Q[s.mask],
|
|
791
826
|
stat=np.nanmean, tstat=np.nanmean)
|
|
792
827
|
setattr(s, q, yb)
|
|
793
828
|
except TypeError:
|
|
@@ -820,13 +855,26 @@ class RV:
|
|
|
820
855
|
return np.nanmean(z, axis=0)
|
|
821
856
|
|
|
822
857
|
def subtract_mean(self):
|
|
823
|
-
|
|
858
|
+
""" Subtract (single) mean RV from all instruments """
|
|
859
|
+
self._meanRV = meanRV = self.mvrad.mean()
|
|
824
860
|
for inst in self.instruments:
|
|
825
861
|
s = getattr(self, inst)
|
|
826
862
|
s.vrad -= meanRV
|
|
827
863
|
self._build_arrays()
|
|
828
864
|
|
|
865
|
+
def _add_back_mean(self):
|
|
866
|
+
""" Add the (single) mean RV removed by self.subtract_mean() """
|
|
867
|
+
if not hasattr(self, '_meanRV'):
|
|
868
|
+
logger.warning("no mean RV stored, run 'self.subtract_mean()'")
|
|
869
|
+
return
|
|
870
|
+
|
|
871
|
+
for inst in self.instruments:
|
|
872
|
+
s = getattr(self, inst)
|
|
873
|
+
s.vrad += self._meanRV
|
|
874
|
+
self._build_arrays()
|
|
875
|
+
|
|
829
876
|
def adjust_means(self, just_rv=False):
|
|
877
|
+
""" Subtract individual mean RVs from each instrument """
|
|
830
878
|
if self._child or self._did_adjust_means:
|
|
831
879
|
return
|
|
832
880
|
|
|
@@ -877,9 +925,14 @@ class RV:
|
|
|
877
925
|
changed = False
|
|
878
926
|
for inst in self.instruments:
|
|
879
927
|
s = getattr(self, inst)
|
|
880
|
-
if
|
|
881
|
-
s.
|
|
882
|
-
|
|
928
|
+
if s.mask.any():
|
|
929
|
+
if np.abs(s.mvrad.mean()) < s.mvrad.ptp():
|
|
930
|
+
s.vrad += self.simbad.rvz_radvel * 1e3
|
|
931
|
+
changed = True
|
|
932
|
+
else: # all observations are masked, use non-masked arrays
|
|
933
|
+
if np.abs(s.vrad.mean()) < s.vrad.ptp():
|
|
934
|
+
s.vrad += self.simbad.rvz_radvel * 1e3
|
|
935
|
+
changed = True
|
|
883
936
|
if changed:
|
|
884
937
|
self._build_arrays()
|
|
885
938
|
|
|
@@ -913,6 +966,11 @@ class RV:
|
|
|
913
966
|
"""
|
|
914
967
|
star_name = self.star.replace(' ', '')
|
|
915
968
|
|
|
969
|
+
if directory is None:
|
|
970
|
+
directory = '.'
|
|
971
|
+
else:
|
|
972
|
+
os.makedirs(directory, exist_ok=True)
|
|
973
|
+
|
|
916
974
|
files = []
|
|
917
975
|
|
|
918
976
|
for inst in self.instruments:
|
|
@@ -920,15 +978,11 @@ class RV:
|
|
|
920
978
|
if instrument not in inst:
|
|
921
979
|
continue
|
|
922
980
|
|
|
923
|
-
file = f'{star_name}_{inst}.rdb'
|
|
924
|
-
files.append(file)
|
|
925
|
-
|
|
926
|
-
if directory is not None:
|
|
927
|
-
os.makedirs(directory, exist_ok=True)
|
|
928
|
-
file = os.path.join(directory, file)
|
|
929
|
-
|
|
930
981
|
_s = getattr(self, inst)
|
|
931
982
|
|
|
983
|
+
if not _s.mask.any(): # all observations are masked, don't save
|
|
984
|
+
continue
|
|
985
|
+
|
|
932
986
|
if full:
|
|
933
987
|
d = np.c_[
|
|
934
988
|
_s.mtime, _s.mvrad, _s.msvrad,
|
|
@@ -941,6 +995,10 @@ class RV:
|
|
|
941
995
|
d = np.c_[_s.mtime, _s.mvrad, _s.msvrad]
|
|
942
996
|
header = 'bjd\tvrad\tsvrad\n---\t----\t-----'
|
|
943
997
|
|
|
998
|
+
file = f'{star_name}_{inst}.rdb'
|
|
999
|
+
files.append(file)
|
|
1000
|
+
file = os.path.join(directory, file)
|
|
1001
|
+
|
|
944
1002
|
np.savetxt(file, d, fmt='%9.5f', header=header, delimiter='\t', comments='')
|
|
945
1003
|
|
|
946
1004
|
if self.verbose:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: arvi
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: The Automated RV Inspector
|
|
5
5
|
Author-email: João Faria <joao.faria@unige.ch>
|
|
6
6
|
License: MIT
|
|
@@ -29,18 +29,6 @@ Requires-Dist: kepmodel
|
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
|
|
32
|
-
## Goals
|
|
33
|
-
|
|
34
|
-
- _Fast_:
|
|
35
|
-
all `arvi` operations must be completed in under **1 second**
|
|
36
|
-
|
|
37
|
-
- _Reproducible_:
|
|
38
|
-
**everyone** must be able to use `arvi`
|
|
39
|
-
|
|
40
|
-
- _Accurate_:
|
|
41
|
-
`arvi` must always provide the **correct result**
|
|
42
|
-
|
|
43
|
-
|
|
44
32
|
#### Actions
|
|
45
33
|
|
|
46
34
|
[](https://github.com/j-faria/arvi/actions/workflows/docs-gh-pages.yml)
|
|
@@ -8,7 +8,7 @@ authors = [
|
|
|
8
8
|
{name = "João Faria", email = "joao.faria@unige.ch"},
|
|
9
9
|
]
|
|
10
10
|
description = "The Automated RV Inspector"
|
|
11
|
-
version = "0.1.
|
|
11
|
+
version = "0.1.6"
|
|
12
12
|
readme = {file = "README.md", content-type = "text/markdown"}
|
|
13
13
|
requires-python = ">=3.8"
|
|
14
14
|
keywords = ["RV", "exoplanets"]
|
|
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
|