arvi 0.2.5__py3-none-any.whl → 0.2.7__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/dace_wrapper.py +18 -9
- arvi/gaia_wrapper.py +2 -2
- arvi/instrument_specific.py +1 -8
- arvi/simbad_wrapper.py +18 -0
- arvi/sophie_wrapper.py +111 -0
- arvi/timeseries.py +223 -83
- arvi/utils.py +5 -2
- {arvi-0.2.5.dist-info → arvi-0.2.7.dist-info}/METADATA +1 -1
- {arvi-0.2.5.dist-info → arvi-0.2.7.dist-info}/RECORD +12 -11
- {arvi-0.2.5.dist-info → arvi-0.2.7.dist-info}/WHEEL +0 -0
- {arvi-0.2.5.dist-info → arvi-0.2.7.dist-info}/licenses/LICENSE +0 -0
- {arvi-0.2.5.dist-info → arvi-0.2.7.dist-info}/top_level.txt +0 -0
arvi/dace_wrapper.py
CHANGED
|
@@ -2,7 +2,7 @@ import os
|
|
|
2
2
|
import sys
|
|
3
3
|
import tarfile
|
|
4
4
|
import collections
|
|
5
|
-
from functools import lru_cache
|
|
5
|
+
from functools import lru_cache, partial
|
|
6
6
|
from itertools import islice
|
|
7
7
|
import numpy as np
|
|
8
8
|
|
|
@@ -170,7 +170,7 @@ def get_observations_from_instrument(star, instrument, user=None, main_id=None,
|
|
|
170
170
|
"""
|
|
171
171
|
Spectroscopy = load_spectroscopy(user)
|
|
172
172
|
found_dace_id = False
|
|
173
|
-
with timer('
|
|
173
|
+
with timer('dace_id query'):
|
|
174
174
|
try:
|
|
175
175
|
dace_id = get_dace_id(star, verbose=verbose, raise_error=True)
|
|
176
176
|
found_dace_id = True
|
|
@@ -212,17 +212,22 @@ def get_observations_from_instrument(star, instrument, user=None, main_id=None,
|
|
|
212
212
|
|
|
213
213
|
for inst in np.unique(result['ins_name']):
|
|
214
214
|
mask1 = result['ins_name'] == inst
|
|
215
|
-
r[inst] = {}
|
|
215
|
+
r[str(inst)] = {}
|
|
216
216
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
217
|
+
key2 = 'ins_drs_version'
|
|
218
|
+
n_key2 = len(np.unique(result[key2][mask1]))
|
|
219
|
+
if len(np.unique(result['pub_bibcode'][mask1])) >= n_key2:
|
|
220
|
+
key2 = 'pub_bibcode'
|
|
221
|
+
|
|
222
|
+
for pipe in np.unique(result[key2][mask1]):
|
|
223
|
+
mask2 = mask1 & (result[key2] == pipe)
|
|
224
|
+
r[str(inst)][str(pipe)] = {}
|
|
220
225
|
|
|
221
226
|
for ins_mode in np.unique(result['ins_mode'][mask2]):
|
|
222
227
|
mask3 = mask2 & (result['ins_mode'] == ins_mode)
|
|
223
228
|
_nan = np.full(mask3.sum(), np.nan)
|
|
224
229
|
|
|
225
|
-
r[inst][pipe][ins_mode] = {
|
|
230
|
+
r[str(inst)][str(pipe)][str(ins_mode)] = {
|
|
226
231
|
'texp': result['texp'][mask3],
|
|
227
232
|
'bispan': result['spectro_ccf_bispan'][mask3],
|
|
228
233
|
'bispan_err': result['spectro_ccf_bispan_err'][mask3],
|
|
@@ -372,9 +377,11 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
372
377
|
# # For all other strings, sort alphabetically
|
|
373
378
|
# return (2, s)
|
|
374
379
|
|
|
375
|
-
def custom_key(val):
|
|
380
|
+
def custom_key(val, strip_EGGS=False):
|
|
381
|
+
if strip_EGGS:
|
|
382
|
+
val = val.replace('-EGGS', '').replace(' EGGS', '')
|
|
376
383
|
key = 0
|
|
377
|
-
key -=
|
|
384
|
+
key -= 1 if '3.5' in val else 0
|
|
378
385
|
key -= 1 if 'EGGS' in val else 0
|
|
379
386
|
key -= 1 if ('UHR' in val or 'MR' in val) else 0
|
|
380
387
|
key -= 1 if 'LBL' in val else 0
|
|
@@ -385,6 +392,8 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
385
392
|
# new_result[inst] = dict(
|
|
386
393
|
# sorted(result[inst].items(), key=custom_sort_key, reverse=True)
|
|
387
394
|
# )
|
|
395
|
+
if all(['EGGS' in k for k in result[inst].keys()]):
|
|
396
|
+
custom_key = partial(custom_key, strip_EGGS=True)
|
|
388
397
|
# WARNING: not the same as reverse=True (not sure why)
|
|
389
398
|
sorted_keys = sorted(result[inst].keys(), key=custom_key)[::-1]
|
|
390
399
|
new_result[inst] = {}
|
arvi/gaia_wrapper.py
CHANGED
|
@@ -3,8 +3,6 @@ from io import StringIO
|
|
|
3
3
|
from csv import DictReader
|
|
4
4
|
import requests
|
|
5
5
|
|
|
6
|
-
from astropy.coordinates import SkyCoord
|
|
7
|
-
|
|
8
6
|
DATA_PATH = os.path.dirname(__file__)
|
|
9
7
|
DATA_PATH = os.path.join(DATA_PATH, 'data')
|
|
10
8
|
|
|
@@ -78,6 +76,8 @@ class gaia:
|
|
|
78
76
|
Args:
|
|
79
77
|
star (str): The name of the star to query simbad
|
|
80
78
|
"""
|
|
79
|
+
from astropy.coordinates import SkyCoord
|
|
80
|
+
|
|
81
81
|
self.star = star
|
|
82
82
|
|
|
83
83
|
if simbad is None:
|
arvi/instrument_specific.py
CHANGED
|
@@ -107,14 +107,7 @@ def divide_HARPS(self):
|
|
|
107
107
|
|
|
108
108
|
|
|
109
109
|
def check(self, instrument):
|
|
110
|
-
|
|
111
|
-
instruments = self._check_instrument(instrument)
|
|
112
|
-
if instruments is None:
|
|
113
|
-
if self.verbose:
|
|
114
|
-
logger.error(f"HARPS_fiber_commissioning: no data from {instrument}")
|
|
115
|
-
return None
|
|
116
|
-
return instruments
|
|
117
|
-
|
|
110
|
+
return self._check_instrument(instrument)
|
|
118
111
|
|
|
119
112
|
# HARPS commissioning
|
|
120
113
|
def HARPS_commissioning(self, mask=True, plot=True):
|
arvi/simbad_wrapper.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import requests
|
|
3
3
|
from dataclasses import dataclass
|
|
4
|
+
from functools import partial
|
|
4
5
|
|
|
5
6
|
import numpy as np
|
|
6
7
|
|
|
@@ -63,6 +64,23 @@ JOIN ident ON oidref = oid
|
|
|
63
64
|
WHERE id = '{star}';
|
|
64
65
|
"""
|
|
65
66
|
|
|
67
|
+
HD_GJ_HIP_QUERY = """
|
|
68
|
+
SELECT id2.id
|
|
69
|
+
FROM ident AS id1 JOIN ident AS id2 USING(oidref)
|
|
70
|
+
WHERE id1.id = '{star}' AND id2.id LIKE '{name}%';
|
|
71
|
+
"""
|
|
72
|
+
|
|
73
|
+
def find_identifier(identifier, star):
|
|
74
|
+
response = run_query(HD_GJ_HIP_QUERY.format(name=identifier, star=star))
|
|
75
|
+
if identifier in response:
|
|
76
|
+
return response.split('"')[1]
|
|
77
|
+
raise ValueError(f'no {identifier} identifier found for "{star}"')
|
|
78
|
+
|
|
79
|
+
find_HD = partial(find_identifier, 'HD')
|
|
80
|
+
find_GJ = partial(find_identifier, 'GJ')
|
|
81
|
+
find_HIP = partial(find_identifier, 'HIP')
|
|
82
|
+
|
|
83
|
+
|
|
66
84
|
@dataclass
|
|
67
85
|
class Measurements:
|
|
68
86
|
teff: list
|
arvi/sophie_wrapper.py
ADDED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
from multiprocessing.pool import ThreadPool
|
|
2
|
+
import re
|
|
3
|
+
import requests
|
|
4
|
+
from io import StringIO
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
from .setup_logger import setup_logger
|
|
9
|
+
|
|
10
|
+
URL_CCF = "http://atlas.obs-hp.fr/sophie/sophie.cgi?n=sophiecc&ob=date&a=t&o={target}"
|
|
11
|
+
URL_HEADER = "http://atlas.obs-hp.fr/sophie/sophie.cgi?n=sophiecc&c=i&z=fd&a=t&o=sophie:[ccf,{seq},{mask},0]"
|
|
12
|
+
|
|
13
|
+
def extract_keyword(keyword, text, raise_error=True):
|
|
14
|
+
for line in text.splitlines():
|
|
15
|
+
if keyword in line:
|
|
16
|
+
value = re.findall(fr'{keyword}\s+([\'\w\d.]+)', line)[0]
|
|
17
|
+
value = value.replace("'", "")
|
|
18
|
+
try:
|
|
19
|
+
return float(value)
|
|
20
|
+
except ValueError:
|
|
21
|
+
return value
|
|
22
|
+
if raise_error:
|
|
23
|
+
raise KeyError(f'Keyword {keyword} not found')
|
|
24
|
+
|
|
25
|
+
def query_sophie_archive(star: str, verbose=True):
|
|
26
|
+
from .timeseries import RV
|
|
27
|
+
logger = setup_logger()
|
|
28
|
+
|
|
29
|
+
resp = requests.get(URL_CCF.format(target=star))
|
|
30
|
+
if 'leda did not return a position for the name' in resp.text:
|
|
31
|
+
raise ValueError(f'no SOPHIE observations for {star}')
|
|
32
|
+
|
|
33
|
+
data = np.genfromtxt(StringIO(resp.text), dtype=None, usecols=(0, 4),
|
|
34
|
+
names=("seq", "mask"))
|
|
35
|
+
|
|
36
|
+
if verbose:
|
|
37
|
+
logger.info(f'found {len(data)} SOPHIE observations for {star}')
|
|
38
|
+
|
|
39
|
+
urls = [URL_HEADER.format(seq=seq, mask=mask) for seq, mask in data]
|
|
40
|
+
with ThreadPool(8) as pool:
|
|
41
|
+
responses = pool.map(requests.get, urls)
|
|
42
|
+
|
|
43
|
+
bjd, vrad, svrad = [], [], []
|
|
44
|
+
fwhm, contrast = [], []
|
|
45
|
+
ccf_mask = []
|
|
46
|
+
_quantities = []
|
|
47
|
+
errors = []
|
|
48
|
+
|
|
49
|
+
for i, resp in enumerate(responses):
|
|
50
|
+
if resp.text == '':
|
|
51
|
+
errors.append(i)
|
|
52
|
+
continue
|
|
53
|
+
|
|
54
|
+
try:
|
|
55
|
+
t, v = map(lambda k: extract_keyword(k, resp.text),
|
|
56
|
+
("OHP DRS BJD", "OHP DRS CCF RV"))
|
|
57
|
+
except KeyError:
|
|
58
|
+
errors.append(i)
|
|
59
|
+
continue
|
|
60
|
+
else:
|
|
61
|
+
bjd.append(t)
|
|
62
|
+
vrad.append(v)
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
svrad.append(extract_keyword("OHP DRS CCF ERR", resp.text))
|
|
66
|
+
except KeyError:
|
|
67
|
+
try:
|
|
68
|
+
svrad.append(1e-3 * extract_keyword("OHP DRS DVRMS", resp.text))
|
|
69
|
+
except KeyError:
|
|
70
|
+
bjd.pop(-1)
|
|
71
|
+
vrad.pop(-1)
|
|
72
|
+
errors.append(i)
|
|
73
|
+
continue
|
|
74
|
+
|
|
75
|
+
fwhm.append(extract_keyword('OHP DRS CCF FWHM', resp.text))
|
|
76
|
+
_quantities.append('fwhm')
|
|
77
|
+
|
|
78
|
+
contrast.append(extract_keyword('OHP DRS CCF CONTRAST', resp.text))
|
|
79
|
+
_quantities.append('contrast')
|
|
80
|
+
|
|
81
|
+
ccf_mask.append(extract_keyword('OHP DRS CCF MASK', resp.text))
|
|
82
|
+
_quantities.append('ccf_mask')
|
|
83
|
+
|
|
84
|
+
if len(errors) > 0:
|
|
85
|
+
logger.warning(f'Could not retrieve {len(errors)} observation'
|
|
86
|
+
f'{"s" if len(errors) > 1 else ""}')
|
|
87
|
+
|
|
88
|
+
bjd = np.array(bjd) - 2400000.5
|
|
89
|
+
|
|
90
|
+
s = RV.from_arrays(star, bjd, vrad, svrad, 'SOPHIE',
|
|
91
|
+
fwhm=fwhm, fwhm_err=2*np.array(svrad),
|
|
92
|
+
contrast=contrast,
|
|
93
|
+
ccf_mask=ccf_mask)
|
|
94
|
+
s.units = 'km/s'
|
|
95
|
+
|
|
96
|
+
# strings
|
|
97
|
+
for q in ['date_night', 'prog_id', 'raw_file', 'pub_reference']:
|
|
98
|
+
setattr(s, q, np.full(bjd.size, ''))
|
|
99
|
+
_quantities.append(q)
|
|
100
|
+
|
|
101
|
+
s._quantities = np.array(_quantities)
|
|
102
|
+
|
|
103
|
+
setattr(s, 'SOPHIE', s)
|
|
104
|
+
s._child = False
|
|
105
|
+
s.verbose = False
|
|
106
|
+
s._build_arrays()
|
|
107
|
+
s.change_units('m/s')
|
|
108
|
+
s.verbose = verbose
|
|
109
|
+
|
|
110
|
+
return s
|
|
111
|
+
|
arvi/timeseries.py
CHANGED
|
@@ -40,43 +40,74 @@ class RV(ISSUES, REPORTS):
|
|
|
40
40
|
"""
|
|
41
41
|
A class holding RV observations
|
|
42
42
|
|
|
43
|
+
Args:
|
|
44
|
+
star (str):
|
|
45
|
+
Name of the star
|
|
46
|
+
instrument (str, list):
|
|
47
|
+
Name of the instrument or list of instruments
|
|
48
|
+
verbose (bool):
|
|
49
|
+
Print logging messages
|
|
50
|
+
do_maxerror:
|
|
51
|
+
Mask points based on a maximum RV uncertainty
|
|
52
|
+
do_secular_acceleration:
|
|
53
|
+
Apply secular acceleration correction. This only applies
|
|
54
|
+
to certain instruments.
|
|
55
|
+
do_sigma_clip (bool):
|
|
56
|
+
Apply sigma clipping on the RVs
|
|
57
|
+
do_adjust_means (bool):
|
|
58
|
+
Subtract individual weighted mean RV from each instrument
|
|
59
|
+
only_latest_pipeline (bool):
|
|
60
|
+
Select only the latest pipeline from each instrument
|
|
61
|
+
load_extra_data (bool):
|
|
62
|
+
check_drs_qc (bool):
|
|
63
|
+
Mask points based on DRS quality control flags
|
|
64
|
+
user (str):
|
|
65
|
+
User name for DACE queries (should be a section in `~/.dacerc` file)
|
|
66
|
+
|
|
43
67
|
Examples:
|
|
44
68
|
>>> s = RV('Proxima')
|
|
69
|
+
>>> s = RV('HD10180', instrument='HARPS')
|
|
45
70
|
|
|
46
|
-
Attributes:
|
|
47
|
-
star (str):
|
|
48
|
-
The name of the star
|
|
49
|
-
N (int):
|
|
50
|
-
Total number of observations
|
|
51
|
-
instruments (list):
|
|
52
|
-
List of instruments for which there are RVs. Each instrument is also
|
|
53
|
-
stored as an attribute (e.g. `self.CORALIE98` or `self.HARPS`)
|
|
54
|
-
simbad (simbad):
|
|
55
|
-
Information on the target from Simbad
|
|
56
71
|
"""
|
|
72
|
+
# Attributes:
|
|
73
|
+
# star (str):
|
|
74
|
+
# The name of the star
|
|
75
|
+
# N (int):
|
|
76
|
+
# Total number of observations
|
|
77
|
+
# NN (dict):
|
|
78
|
+
# Number of observations per instrument
|
|
79
|
+
# instruments (list):
|
|
80
|
+
# List of instruments for which there are RVs. Each instrument is also
|
|
81
|
+
# stored as an attribute (e.g. `self.CORALIE98` or `self.HARPS`)
|
|
82
|
+
# simbad (simbad):
|
|
83
|
+
# Information on the target from Simbad
|
|
84
|
+
# gaia (gaia):
|
|
85
|
+
# Information on the target from Gaia DR3
|
|
57
86
|
star: str
|
|
58
87
|
instrument: Union[str, list] = field(init=True, repr=False, default=None)
|
|
59
88
|
verbose: bool = field(init=True, repr=False, default=True)
|
|
60
|
-
do_maxerror:
|
|
89
|
+
do_maxerror: float = field(init=True, repr=False, default=None)
|
|
61
90
|
do_secular_acceleration: bool = field(init=True, repr=False, default=True)
|
|
62
91
|
do_sigma_clip: bool = field(init=True, repr=False, default=False)
|
|
63
92
|
do_adjust_means: bool = field(init=True, repr=False, default=True)
|
|
64
93
|
only_latest_pipeline: bool = field(init=True, repr=False, default=True)
|
|
65
94
|
load_extra_data: Union[bool, str] = field(init=True, repr=False, default=False)
|
|
66
95
|
check_drs_qc: bool = field(init=True, repr=False, default=True)
|
|
67
|
-
|
|
96
|
+
check_sophie_archive: bool = field(init=True, repr=False, default=False)
|
|
97
|
+
user: Union[str, None] = field(init=True, repr=False, default=None)
|
|
68
98
|
#
|
|
69
99
|
units = 'm/s'
|
|
70
100
|
_child: bool = field(init=True, repr=False, default=False)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
101
|
+
#
|
|
102
|
+
_did_secular_acceleration : bool = field(init=False, repr=False, default=False)
|
|
103
|
+
_did_sigma_clip : bool = field(init=False, repr=False, default=False)
|
|
104
|
+
_did_adjust_means : bool = field(init=False, repr=False, default=False)
|
|
105
|
+
_did_simbad_query : bool = field(init=False, repr=False, default=False)
|
|
106
|
+
_did_gaia_query : bool = field(init=False, repr=False, default=False)
|
|
107
|
+
_did_toi_query : bool = field(init=False, repr=False, default=False)
|
|
108
|
+
_raise_on_error : bool = field(init=True, repr=False, default=True)
|
|
109
|
+
__masked_numbers : bool = field(init=False, repr=False, default=False)
|
|
110
|
+
#
|
|
80
111
|
_simbad = None
|
|
81
112
|
_gaia = None
|
|
82
113
|
_toi = None
|
|
@@ -104,7 +135,7 @@ class RV(ISSUES, REPORTS):
|
|
|
104
135
|
|
|
105
136
|
if self._child:
|
|
106
137
|
return None
|
|
107
|
-
|
|
138
|
+
|
|
108
139
|
if self._did_simbad_query:
|
|
109
140
|
return None
|
|
110
141
|
|
|
@@ -215,7 +246,7 @@ class RV(ISSUES, REPORTS):
|
|
|
215
246
|
else:
|
|
216
247
|
mid = None
|
|
217
248
|
|
|
218
|
-
with timer():
|
|
249
|
+
with timer('dace query'):
|
|
219
250
|
self.dace_result = get_observations(self.__star__, self.instrument,
|
|
220
251
|
user=self.user, main_id=mid, verbose=self.verbose)
|
|
221
252
|
except ValueError as e:
|
|
@@ -288,6 +319,21 @@ class RV(ISSUES, REPORTS):
|
|
|
288
319
|
# all other quantities
|
|
289
320
|
self._build_arrays()
|
|
290
321
|
|
|
322
|
+
# self.actin = get_actin_data(self, verbose=self.verbose)
|
|
323
|
+
|
|
324
|
+
|
|
325
|
+
# check for SOPHIE observations
|
|
326
|
+
cond = not self._child
|
|
327
|
+
cond = cond and self.instrument is None
|
|
328
|
+
cond = cond and self.check_sophie_archive
|
|
329
|
+
if cond:
|
|
330
|
+
try:
|
|
331
|
+
from arvi.sophie_wrapper import query_sophie_archive
|
|
332
|
+
self.__add__(query_sophie_archive(self.star, verbose=self.verbose),
|
|
333
|
+
inplace=True)
|
|
334
|
+
except Exception as e:
|
|
335
|
+
print(e)
|
|
336
|
+
|
|
291
337
|
# do clip_maxerror, secular_acceleration, sigmaclip, adjust_means
|
|
292
338
|
if not self._child:
|
|
293
339
|
if self.do_maxerror:
|
|
@@ -301,7 +347,7 @@ class RV(ISSUES, REPORTS):
|
|
|
301
347
|
|
|
302
348
|
if self.do_adjust_means:
|
|
303
349
|
self.adjust_means()
|
|
304
|
-
|
|
350
|
+
|
|
305
351
|
_star_no_space = self.star.replace(' ', '')
|
|
306
352
|
_directory = sanitize_path(_star_no_space)
|
|
307
353
|
self._download_directory = f'{_directory}_downloads'
|
|
@@ -526,7 +572,7 @@ class RV(ISSUES, REPORTS):
|
|
|
526
572
|
return s
|
|
527
573
|
|
|
528
574
|
@classmethod
|
|
529
|
-
def from_arrays(cls, star, time, vrad, svrad, inst,
|
|
575
|
+
def from_arrays(cls, star, time, vrad, svrad, inst, **kwargs):
|
|
530
576
|
s = cls(star, _child=True)
|
|
531
577
|
time, vrad, svrad = map(np.atleast_1d, (time, vrad, svrad))
|
|
532
578
|
|
|
@@ -541,11 +587,15 @@ class RV(ISSUES, REPORTS):
|
|
|
541
587
|
s.time = time
|
|
542
588
|
s.vrad = vrad
|
|
543
589
|
s.svrad = svrad
|
|
544
|
-
|
|
545
|
-
s.mask = kwargs.
|
|
590
|
+
|
|
591
|
+
s.mask = kwargs.pop('mask', np.full_like(s.time, True, dtype=bool))
|
|
592
|
+
s.units = kwargs.pop('units', 'm/s')
|
|
593
|
+
|
|
594
|
+
for k, v in kwargs.items():
|
|
595
|
+
setattr(s, k, np.atleast_1d(v))
|
|
546
596
|
|
|
547
597
|
s.instruments = [inst]
|
|
548
|
-
s._quantities = np.array(
|
|
598
|
+
s._quantities = np.array(list(kwargs.keys()))
|
|
549
599
|
|
|
550
600
|
return s
|
|
551
601
|
|
|
@@ -566,7 +616,7 @@ class RV(ISSUES, REPORTS):
|
|
|
566
616
|
dt = datetime.fromtimestamp(float(timestamp))
|
|
567
617
|
if verbose:
|
|
568
618
|
logger.info(f'reading snapshot of {star} from {dt}')
|
|
569
|
-
|
|
619
|
+
|
|
570
620
|
s = pickle.load(open(file, 'rb'))
|
|
571
621
|
s._snapshot = file
|
|
572
622
|
return s
|
|
@@ -578,7 +628,7 @@ class RV(ISSUES, REPORTS):
|
|
|
578
628
|
|
|
579
629
|
Args:
|
|
580
630
|
files (str, list):
|
|
581
|
-
File name or list of file names
|
|
631
|
+
File name, file object, or list of file names
|
|
582
632
|
star (str, optional):
|
|
583
633
|
Name of the star. If None, try to infer it from file name
|
|
584
634
|
instrument (str, list, optional):
|
|
@@ -589,37 +639,68 @@ class RV(ISSUES, REPORTS):
|
|
|
589
639
|
Number of lines to skip in the header. Defaults to 2.
|
|
590
640
|
|
|
591
641
|
Examples:
|
|
592
|
-
s = RV.from_rdb('star_HARPS.rdb')
|
|
642
|
+
>>> s = RV.from_rdb('star_HARPS.rdb')
|
|
593
643
|
"""
|
|
594
644
|
from glob import glob
|
|
595
645
|
from os.path import splitext, basename
|
|
596
646
|
|
|
597
647
|
verbose = kwargs.pop('verbose', True)
|
|
598
648
|
|
|
649
|
+
file_object = False
|
|
650
|
+
|
|
599
651
|
if isinstance(files, str):
|
|
600
652
|
if '*' in files:
|
|
601
653
|
files = glob(files)
|
|
602
654
|
else:
|
|
603
655
|
files = [files]
|
|
656
|
+
elif isinstance(files, list):
|
|
657
|
+
pass
|
|
658
|
+
else:
|
|
659
|
+
file_object = hasattr(files, 'read')
|
|
660
|
+
files = [files]
|
|
604
661
|
|
|
605
|
-
if len(files) == 0:
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
662
|
+
# if len(files) == 0:
|
|
663
|
+
# if verbose:
|
|
664
|
+
# logger.error('no files found')
|
|
665
|
+
# return
|
|
666
|
+
def get_star_name(file):
|
|
667
|
+
return splitext(basename(file))[0].split('_')[0].replace('-', '_')
|
|
668
|
+
|
|
669
|
+
def get_instrument(file):
|
|
670
|
+
return splitext(basename(file))[0].split('_')[1]
|
|
609
671
|
|
|
610
|
-
if
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
672
|
+
if file_object:
|
|
673
|
+
if star is None:
|
|
674
|
+
try:
|
|
675
|
+
star = get_star_name(files[0].name)
|
|
676
|
+
except Exception:
|
|
677
|
+
star ='unknown'
|
|
614
678
|
if verbose:
|
|
615
679
|
logger.info(f'assuming star is {star}')
|
|
616
680
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
681
|
+
if instrument is None:
|
|
682
|
+
try:
|
|
683
|
+
instrument = get_instrument(files[0].name)
|
|
684
|
+
except Exception:
|
|
685
|
+
instrument = 'unknown'
|
|
686
|
+
if verbose:
|
|
687
|
+
logger.info(f'assuming instrument is {instrument}')
|
|
688
|
+
|
|
689
|
+
instruments = np.array([instrument])
|
|
621
690
|
else:
|
|
622
|
-
|
|
691
|
+
if star is None:
|
|
692
|
+
star = np.unique([get_star_name(f) for f in files])[0]
|
|
693
|
+
if verbose:
|
|
694
|
+
logger.info(f'assuming star is {star}')
|
|
695
|
+
else:
|
|
696
|
+
star = 'unknown'
|
|
697
|
+
|
|
698
|
+
if instrument is None:
|
|
699
|
+
instruments = np.array([splitext(basename(f))[0].split('_')[1] for f in files])
|
|
700
|
+
if verbose:
|
|
701
|
+
logger.info(f'assuming instruments: {instruments}')
|
|
702
|
+
else:
|
|
703
|
+
instruments = np.atleast_1d(instrument)
|
|
623
704
|
|
|
624
705
|
if instruments.size == 1 and len(files) > 1:
|
|
625
706
|
instruments = np.repeat(instruments, len(files))
|
|
@@ -652,12 +733,16 @@ class RV(ISSUES, REPORTS):
|
|
|
652
733
|
_quantities = []
|
|
653
734
|
|
|
654
735
|
#! hack
|
|
655
|
-
|
|
656
|
-
header =
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
736
|
+
if file_object:
|
|
737
|
+
header = f.readline().strip()
|
|
738
|
+
else:
|
|
739
|
+
with open(f) as ff:
|
|
740
|
+
header = ff.readline().strip()
|
|
741
|
+
|
|
742
|
+
if '\t' in header:
|
|
743
|
+
names = header.split('\t')
|
|
744
|
+
else:
|
|
745
|
+
names = header.split()
|
|
661
746
|
|
|
662
747
|
if len(names) > 3:
|
|
663
748
|
# if f.endswith('.rdb'):
|
|
@@ -670,7 +755,7 @@ class RV(ISSUES, REPORTS):
|
|
|
670
755
|
data = np.genfromtxt(f, **kw, delimiter='\t')
|
|
671
756
|
else:
|
|
672
757
|
data = np.genfromtxt(f, **kw)
|
|
673
|
-
|
|
758
|
+
|
|
674
759
|
# if data.ndim in (0, 1):
|
|
675
760
|
# data = data.reshape(-1, 1)
|
|
676
761
|
|
|
@@ -814,7 +899,22 @@ class RV(ISSUES, REPORTS):
|
|
|
814
899
|
|
|
815
900
|
@classmethod
|
|
816
901
|
def from_ccf(cls, files, star=None, instrument=None, **kwargs):
|
|
817
|
-
""" Create an RV object from a CCF file or a list of CCF files
|
|
902
|
+
""" Create an RV object from a CCF file or a list of CCF files
|
|
903
|
+
|
|
904
|
+
!!! Note
|
|
905
|
+
This function relies on the `iCCF` package
|
|
906
|
+
|
|
907
|
+
Args:
|
|
908
|
+
files (str or list):
|
|
909
|
+
CCF file or list of CCF files
|
|
910
|
+
star (str):
|
|
911
|
+
Star name. If not provided, it will be inferred from the header
|
|
912
|
+
of the CCF file
|
|
913
|
+
instrument (str):
|
|
914
|
+
Instrument name. If not provided, it will be inferred from the
|
|
915
|
+
header of the CCF file
|
|
916
|
+
|
|
917
|
+
"""
|
|
818
918
|
try:
|
|
819
919
|
import iCCF
|
|
820
920
|
except ImportError:
|
|
@@ -839,7 +939,7 @@ class RV(ISSUES, REPORTS):
|
|
|
839
939
|
objects = np.unique([i.HDU[0].header['OBJECT'].replace(' ', '') for i in CCFs])
|
|
840
940
|
|
|
841
941
|
if len(objects) != 1:
|
|
842
|
-
logger.warning(f'found {objects.size} different stars in the CCF files, '
|
|
942
|
+
logger.warning(f'found {objects.size} different stars in the CCF files ({objects}), '
|
|
843
943
|
'choosing the first one')
|
|
844
944
|
star = objects[0]
|
|
845
945
|
|
|
@@ -865,9 +965,22 @@ class RV(ISSUES, REPORTS):
|
|
|
865
965
|
_quantities.append('contrast')
|
|
866
966
|
_quantities.append('contrast_err')
|
|
867
967
|
|
|
968
|
+
_s.bispan = np.array([i.BIS*1e3 for i in CCFs])
|
|
969
|
+
_s.bispan_err = np.array([i.BISerror*1e3 for i in CCFs])
|
|
970
|
+
_quantities.append('bispan')
|
|
971
|
+
_quantities.append('bispan_err')
|
|
972
|
+
|
|
973
|
+
_s.rhk = np.full_like(time, np.nan)
|
|
974
|
+
_s.rhk_err = np.full_like(time, np.nan)
|
|
975
|
+
_quantities.append('rhk')
|
|
976
|
+
_quantities.append('rhk_err')
|
|
977
|
+
|
|
868
978
|
_s.texp = np.array([i.HDU[0].header['EXPTIME'] for i in CCFs])
|
|
869
979
|
_quantities.append('texp')
|
|
870
980
|
|
|
981
|
+
_s.berv = np.array([i.HDU[0].header['HIERARCH ESO QC BERV'] for i in CCFs])
|
|
982
|
+
_quantities.append('berv')
|
|
983
|
+
|
|
871
984
|
_s.date_night = np.array([
|
|
872
985
|
i.HDU[0].header['DATE-OBS'].split('T')[0] for i in CCFs
|
|
873
986
|
])
|
|
@@ -938,17 +1051,17 @@ class RV(ISSUES, REPORTS):
|
|
|
938
1051
|
if fits_file not in tar.getnames():
|
|
939
1052
|
logger.error(f'KOBE file not found for {star}')
|
|
940
1053
|
return
|
|
941
|
-
|
|
1054
|
+
|
|
942
1055
|
hdul = fits.open(tar.extractfile(fits_file))
|
|
943
1056
|
|
|
944
1057
|
else:
|
|
945
1058
|
resp = requests.get(f'https://kobe.caha.es/internal/fitsfiles/{fits_file}',
|
|
946
1059
|
auth=HTTPBasicAuth('kobeteam', config.kobe_password))
|
|
947
|
-
|
|
1060
|
+
|
|
948
1061
|
if resp.status_code != 200:
|
|
949
1062
|
# something went wrong, try to extract the file by downloading the
|
|
950
1063
|
# full tar.gz archive
|
|
951
|
-
|
|
1064
|
+
|
|
952
1065
|
logger.warning(f'could not find "{fits_file}" on server, trying to download full archive')
|
|
953
1066
|
resp = requests.get('https://kobe.caha.es/internal/fitsfiles.tar.gz',
|
|
954
1067
|
auth=HTTPBasicAuth('kobeteam', config.kobe_password))
|
|
@@ -966,7 +1079,7 @@ class RV(ISSUES, REPORTS):
|
|
|
966
1079
|
if fits_file not in tar.getnames():
|
|
967
1080
|
logger.error(f'KOBE file not found for {star}')
|
|
968
1081
|
return
|
|
969
|
-
|
|
1082
|
+
|
|
970
1083
|
hdul = fits.open(tar.extractfile(fits_file))
|
|
971
1084
|
|
|
972
1085
|
else:
|
|
@@ -1365,7 +1478,9 @@ class RV(ISSUES, REPORTS):
|
|
|
1365
1478
|
def remove_point(self, index):
|
|
1366
1479
|
"""
|
|
1367
1480
|
Remove individual observations at a given index (or indices).
|
|
1368
|
-
|
|
1481
|
+
|
|
1482
|
+
!!! Note
|
|
1483
|
+
Like Python, the index is 0-based.
|
|
1369
1484
|
|
|
1370
1485
|
Args:
|
|
1371
1486
|
index (int, list, ndarray):
|
|
@@ -1376,7 +1491,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1376
1491
|
instrument_index = self.obs[index]
|
|
1377
1492
|
np.array(self.instruments)[instrument_index - 1]
|
|
1378
1493
|
except IndexError:
|
|
1379
|
-
logger.
|
|
1494
|
+
logger.error(f'index {index} is out of bounds for N={self.N}')
|
|
1380
1495
|
return
|
|
1381
1496
|
|
|
1382
1497
|
if self.verbose:
|
|
@@ -1397,18 +1512,21 @@ class RV(ISSUES, REPORTS):
|
|
|
1397
1512
|
def restore_point(self, index):
|
|
1398
1513
|
"""
|
|
1399
1514
|
Restore previously deleted individual observations at a given index (or
|
|
1400
|
-
indices).
|
|
1515
|
+
indices).
|
|
1516
|
+
|
|
1517
|
+
!!! Note
|
|
1518
|
+
Like Python, the index is 0-based
|
|
1401
1519
|
|
|
1402
1520
|
Args:
|
|
1403
1521
|
index (int, list, ndarray):
|
|
1404
|
-
Single index, list, or array of indices to restore
|
|
1522
|
+
Single index, list, or array of indices to restore
|
|
1405
1523
|
"""
|
|
1406
1524
|
index = np.atleast_1d(index)
|
|
1407
1525
|
try:
|
|
1408
1526
|
instrument_index = self.obs[index]
|
|
1409
1527
|
np.array(self.instruments)[instrument_index - 1]
|
|
1410
1528
|
except IndexError:
|
|
1411
|
-
logger.
|
|
1529
|
+
logger.error(f'index {index} is out of bounds for N={self.N}')
|
|
1412
1530
|
return
|
|
1413
1531
|
|
|
1414
1532
|
if self.verbose:
|
|
@@ -1427,6 +1545,14 @@ class RV(ISSUES, REPORTS):
|
|
|
1427
1545
|
self.mask = self.mask & self.public
|
|
1428
1546
|
self._propagate_mask_changes()
|
|
1429
1547
|
|
|
1548
|
+
def remove_public(self):
|
|
1549
|
+
""" Remove public observations """
|
|
1550
|
+
if self.verbose:
|
|
1551
|
+
n = self.public.sum()
|
|
1552
|
+
logger.info(f'masking public observations ({n})')
|
|
1553
|
+
self.mask = self.mask & (~self.public)
|
|
1554
|
+
self._propagate_mask_changes()
|
|
1555
|
+
|
|
1430
1556
|
def remove_single_observations(self):
|
|
1431
1557
|
""" Remove instruments for which there is a single observation """
|
|
1432
1558
|
singles = [i for i in self.instruments if getattr(self, i).mtime.size == 1]
|
|
@@ -1452,26 +1578,26 @@ class RV(ISSUES, REPORTS):
|
|
|
1452
1578
|
if self.verbose:
|
|
1453
1579
|
logger.warning(f'no observations for prog_id "{prog_id}"')
|
|
1454
1580
|
|
|
1455
|
-
def remove_after_bjd(self, bjd):
|
|
1581
|
+
def remove_after_bjd(self, bjd: float):
|
|
1456
1582
|
""" Remove observations after a given BJD """
|
|
1457
1583
|
if (self.time > bjd).any():
|
|
1458
1584
|
ind = np.where(self.time > bjd)[0]
|
|
1459
1585
|
self.remove_point(ind)
|
|
1460
1586
|
|
|
1461
|
-
def remove_before_bjd(self, bjd):
|
|
1587
|
+
def remove_before_bjd(self, bjd: float):
|
|
1462
1588
|
""" Remove observations before a given BJD """
|
|
1463
1589
|
if (self.time < bjd).any():
|
|
1464
1590
|
ind = np.where(self.time < bjd)[0]
|
|
1465
1591
|
self.remove_point(ind)
|
|
1466
|
-
|
|
1467
|
-
def remove_between_bjds(self, bjd1, bjd2):
|
|
1592
|
+
|
|
1593
|
+
def remove_between_bjds(self, bjd1: float, bjd2: float):
|
|
1468
1594
|
""" Remove observations between two BJDs """
|
|
1469
1595
|
to_remove = (self.time > bjd1) & (self.time < bjd2)
|
|
1470
1596
|
if to_remove.any():
|
|
1471
1597
|
ind = np.where(to_remove)[0]
|
|
1472
1598
|
self.remove_point(ind)
|
|
1473
1599
|
|
|
1474
|
-
def choose_n_points(self, n, seed=None, instrument=None):
|
|
1600
|
+
def choose_n_points(self, n: int, seed=None, instrument=None):
|
|
1475
1601
|
""" Randomly choose `n` observations and mask out the remaining ones
|
|
1476
1602
|
|
|
1477
1603
|
Args:
|
|
@@ -1509,15 +1635,20 @@ class RV(ISSUES, REPORTS):
|
|
|
1509
1635
|
getattr(self, inst).mask[m - n_before] = False
|
|
1510
1636
|
|
|
1511
1637
|
def secular_acceleration(self, epoch=None, just_compute=False, force_simbad=False):
|
|
1512
|
-
"""
|
|
1513
|
-
Remove secular acceleration from RVs
|
|
1638
|
+
"""
|
|
1639
|
+
Remove secular acceleration from RVs. This uses the proper motions from
|
|
1640
|
+
Gaia (in `self.gaia`) if available, otherwise from Simbad (in
|
|
1641
|
+
`self.simbad`), unless `force_simbad=True`.
|
|
1642
|
+
|
|
1514
1643
|
|
|
1515
1644
|
Args:
|
|
1516
1645
|
epoch (float, optional):
|
|
1517
1646
|
The reference epoch (DACE uses 55500, 31/10/2010)
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1647
|
+
just_compute (bool, optional):
|
|
1648
|
+
Just compute the secular acceleration and return, without
|
|
1649
|
+
changing the RVs
|
|
1650
|
+
force_simbad (bool, optional):
|
|
1651
|
+
Use Simbad proper motions even if Gaia is available
|
|
1521
1652
|
"""
|
|
1522
1653
|
if self._did_secular_acceleration and not just_compute: # don't do it twice
|
|
1523
1654
|
return
|
|
@@ -1626,7 +1757,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1626
1757
|
|
|
1627
1758
|
if config.return_self:
|
|
1628
1759
|
return self
|
|
1629
|
-
|
|
1760
|
+
|
|
1630
1761
|
def _undo_secular_acceleration(self):
|
|
1631
1762
|
if self._did_secular_acceleration:
|
|
1632
1763
|
_old_verbose = self.verbose
|
|
@@ -1654,7 +1785,15 @@ class RV(ISSUES, REPORTS):
|
|
|
1654
1785
|
self._did_secular_acceleration = False
|
|
1655
1786
|
|
|
1656
1787
|
def sigmaclip(self, sigma=5, instrument=None, strict=True):
|
|
1657
|
-
"""
|
|
1788
|
+
"""
|
|
1789
|
+
Sigma-clip RVs (per instrument!), by MAD away from the median.
|
|
1790
|
+
|
|
1791
|
+
Args:
|
|
1792
|
+
sigma (float):
|
|
1793
|
+
Number of MADs to clip
|
|
1794
|
+
instrument (str, list):
|
|
1795
|
+
Instrument(s) to sigma-clip
|
|
1796
|
+
"""
|
|
1658
1797
|
#from scipy.stats import sigmaclip as dosigmaclip
|
|
1659
1798
|
from .stats import sigmaclip_median as dosigmaclip
|
|
1660
1799
|
|
|
@@ -1691,7 +1830,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1691
1830
|
|
|
1692
1831
|
self._propagate_mask_changes()
|
|
1693
1832
|
|
|
1694
|
-
if self._did_adjust_means:
|
|
1833
|
+
if len(changed_instruments) > 0 and self._did_adjust_means:
|
|
1695
1834
|
self._did_adjust_means = False
|
|
1696
1835
|
self.adjust_means(instrument=changed_instruments)
|
|
1697
1836
|
|
|
@@ -1724,7 +1863,8 @@ class RV(ISSUES, REPORTS):
|
|
|
1724
1863
|
"""
|
|
1725
1864
|
Nightly bin the observations.
|
|
1726
1865
|
|
|
1727
|
-
|
|
1866
|
+
!!! Warning
|
|
1867
|
+
This creates and returns a new object and does not modify self.
|
|
1728
1868
|
"""
|
|
1729
1869
|
|
|
1730
1870
|
# create copy of self to be returned
|
|
@@ -1828,7 +1968,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1828
1968
|
return np.nanmean(z, axis=0)
|
|
1829
1969
|
|
|
1830
1970
|
def subtract_mean(self):
|
|
1831
|
-
""" Subtract (single) mean RV from all instruments """
|
|
1971
|
+
""" Subtract (a single) non-weighted mean RV from all instruments """
|
|
1832
1972
|
self._meanRV = meanRV = self.mvrad.mean()
|
|
1833
1973
|
for inst in self.instruments:
|
|
1834
1974
|
s = getattr(self, inst)
|
|
@@ -1864,7 +2004,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1864
2004
|
# row = []
|
|
1865
2005
|
# if print_as_table:
|
|
1866
2006
|
# logger.info('subtracted weighted average from each instrument:')
|
|
1867
|
-
|
|
2007
|
+
|
|
1868
2008
|
others = ('fwhm', 'bispan', )
|
|
1869
2009
|
|
|
1870
2010
|
instruments = self._check_instrument(instrument, strict=kwargs.get('strict', False))
|
|
@@ -2143,10 +2283,10 @@ class RV(ISSUES, REPORTS):
|
|
|
2143
2283
|
""" Sort instruments by first or last observation date.
|
|
2144
2284
|
|
|
2145
2285
|
Args:
|
|
2146
|
-
by_first_observation (bool, optional
|
|
2147
|
-
Sort by first observation date
|
|
2148
|
-
by_last_observation (bool, optional
|
|
2149
|
-
Sort by last observation date
|
|
2286
|
+
by_first_observation (bool, optional):
|
|
2287
|
+
Sort by first observation date
|
|
2288
|
+
by_last_observation (bool, optional):
|
|
2289
|
+
Sort by last observation date
|
|
2150
2290
|
"""
|
|
2151
2291
|
if by_last_observation:
|
|
2152
2292
|
by_first_observation = False
|
|
@@ -2222,7 +2362,7 @@ class RV(ISSUES, REPORTS):
|
|
|
2222
2362
|
# if self.verbose:
|
|
2223
2363
|
# logger.warning(f'masking {nan_mask.sum()} observations with NaN in indicators')
|
|
2224
2364
|
|
|
2225
|
-
header = '\t'.join(['rjd', 'vrad', 'svrad',
|
|
2365
|
+
header = '\t'.join(['rjd', 'vrad', 'svrad',
|
|
2226
2366
|
'fwhm', 'sig_fwhm',
|
|
2227
2367
|
'bispan', 'sig_bispan',
|
|
2228
2368
|
'contrast', 'sig_contrast',
|
arvi/utils.py
CHANGED
|
@@ -79,14 +79,17 @@ def timer(name=None):
|
|
|
79
79
|
if name is None:
|
|
80
80
|
logger.debug('starting timer')
|
|
81
81
|
else:
|
|
82
|
-
logger.debug(f'starting timer
|
|
82
|
+
logger.debug(f'{name}: starting timer')
|
|
83
83
|
|
|
84
84
|
start = time.time()
|
|
85
85
|
try:
|
|
86
86
|
yield
|
|
87
87
|
finally:
|
|
88
88
|
end = time.time()
|
|
89
|
-
|
|
89
|
+
if name is None:
|
|
90
|
+
logger.debug(f'elapsed time {end - start:.2f} seconds')
|
|
91
|
+
else:
|
|
92
|
+
logger.debug(f'{name}: elapsed time {end - start:.2f} seconds')
|
|
90
93
|
|
|
91
94
|
|
|
92
95
|
def sanitize_path(path):
|
|
@@ -4,12 +4,12 @@ arvi/ariadne_wrapper.py,sha256=YvilopJa9T4NwPcj3Nah_U8smSeSAU5-HYZMb_GJ-BQ,2232
|
|
|
4
4
|
arvi/berv.py,sha256=eKnpuPC1w45UrUEyFRbs9F9j3bXz3kxYzNXbnRgvFQM,17596
|
|
5
5
|
arvi/binning.py,sha256=NK9y9bUrdyWCbh79LkcRABHG-n5MtlETMHMvLj1z-OM,15437
|
|
6
6
|
arvi/config.py,sha256=JkHSwF-EEqwwbcc8thGgbFc9udDZPjQH-9XFjqDepBY,2337
|
|
7
|
-
arvi/dace_wrapper.py,sha256=
|
|
7
|
+
arvi/dace_wrapper.py,sha256=sgFxM2Jtd1NbT0e7xuKIE94dVN5mjlv15m72WYf95HU,25685
|
|
8
8
|
arvi/exofop_wrapper.py,sha256=8S7UEcrBAgANIweMV0-CvaWaVTPgGVo8vQQk_KRa0nU,2414
|
|
9
9
|
arvi/extra_data.py,sha256=Xi65pI5kkzqlMmHGl9xFoumtH699611pJJ5PV-a_IfU,3397
|
|
10
|
-
arvi/gaia_wrapper.py,sha256=
|
|
10
|
+
arvi/gaia_wrapper.py,sha256=HTuigIduin3raWfSC7QYuQxDk2dEXYH_4egRkzzg7Xw,4379
|
|
11
11
|
arvi/headers.py,sha256=uvdJebw1M5YkGjE3vJJwYBOnLikib75uuZE9FXB5JJM,1673
|
|
12
|
-
arvi/instrument_specific.py,sha256=
|
|
12
|
+
arvi/instrument_specific.py,sha256=np-kYQeKJ39CKjOzHzM9av_WIjbmmDyDUODEnrx8Y4s,11462
|
|
13
13
|
arvi/kima_wrapper.py,sha256=BvNTVqzM4lMNhLCyBFVh3T84hHfGKAFpgiYiOi4lh0g,2731
|
|
14
14
|
arvi/lbl_wrapper.py,sha256=_ViGVkpakvuBR_xhu9XJRV5EKHpj5Go6jBZGJZMIS2Y,11850
|
|
15
15
|
arvi/nasaexo_wrapper.py,sha256=mWt7eHgSZe4MBKCmUvMPTyUPGuiwGTqKugNBvmjOg9s,7306
|
|
@@ -17,21 +17,22 @@ arvi/plots.py,sha256=fHc6ScATCzvM4KQ77TYfHYmY6HSZ4N4oMYsLEUvxJpU,35279
|
|
|
17
17
|
arvi/programs.py,sha256=BW7xBNKLei7NVLLW3_lsVskwzkaIoNRiHK2jn9Tn2ZM,8879
|
|
18
18
|
arvi/reports.py,sha256=CKmtg5rewMyT26gbWeoZDYrL0z5Sbb6cTJry0HWk_rs,7445
|
|
19
19
|
arvi/setup_logger.py,sha256=dHzO2gPjw6CaKWpYZd2f83z09tmxgi--qpp7k1jROjI,615
|
|
20
|
-
arvi/simbad_wrapper.py,sha256=
|
|
20
|
+
arvi/simbad_wrapper.py,sha256=nwQIp7RfLu_SIeO0BTMukkY6koF7lexYFFfOZveKTnU,9185
|
|
21
|
+
arvi/sophie_wrapper.py,sha256=KUeWccXud5_Lrx72S1HSemHIZRdjd2oLvqyofwsL0QQ,3440
|
|
21
22
|
arvi/spectra.py,sha256=ebF1ocodTastLx0CyqLSpE8EZNDXBF8riyfxMr3L6H0,7491
|
|
22
23
|
arvi/stats.py,sha256=ilzzGL9ew-SyVa9eEdrYCpD3DliOAwhoNUg9LIlHjzU,2583
|
|
23
24
|
arvi/stellar.py,sha256=GQ7yweuBRnfkJ0M5eWjvLd8uvGq_by81PbXfidBvWis,4918
|
|
24
|
-
arvi/timeseries.py,sha256=
|
|
25
|
+
arvi/timeseries.py,sha256=Ev4McrYznhs4pDgza5TEl0V1KgSrWpmCSlJFG-uQlpM,95722
|
|
25
26
|
arvi/translations.py,sha256=PUSrn4zvYO2MqGzUxlFGwev_tBkgJaJrIYs6NKHzbWo,951
|
|
26
|
-
arvi/utils.py,sha256=
|
|
27
|
+
arvi/utils.py,sha256=EY4hdwGcTUZg_tPT3yQ7ShLIVm9dAfmJC0c7toAVSKI,7221
|
|
27
28
|
arvi/data/info.svg,sha256=0IMI6W-eFoTD8acnury79WJJakpBwLa4qKS4JWpsXiI,489
|
|
28
29
|
arvi/data/obs_affected_ADC_issues.dat,sha256=tn93uOL0eCTYhireqp1wG-_c3CbxPA7C-Rf-pejVY8M,10853
|
|
29
30
|
arvi/data/obs_affected_blue_cryostat_issues.dat,sha256=z4AK17xfz8tGTDv1FjRvQFnio4XA6PNNfDXuicewHk4,1771
|
|
30
31
|
arvi/data/extra/HD86226_PFS1.rdb,sha256=vfAozbrKHM_j8dYkCBJsuHyD01KEM1asghe2KInwVao,3475
|
|
31
32
|
arvi/data/extra/HD86226_PFS2.rdb,sha256=F2P7dB6gVyzCglUjNheB0hIHVClC5RmARrGwbrY1cfo,4114
|
|
32
33
|
arvi/data/extra/metadata.json,sha256=C69hIw6CohyES6BI9vDWjxwSz7N4VOYX0PCgjXtYFmU,178
|
|
33
|
-
arvi-0.2.
|
|
34
|
-
arvi-0.2.
|
|
35
|
-
arvi-0.2.
|
|
36
|
-
arvi-0.2.
|
|
37
|
-
arvi-0.2.
|
|
34
|
+
arvi-0.2.7.dist-info/licenses/LICENSE,sha256=6JfQgl7SpM55t0EHMFNMnNh-AdkpGW25MwMiTnhdWQg,1068
|
|
35
|
+
arvi-0.2.7.dist-info/METADATA,sha256=UnB8zRrrEjG78dAjKiFY2Qh6a1tqvRaptf026MsUrdw,1932
|
|
36
|
+
arvi-0.2.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
37
|
+
arvi-0.2.7.dist-info/top_level.txt,sha256=4EeiKDVLD45ztuflTGfQ3TU8GVjJg5Y95xS5XjI-utU,5
|
|
38
|
+
arvi-0.2.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|