arvi 0.2.11__py3-none-any.whl → 0.3.2__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.
- arvi/__init__.py +5 -1
- arvi/config.py +3 -2
- arvi/dace_wrapper.py +91 -53
- arvi/gaia_wrapper.py +12 -2
- arvi/kima_wrapper.py +33 -22
- arvi/plots.py +26 -0
- arvi/programs.py +15 -21
- arvi/setup_logger.py +11 -11
- arvi/simbad_wrapper.py +35 -5
- arvi/sophie_wrapper.py +1 -1
- arvi/stats.py +7 -3
- arvi/timeseries.py +86 -35
- {arvi-0.2.11.dist-info → arvi-0.3.2.dist-info}/METADATA +1 -1
- {arvi-0.2.11.dist-info → arvi-0.3.2.dist-info}/RECORD +17 -17
- {arvi-0.2.11.dist-info → arvi-0.3.2.dist-info}/WHEEL +1 -1
- {arvi-0.2.11.dist-info → arvi-0.3.2.dist-info}/licenses/LICENSE +0 -0
- {arvi-0.2.11.dist-info → arvi-0.3.2.dist-info}/top_level.txt +0 -0
arvi/__init__.py
CHANGED
|
@@ -17,11 +17,15 @@ def __getattr__(name: str):
|
|
|
17
17
|
if not config.fancy_import:
|
|
18
18
|
raise AttributeError
|
|
19
19
|
|
|
20
|
+
if name.startswith('__'):
|
|
21
|
+
return
|
|
20
22
|
if name in (
|
|
21
23
|
'_ipython_canary_method_should_not_exist_',
|
|
22
24
|
'_ipython_display_',
|
|
23
25
|
'_repr_mimebundle_',
|
|
24
|
-
'
|
|
26
|
+
# '__custom_documentations__',
|
|
27
|
+
# '__wrapped__',
|
|
28
|
+
# '__dataframe__'
|
|
25
29
|
):
|
|
26
30
|
return
|
|
27
31
|
|
arvi/config.py
CHANGED
|
@@ -36,6 +36,8 @@ class config:
|
|
|
36
36
|
'fancy_import': True,
|
|
37
37
|
# use the 'dark_background' matplotlib theme
|
|
38
38
|
'dark_plots': False,
|
|
39
|
+
# specific colors per instrument
|
|
40
|
+
'colors_per_instrument': False,
|
|
39
41
|
# debug
|
|
40
42
|
'debug': False,
|
|
41
43
|
}
|
|
@@ -43,7 +45,7 @@ class config:
|
|
|
43
45
|
|
|
44
46
|
__user_config = get_config()
|
|
45
47
|
|
|
46
|
-
def __getattr__(self, name):
|
|
48
|
+
def __getattr__(self, name: str):
|
|
47
49
|
if name in ('__custom_documentations__', ):
|
|
48
50
|
# return {'return_self': 'help!'}
|
|
49
51
|
return {}
|
|
@@ -54,7 +56,6 @@ class config:
|
|
|
54
56
|
value = True if value == 'True' else value
|
|
55
57
|
value = False if value == 'False' else value
|
|
56
58
|
self.__conf[name] = value
|
|
57
|
-
|
|
58
59
|
return self.__conf[name]
|
|
59
60
|
except KeyError:
|
|
60
61
|
raise KeyError(f"unknown config option '{name}'")
|
arvi/dace_wrapper.py
CHANGED
|
@@ -229,61 +229,95 @@ def get_observations_from_instrument(star, instrument, user=None, main_id=None,
|
|
|
229
229
|
mask3 = mask2 & (result['ins_mode'] == ins_mode)
|
|
230
230
|
_nan = np.full(mask3.sum(), np.nan)
|
|
231
231
|
|
|
232
|
-
|
|
233
|
-
'
|
|
234
|
-
'
|
|
235
|
-
'
|
|
236
|
-
'
|
|
237
|
-
'
|
|
238
|
-
'
|
|
239
|
-
'
|
|
240
|
-
'fwhm_err': result['spectro_ccf_fwhm_err'][mask3],
|
|
241
|
-
'rv': result['spectro_ccf_rv'][mask3],
|
|
242
|
-
'rv_err': result['spectro_ccf_rv_err'][mask3],
|
|
243
|
-
'berv': result['spectro_cal_berv'][mask3],
|
|
244
|
-
'ccf_noise': np.sqrt(
|
|
245
|
-
np.square(result['spectro_ccf_rv_err'][mask3]) - np.square(result['spectro_cal_drift_noise'][mask3])
|
|
246
|
-
),
|
|
247
|
-
'rhk': result['spectro_analysis_rhk'][mask3],
|
|
248
|
-
'rhk_err': result['spectro_analysis_rhk_err'][mask3],
|
|
249
|
-
'contrast': result['spectro_ccf_contrast'][mask3],
|
|
250
|
-
'contrast_err': result['spectro_ccf_contrast_err'][mask3],
|
|
251
|
-
'cal_thfile': result['spectro_cal_thfile'][mask3],
|
|
252
|
-
'spectroFluxSn50': result['spectro_flux_sn50'][mask3],
|
|
253
|
-
'protm08': result['spectro_analysis_protm08'][mask3],
|
|
254
|
-
'protm08_err': result['spectro_analysis_protm08_err'][mask3],
|
|
255
|
-
'caindex': result['spectro_analysis_ca'][mask3],
|
|
256
|
-
'caindex_err': result['spectro_analysis_ca_err'][mask3],
|
|
257
|
-
'pub_reference': result['pub_ref'][mask3],
|
|
258
|
-
'drs_qc': result['spectro_drs_qc'][mask3],
|
|
259
|
-
'haindex': result['spectro_analysis_halpha'][mask3],
|
|
260
|
-
'haindex_err': result['spectro_analysis_halpha_err'][mask3],
|
|
261
|
-
'protn84': result['spectro_analysis_protn84'][mask3],
|
|
262
|
-
'protn84_err': result['spectro_analysis_protn84_err'][mask3],
|
|
263
|
-
'naindex': result['spectro_analysis_na'][mask3],
|
|
264
|
-
'naindex_err': result['spectro_analysis_na_err'][mask3],
|
|
265
|
-
'snca2': _nan,
|
|
266
|
-
'mask': result['spectro_ccf_mask'][mask3],
|
|
267
|
-
'public': result['public'][mask3],
|
|
268
|
-
'spectroFluxSn20': result['spectro_flux_sn20'][mask3],
|
|
269
|
-
'sindex': result['spectro_analysis_smw'][mask3],
|
|
270
|
-
'sindex_err': result['spectro_analysis_smw_err'][mask3],
|
|
271
|
-
'drift_used': _nan,
|
|
272
|
-
'ccf_asym': result['spectro_ccf_asym'][mask3],
|
|
273
|
-
'ccf_asym_err': result['spectro_ccf_asym_err'][mask3],
|
|
274
|
-
'date_night': result['date_night'][mask3],
|
|
275
|
-
'raw_file': result['file_rootpath'][mask3],
|
|
276
|
-
'prog_id': result['prog_id'][mask3],
|
|
277
|
-
'th_ar': result['th_ar'][mask3],
|
|
278
|
-
'th_ar1': result['th_ar1'][mask3],
|
|
279
|
-
'th_ar2': result['th_ar2'][mask3],
|
|
232
|
+
translations = {
|
|
233
|
+
'obj_date_bjd': 'rjd',
|
|
234
|
+
'spectro_drs_qc': 'drs_qc',
|
|
235
|
+
'spectro_cal_berv_mx': 'bervmax',
|
|
236
|
+
'pub_ref': 'pub_reference',
|
|
237
|
+
'file_rootpath': 'raw_file',
|
|
238
|
+
'spectro_ccf_asym': 'ccf_asym',
|
|
239
|
+
'spectro_ccf_asym_err': 'ccf_asym_err',
|
|
280
240
|
}
|
|
241
|
+
new_result = {}
|
|
242
|
+
for key in result.keys():
|
|
243
|
+
if key in translations:
|
|
244
|
+
new_key = translations[key]
|
|
245
|
+
else:
|
|
246
|
+
new_key = key
|
|
247
|
+
new_key = new_key.replace('spectro_ccf_', '')
|
|
248
|
+
new_key = new_key.replace('spectro_cal_', '')
|
|
249
|
+
new_key = new_key.replace('spectro_analysis_', '')
|
|
250
|
+
new_result[new_key] = result[key][mask3]
|
|
251
|
+
|
|
252
|
+
new_result['ccf_noise'] = np.sqrt(
|
|
253
|
+
np.square(result['spectro_ccf_rv_err'][mask3]) - np.square(result['spectro_cal_drift_noise'][mask3])
|
|
254
|
+
)
|
|
255
|
+
|
|
256
|
+
r[str(inst)][str(pipe)][str(ins_mode)] = new_result
|
|
257
|
+
|
|
258
|
+
# r[str(inst)][str(pipe)][str(ins_mode)] = {
|
|
259
|
+
# 'texp': result['texp'][mask3],
|
|
260
|
+
# 'bispan': result['spectro_ccf_bispan'][mask3],
|
|
261
|
+
# 'bispan_err': result['spectro_ccf_bispan_err'][mask3],
|
|
262
|
+
# 'drift_noise': result['spectro_cal_drift_noise'][mask3],
|
|
263
|
+
# 'rjd': result['obj_date_bjd'][mask3],
|
|
264
|
+
# 'cal_therror': _nan,
|
|
265
|
+
# 'fwhm': result['spectro_ccf_fwhm'][mask3],
|
|
266
|
+
# 'fwhm_err': result['spectro_ccf_fwhm_err'][mask3],
|
|
267
|
+
# 'rv': result['spectro_ccf_rv'][mask3],
|
|
268
|
+
# 'rv_err': result['spectro_ccf_rv_err'][mask3],
|
|
269
|
+
# 'berv': result['spectro_cal_berv'][mask3],
|
|
270
|
+
# 'ccf_noise': np.sqrt(
|
|
271
|
+
# np.square(result['spectro_ccf_rv_err'][mask3]) - np.square(result['spectro_cal_drift_noise'][mask3])
|
|
272
|
+
# ),
|
|
273
|
+
# 'rhk': result['spectro_analysis_rhk'][mask3],
|
|
274
|
+
# 'rhk_err': result['spectro_analysis_rhk_err'][mask3],
|
|
275
|
+
# 'contrast': result['spectro_ccf_contrast'][mask3],
|
|
276
|
+
# 'contrast_err': result['spectro_ccf_contrast_err'][mask3],
|
|
277
|
+
# 'cal_thfile': result['spectro_cal_thfile'][mask3],
|
|
278
|
+
# 'spectroFluxSn50': result['spectro_flux_sn50'][mask3],
|
|
279
|
+
# 'protm08': result['spectro_analysis_protm08'][mask3],
|
|
280
|
+
# 'protm08_err': result['spectro_analysis_protm08_err'][mask3],
|
|
281
|
+
# 'caindex': result['spectro_analysis_ca'][mask3],
|
|
282
|
+
# 'caindex_err': result['spectro_analysis_ca_err'][mask3],
|
|
283
|
+
# 'pub_reference': result['pub_ref'][mask3],
|
|
284
|
+
# 'drs_qc': result['spectro_drs_qc'][mask3],
|
|
285
|
+
# 'haindex': result['spectro_analysis_halpha'][mask3],
|
|
286
|
+
# 'haindex_err': result['spectro_analysis_halpha_err'][mask3],
|
|
287
|
+
# 'protn84': result['spectro_analysis_protn84'][mask3],
|
|
288
|
+
# 'protn84_err': result['spectro_analysis_protn84_err'][mask3],
|
|
289
|
+
# 'naindex': result['spectro_analysis_na'][mask3],
|
|
290
|
+
# 'naindex_err': result['spectro_analysis_na_err'][mask3],
|
|
291
|
+
# 'snca2': _nan,
|
|
292
|
+
# 'mask': result['spectro_ccf_mask'][mask3],
|
|
293
|
+
# 'public': result['public'][mask3],
|
|
294
|
+
# 'spectroFluxSn20': result['spectro_flux_sn20'][mask3],
|
|
295
|
+
# 'sindex': result['spectro_analysis_smw'][mask3],
|
|
296
|
+
# 'sindex_err': result['spectro_analysis_smw_err'][mask3],
|
|
297
|
+
# 'drift_used': _nan,
|
|
298
|
+
# 'ccf_asym': result['spectro_ccf_asym'][mask3],
|
|
299
|
+
# 'ccf_asym_err': result['spectro_ccf_asym_err'][mask3],
|
|
300
|
+
# 'date_night': result['date_night'][mask3],
|
|
301
|
+
# 'raw_file': result['file_rootpath'][mask3],
|
|
302
|
+
# 'prog_id': result['prog_id'][mask3],
|
|
303
|
+
# 'th_ar': result['th_ar'][mask3],
|
|
304
|
+
# 'th_ar1': result['th_ar1'][mask3],
|
|
305
|
+
# 'th_ar2': result['th_ar2'][mask3],
|
|
306
|
+
# }
|
|
281
307
|
|
|
282
308
|
# print(r.keys())
|
|
283
309
|
# print([r[k].keys() for k in r.keys()])
|
|
284
310
|
# print([r[k1][k2].keys() for k1 in r.keys() for k2 in r[k1].keys()])
|
|
285
311
|
return r
|
|
286
312
|
|
|
313
|
+
def _warn_harpsn(instrument):
|
|
314
|
+
if 'HARPSN' in instrument or 'HARPS-N' in instrument:
|
|
315
|
+
logger = setup_logger()
|
|
316
|
+
logger.warning(f'Did you mean "HARPN" instead of "{instrument}"?')
|
|
317
|
+
return True
|
|
318
|
+
return False
|
|
319
|
+
|
|
320
|
+
|
|
287
321
|
def get_observations(star, instrument=None, user=None, main_id=None, verbose=True):
|
|
288
322
|
logger = setup_logger()
|
|
289
323
|
if instrument is None:
|
|
@@ -305,6 +339,7 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
305
339
|
result = get_observations_from_instrument(star, instrument, user, main_id, verbose)
|
|
306
340
|
except ValueError:
|
|
307
341
|
msg = f'no {instrument} observations for {star}'
|
|
342
|
+
_warn_harpsn(instrument)
|
|
308
343
|
raise ValueError(msg) from None
|
|
309
344
|
|
|
310
345
|
# defaultdict --> dict
|
|
@@ -384,6 +419,8 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
384
419
|
def custom_key(val, strip_EGGS=False):
|
|
385
420
|
if strip_EGGS:
|
|
386
421
|
val = val.replace('-EGGS', '').replace(' EGGS', '')
|
|
422
|
+
if val in ('3.3', '3.4', '3.5', '3.6', '3.7', '3.8'):
|
|
423
|
+
val = '0.' + val
|
|
387
424
|
key = 0
|
|
388
425
|
key -= 1 if '3.5' in val else 0
|
|
389
426
|
key -= 1 if 'EGGS' in val else 0
|
|
@@ -408,9 +445,10 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
408
445
|
logger.info('RVs available from')
|
|
409
446
|
with logger.contextualize(indent=' '):
|
|
410
447
|
_inst = ''
|
|
411
|
-
for inst in instruments
|
|
448
|
+
max_len_inst = max([len(inst) for inst in instruments])
|
|
449
|
+
for inst in sorted(instruments):
|
|
412
450
|
pipelines = list(new_result[inst].keys())
|
|
413
|
-
|
|
451
|
+
max_len_pipe = max([len(pipe) for pipe in pipelines])
|
|
414
452
|
for pipe in pipelines:
|
|
415
453
|
last_pipe = pipe == pipelines[-1]
|
|
416
454
|
modes = list(new_result[inst][pipe].keys())
|
|
@@ -418,11 +456,11 @@ def get_observations(star, instrument=None, user=None, main_id=None, verbose=Tru
|
|
|
418
456
|
N = len(new_result[inst][pipe][mode]['rjd'])
|
|
419
457
|
# LOG
|
|
420
458
|
if inst == _inst and last_pipe:
|
|
421
|
-
logger.info(f'{" ":>
|
|
459
|
+
logger.info(f'{" ":>{max_len_inst}s} └ {pipe:{max_len_pipe}s} - {mode} ({N} observations)')
|
|
422
460
|
elif inst == _inst:
|
|
423
|
-
logger.info(f'{" ":>
|
|
461
|
+
logger.info(f'{" ":>{max_len_inst}s} ├ {pipe:{max_len_pipe}s} - {mode} ({N} observations)')
|
|
424
462
|
else:
|
|
425
|
-
logger.info(f'{inst:>
|
|
463
|
+
logger.info(f'{inst:>{max_len_inst}s} ├ {pipe:{max_len_pipe}s} - {mode} ({N} observations)')
|
|
426
464
|
_inst = inst
|
|
427
465
|
|
|
428
466
|
return new_result
|
arvi/gaia_wrapper.py
CHANGED
|
@@ -9,7 +9,8 @@ DATA_PATH = os.path.join(DATA_PATH, 'data')
|
|
|
9
9
|
QUERY = """
|
|
10
10
|
SELECT TOP 20 gaia_source.designation, gaia_source.source_id,
|
|
11
11
|
gaia_source.ra, gaia_source.dec,
|
|
12
|
-
gaia_source.parallax, gaia_source.
|
|
12
|
+
gaia_source.parallax, gaia_source.parallax_error,
|
|
13
|
+
gaia_source.pmra, gaia_source.pmdec,
|
|
13
14
|
gaia_source.ruwe, gaia_source.phot_g_mean_mag, gaia_source.bp_rp,
|
|
14
15
|
gaia_source.radial_velocity, gaia_source.radial_velocity_error
|
|
15
16
|
FROM gaiadr3.gaia_source
|
|
@@ -27,7 +28,8 @@ CONTAINS(
|
|
|
27
28
|
QUERY_ID = """
|
|
28
29
|
SELECT TOP 20 gaia_source.designation, gaia_source.source_id,
|
|
29
30
|
gaia_source.ra, gaia_source.dec,
|
|
30
|
-
gaia_source.parallax, gaia_source.
|
|
31
|
+
gaia_source.parallax, gaia_source.parallax_error,
|
|
32
|
+
gaia_source.pmra, gaia_source.pmdec,
|
|
31
33
|
gaia_source.ruwe, gaia_source.phot_g_mean_mag, gaia_source.bp_rp,
|
|
32
34
|
gaia_source.radial_velocity, gaia_source.radial_velocity_error
|
|
33
35
|
FROM gaiadr3.gaia_source
|
|
@@ -120,6 +122,7 @@ class gaia:
|
|
|
120
122
|
self.pmdec = float(results['pmdec'])
|
|
121
123
|
self.coords = SkyCoord(self.ra, self.dec, unit='deg')
|
|
122
124
|
self.plx = float(results['parallax'])
|
|
125
|
+
self.plx_err = float(results['parallax_error'])
|
|
123
126
|
try:
|
|
124
127
|
self.radial_velocity = float(results['radial_velocity'])
|
|
125
128
|
except ValueError:
|
|
@@ -131,5 +134,12 @@ class gaia:
|
|
|
131
134
|
|
|
132
135
|
return
|
|
133
136
|
|
|
137
|
+
def distance(self):
|
|
138
|
+
""" Calculate the distance to the star as 1 / parallax [pc] """
|
|
139
|
+
from astropy import units as u
|
|
140
|
+
d = (self.plx * u.mas).to(u.parsec,
|
|
141
|
+
equivalencies=u.equivalencies.parallax())
|
|
142
|
+
return d
|
|
143
|
+
|
|
134
144
|
def __repr__(self):
|
|
135
145
|
return f'{self.star} (DR3 id={self.dr3_id})'
|
arvi/kima_wrapper.py
CHANGED
|
@@ -1,19 +1,8 @@
|
|
|
1
1
|
import os
|
|
2
|
-
import
|
|
2
|
+
import ast
|
|
3
3
|
|
|
4
4
|
from .setup_logger import setup_logger
|
|
5
5
|
|
|
6
|
-
try:
|
|
7
|
-
import kima
|
|
8
|
-
from kima.pykima.utils import chdir
|
|
9
|
-
from kima import distributions
|
|
10
|
-
from kima import RVData, HGPMdata
|
|
11
|
-
from kima import RVmodel, GPmodel, RVHGPMmodel
|
|
12
|
-
kima_available = True
|
|
13
|
-
except ImportError:
|
|
14
|
-
kima_available = False
|
|
15
|
-
|
|
16
|
-
|
|
17
6
|
def try_to_guess_prior(model, prior):
|
|
18
7
|
if 'jitter' in prior:
|
|
19
8
|
return 'Jprior'
|
|
@@ -23,8 +12,14 @@ def try_to_guess_prior(model, prior):
|
|
|
23
12
|
|
|
24
13
|
|
|
25
14
|
def run_kima(self, run=False, load=False, run_directory=None,
|
|
26
|
-
model=RVmodel, priors={}, **kwargs):
|
|
27
|
-
|
|
15
|
+
model='RVmodel', priors={}, **kwargs):
|
|
16
|
+
try:
|
|
17
|
+
import kima
|
|
18
|
+
from kima.pykima.utils import chdir
|
|
19
|
+
from kima import distributions
|
|
20
|
+
from kima import RVData, HGPMdata
|
|
21
|
+
from kima import RVmodel, GPmodel, RVHGPMmodel
|
|
22
|
+
except ImportError:
|
|
28
23
|
raise ImportError('kima not available, please install with `pip install kima`')
|
|
29
24
|
|
|
30
25
|
logger = setup_logger()
|
|
@@ -57,7 +52,7 @@ def run_kima(self, run=False, load=False, run_directory=None,
|
|
|
57
52
|
model.trend = kwargs.pop('trend', False)
|
|
58
53
|
model.degree = kwargs.pop('degree', 0)
|
|
59
54
|
|
|
60
|
-
if isinstance(model, RVmodel):
|
|
55
|
+
if isinstance(model, (RVmodel, RVHGPMmodel)):
|
|
61
56
|
model.studentt = kwargs.pop('studentt', False)
|
|
62
57
|
|
|
63
58
|
if isinstance(model, GPmodel):
|
|
@@ -81,6 +76,16 @@ def run_kima(self, run=False, load=False, run_directory=None,
|
|
|
81
76
|
model.pm_dec_bary_prior = priors.pop('pm_dec_bary_prior',
|
|
82
77
|
distributions.Gaussian(pm_data.pm_dec_hg, pm_data.sig_hg_dec))
|
|
83
78
|
|
|
79
|
+
KO = kwargs.pop('known_object', False)
|
|
80
|
+
if KO:
|
|
81
|
+
if isinstance(KO, int) and KO is not True:
|
|
82
|
+
model.set_known_object(KO)
|
|
83
|
+
else:
|
|
84
|
+
try:
|
|
85
|
+
model.set_known_object(kwargs.pop('n_known_object'))
|
|
86
|
+
except KeyError:
|
|
87
|
+
msg = 'if `known_object` is True, specify `n_known_object` or pass `known_object` as an integer'
|
|
88
|
+
raise ValueError(msg) from None
|
|
84
89
|
|
|
85
90
|
for k, v in priors.items():
|
|
86
91
|
try:
|
|
@@ -99,21 +104,27 @@ def run_kima(self, run=False, load=False, run_directory=None,
|
|
|
99
104
|
if run_directory is None:
|
|
100
105
|
run_directory = os.getcwd()
|
|
101
106
|
|
|
102
|
-
|
|
103
|
-
# TODO: use signature of kima.run to pop the correct kwargs
|
|
104
|
-
# model_name = model.__class__.__name__
|
|
105
|
-
# model_name = f'kima.{model_name}.{model_name}'
|
|
106
|
-
# signature, defaults = [sig for sig in kima.run.__nb_signature__ if model_name in sig[0]]
|
|
107
|
+
diagnostic = kwargs.pop('diagnostic', False)
|
|
107
108
|
|
|
109
|
+
if run:
|
|
110
|
+
model_name = model.__class__.__name__
|
|
111
|
+
model_name = f'kima.{model_name}.{model_name}'
|
|
112
|
+
signature, _, defaults = [sig for sig in kima._run_really.__nb_signature__ if model_name in sig[0]][0]
|
|
113
|
+
signature = signature.replace('\\', '')
|
|
114
|
+
args = ast.parse(signature + ':\n pass').body[0].args
|
|
115
|
+
defaults = {arg.arg: d for arg, d in zip(args.args[1:], defaults)}
|
|
116
|
+
defaults.update(kwargs)
|
|
108
117
|
with chdir(run_directory):
|
|
109
|
-
kima.run(model, **
|
|
118
|
+
kima.run(model, **defaults)
|
|
110
119
|
|
|
111
120
|
if isinstance(model, RVHGPMmodel):
|
|
112
121
|
data = (data, pm_data)
|
|
113
122
|
|
|
114
123
|
if load:
|
|
115
124
|
with chdir(run_directory):
|
|
116
|
-
res = kima.load_results(model)
|
|
125
|
+
res = kima.load_results(model, diagnostic=diagnostic)
|
|
126
|
+
|
|
127
|
+
res.star = self.star
|
|
117
128
|
return data, model, res
|
|
118
129
|
|
|
119
130
|
return data, model
|
arvi/plots.py
CHANGED
|
@@ -587,6 +587,32 @@ def plot_xy(self, x, y, ax=None, instrument=None, show_legend=True, **kwargs):
|
|
|
587
587
|
return fig, ax
|
|
588
588
|
|
|
589
589
|
|
|
590
|
+
def plot_several(obj, axs=None, **kwargs):
|
|
591
|
+
try:
|
|
592
|
+
from grid_strategy.strategies import SquareStrategy
|
|
593
|
+
except ImportError:
|
|
594
|
+
raise ImportError("Please install 'grid-strategy' to use this function")
|
|
595
|
+
if axs is None:
|
|
596
|
+
if isinstance(obj, (list, tuple)):
|
|
597
|
+
n = len(obj)
|
|
598
|
+
GS = SquareStrategy().get_grid(n)
|
|
599
|
+
fig = plt.gcf()
|
|
600
|
+
fig.set_size_inches(8, 6)
|
|
601
|
+
axs = [fig.add_subplot(gs) for gs in GS]
|
|
602
|
+
else:
|
|
603
|
+
raise NotImplementedError('`obj` should be a list or tuple')
|
|
604
|
+
else:
|
|
605
|
+
assert isinstance(axs, (list, tuple))
|
|
606
|
+
assert len(axs) == len(obj), 'Number of axes does not match number of objects'
|
|
607
|
+
|
|
608
|
+
kwargs.setdefault('show_legend', False)
|
|
609
|
+
kwargs.setdefault('show_title', True)
|
|
610
|
+
|
|
611
|
+
for ax, s in zip(axs, obj):
|
|
612
|
+
s.plot(ax=ax, **kwargs)
|
|
613
|
+
ax.set(xlabel='', ylabel='')
|
|
614
|
+
|
|
615
|
+
|
|
590
616
|
# @plot_fast
|
|
591
617
|
def gls(self, ax=None, label=None, instrument=None,
|
|
592
618
|
fap=True, fap_method='baluev', adjust_means=config.adjust_means_gls,
|
arvi/programs.py
CHANGED
|
@@ -23,6 +23,7 @@ def get_star(star, instrument=None, verbose=False, **kwargs):
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
class LazyRV:
|
|
26
|
+
""" A lazy wrapper around `RV` """
|
|
26
27
|
def __init__(self, stars: list, instrument: str = None,
|
|
27
28
|
_parallel_limit=10, _parallel_workers=8):
|
|
28
29
|
self.stars = stars
|
|
@@ -60,25 +61,6 @@ class LazyRV:
|
|
|
60
61
|
|
|
61
62
|
return result
|
|
62
63
|
|
|
63
|
-
# # use a with statement to ensure threads are cleaned up promptly
|
|
64
|
-
# with concurrent.futures.ThreadPoolExecutor(max_workers=8) as pool:
|
|
65
|
-
# star_to_RV = {
|
|
66
|
-
# pool.submit(get_star, star, self.instrument): star
|
|
67
|
-
# for star in self.stars
|
|
68
|
-
# }
|
|
69
|
-
# logger.info('Querying DACE...')
|
|
70
|
-
# pbar = tqdm(concurrent.futures.as_completed(star_to_RV),
|
|
71
|
-
# total=self.N, unit='star')
|
|
72
|
-
# for future in pbar:
|
|
73
|
-
# star = star_to_RV[future]
|
|
74
|
-
# pbar.set_description(star)
|
|
75
|
-
# try:
|
|
76
|
-
# result.append(future.result())
|
|
77
|
-
# except ValueError:
|
|
78
|
-
# print(f'{star} generated an exception')
|
|
79
|
-
# result.append(None)
|
|
80
|
-
# return result
|
|
81
|
-
|
|
82
64
|
def reload(self, **kwargs):
|
|
83
65
|
self._saved = self._get(**kwargs)
|
|
84
66
|
return self._saved
|
|
@@ -92,12 +74,24 @@ class LazyRV:
|
|
|
92
74
|
return self._saved
|
|
93
75
|
|
|
94
76
|
@lru_cache(maxsize=10)
|
|
95
|
-
def __getitem__(self,
|
|
96
|
-
|
|
77
|
+
def __getitem__(self, index_or_name):
|
|
78
|
+
if isinstance(index_or_name, str):
|
|
79
|
+
index = self.stars.index(index_or_name)
|
|
80
|
+
else:
|
|
81
|
+
index = index_or_name
|
|
82
|
+
|
|
97
83
|
if self._saved is not None:
|
|
98
84
|
return self._saved[index]
|
|
85
|
+
|
|
86
|
+
star = self.stars[index]
|
|
99
87
|
return get_star(star, self.instrument, verbose=True)
|
|
100
88
|
|
|
89
|
+
def plot(self, split=20, **kwargs):
|
|
90
|
+
from .plots import plot_several
|
|
91
|
+
from itertools import batched
|
|
92
|
+
S = list(batched(self.__call__(), split))
|
|
93
|
+
for s in S:
|
|
94
|
+
plot_several(s, **kwargs)
|
|
101
95
|
|
|
102
96
|
# sorted by spectral type
|
|
103
97
|
WG1_stars = [
|
arvi/setup_logger.py
CHANGED
|
@@ -2,17 +2,17 @@ import sys
|
|
|
2
2
|
|
|
3
3
|
def setup_logger():
|
|
4
4
|
from loguru import logger
|
|
5
|
-
try:
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
5
|
+
# try:
|
|
6
|
+
# import marimo as mo
|
|
7
|
+
# if mo.running_in_notebook():
|
|
8
|
+
# return logger
|
|
9
|
+
# raise NotImplementedError
|
|
10
|
+
# except (NotImplementedError, AttributeError):
|
|
11
|
+
# pass
|
|
12
|
+
# except (ImportError, ModuleNotFoundError):
|
|
13
|
+
# logger.remove()
|
|
14
|
+
# else:
|
|
15
|
+
logger.remove()
|
|
16
16
|
logger.configure(extra={"indent": ""})
|
|
17
17
|
logger.add(
|
|
18
18
|
sys.stdout,
|
arvi/simbad_wrapper.py
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from urllib.error import URLError
|
|
2
3
|
import requests
|
|
3
4
|
from dataclasses import dataclass
|
|
4
5
|
from functools import partial
|
|
@@ -64,6 +65,12 @@ JOIN ident ON oidref = oid
|
|
|
64
65
|
WHERE id = '{star}';
|
|
65
66
|
"""
|
|
66
67
|
|
|
68
|
+
OTYPE_QUERY = """
|
|
69
|
+
SELECT otype FROM basic
|
|
70
|
+
JOIN ident ON oidref = oid
|
|
71
|
+
WHERE id = '{star}';
|
|
72
|
+
"""
|
|
73
|
+
|
|
67
74
|
HD_GJ_HIP_QUERY = """
|
|
68
75
|
SELECT id2.id
|
|
69
76
|
FROM ident AS id1 JOIN ident AS id2 USING(oidref)
|
|
@@ -204,11 +211,19 @@ class simbad:
|
|
|
204
211
|
try:
|
|
205
212
|
table2 = run_query(query=BV_QUERY.format(star=self.star))
|
|
206
213
|
if _debug:
|
|
207
|
-
print('table2
|
|
214
|
+
print('table2:\n', table2)
|
|
208
215
|
cols, values = parse_table1(table2, cols, values)
|
|
209
216
|
except IndexError:
|
|
210
217
|
self.B = self.V = np.nan
|
|
211
218
|
|
|
219
|
+
try:
|
|
220
|
+
table21 = run_query(query=OTYPE_QUERY.format(star=self.star))
|
|
221
|
+
if _debug:
|
|
222
|
+
print('table21:\n', table21)
|
|
223
|
+
cols, values = parse_table1(table21, cols, values)
|
|
224
|
+
except IndexError:
|
|
225
|
+
self.otype = None
|
|
226
|
+
|
|
212
227
|
try:
|
|
213
228
|
table3 = run_query(query=IDS_QUERY.format(star=self.star))
|
|
214
229
|
if _debug:
|
|
@@ -228,6 +243,14 @@ class simbad:
|
|
|
228
243
|
setattr(self, '_' + filter_name, ufloat(float(mag), float(mag_err)))
|
|
229
244
|
except ValueError:
|
|
230
245
|
setattr(self, '_' + filter_name, float(mag))
|
|
246
|
+
|
|
247
|
+
# substitute missing V magnitude
|
|
248
|
+
if filter_name == 'V' and values[cols.index('V')] == '':
|
|
249
|
+
values[cols.index('V')] = mag
|
|
250
|
+
# substitute missing B magnitude
|
|
251
|
+
if filter_name == 'B' and values[cols.index('B')] == '':
|
|
252
|
+
values[cols.index('B')] = mag
|
|
253
|
+
|
|
231
254
|
|
|
232
255
|
# measurements table
|
|
233
256
|
table5 = run_query(query=MEAS_QUERY.format(star=self.star))
|
|
@@ -258,6 +281,8 @@ class simbad:
|
|
|
258
281
|
try:
|
|
259
282
|
setattr(self, col, float(val))
|
|
260
283
|
except ValueError:
|
|
284
|
+
if val == '':
|
|
285
|
+
val = None
|
|
261
286
|
setattr(self, col, val)
|
|
262
287
|
|
|
263
288
|
self.coords = SkyCoord(self.ra, self.dec, unit='deg')
|
|
@@ -281,12 +306,17 @@ class simbad:
|
|
|
281
306
|
else:
|
|
282
307
|
self.teff = data['teff']
|
|
283
308
|
self.sweetcat = data
|
|
284
|
-
|
|
309
|
+
except URLError:
|
|
310
|
+
pass
|
|
285
311
|
except IndexError:
|
|
286
|
-
if self.sp_type
|
|
312
|
+
if self.sp_type in (None, ''):
|
|
287
313
|
if len(self.measurements.teff) > 0:
|
|
288
|
-
|
|
289
|
-
|
|
314
|
+
try:
|
|
315
|
+
self.teff = int(np.mean(self.measurements.teff))
|
|
316
|
+
self.sp_type = teff_to_sptype(self.teff)
|
|
317
|
+
except ValueError:
|
|
318
|
+
self.teff = np.nan
|
|
319
|
+
self.sp_type = ''
|
|
290
320
|
elif self.sp_type[:2] in EFFECTIVE_TEMPERATURES:
|
|
291
321
|
self.teff = EFFECTIVE_TEMPERATURES[self.sp_type[:2]]
|
|
292
322
|
|
arvi/sophie_wrapper.py
CHANGED
|
@@ -13,7 +13,7 @@ URL_HEADER = "http://atlas.obs-hp.fr/sophie/sophie.cgi?n=sophiecc&c=i&z=fd&a=t&o
|
|
|
13
13
|
def extract_keyword(keyword, text, raise_error=True):
|
|
14
14
|
for line in text.splitlines():
|
|
15
15
|
if keyword in line:
|
|
16
|
-
value = re.findall(fr'{keyword}\s+([
|
|
16
|
+
value = re.findall(fr'{keyword}\s+([-\'\w\d.]+)', line)[0]
|
|
17
17
|
value = value.replace("'", "")
|
|
18
18
|
try:
|
|
19
19
|
return float(value)
|
arvi/stats.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from functools import partial
|
|
2
2
|
import numpy as np
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
|
|
5
5
|
def wmean(a, e):
|
|
6
6
|
"""Weighted mean of array `a`, with uncertainties given by `e`.
|
|
@@ -69,7 +69,7 @@ weighted_median = partial(weighted_quantiles_interpolate, quantiles=0.5)
|
|
|
69
69
|
|
|
70
70
|
|
|
71
71
|
|
|
72
|
-
def sigmaclip_median(a, low=4.0, high=4.0, k=
|
|
72
|
+
def sigmaclip_median(a, low=4.0, high=4.0, k=None):
|
|
73
73
|
"""
|
|
74
74
|
Same as scipy.stats.sigmaclip but using the median and median absolute
|
|
75
75
|
deviation instead of the mean and standard deviation.
|
|
@@ -91,8 +91,12 @@ def sigmaclip_median(a, low=4.0, high=4.0, k=1/norm.ppf(3/4)):
|
|
|
91
91
|
- `lower`: Lower clipping limit
|
|
92
92
|
- `upper`: Upper clipping limit
|
|
93
93
|
"""
|
|
94
|
-
from scipy.stats import median_abs_deviation
|
|
94
|
+
from scipy.stats import median_abs_deviation, norm
|
|
95
95
|
from scipy.stats._stats_py import SigmaclipResult
|
|
96
|
+
|
|
97
|
+
if k is None:
|
|
98
|
+
k = 1 / norm.ppf(3 / 4)
|
|
99
|
+
|
|
96
100
|
c = np.asarray(a).ravel()
|
|
97
101
|
delta = 1
|
|
98
102
|
while delta:
|
arvi/timeseries.py
CHANGED
|
@@ -145,6 +145,7 @@ class RV(ISSUES, REPORTS):
|
|
|
145
145
|
if self.verbose:
|
|
146
146
|
logger.info('querying Simbad...')
|
|
147
147
|
|
|
148
|
+
# TODO: removing the 'A' might not be a good idea
|
|
148
149
|
# complicated way to query Simbad with self.__star__ or, if that
|
|
149
150
|
# fails, try after removing a trailing 'A'
|
|
150
151
|
for target in set([self.__star__, self.__star__.replace('A', '')]):
|
|
@@ -590,9 +591,12 @@ class RV(ISSUES, REPORTS):
|
|
|
590
591
|
""" Total time span of the (masked) observations """
|
|
591
592
|
return np.ptp(self.mtime)
|
|
592
593
|
|
|
593
|
-
def _index_from_instrument_index(self, index, instrument):
|
|
594
|
+
def _index_from_instrument_index(self, index, instrument, masked=True):
|
|
594
595
|
ind = np.where(self.instrument_array == instrument)[0]
|
|
595
|
-
|
|
596
|
+
if masked:
|
|
597
|
+
return ind[getattr(self, instrument).mask][index]
|
|
598
|
+
else:
|
|
599
|
+
return ind[index]
|
|
596
600
|
|
|
597
601
|
# @property
|
|
598
602
|
def _tt(self, f=20) -> np.ndarray:
|
|
@@ -651,7 +655,11 @@ class RV(ISSUES, REPORTS):
|
|
|
651
655
|
return s
|
|
652
656
|
|
|
653
657
|
@classmethod
|
|
654
|
-
def from_arrays(cls, star, time, vrad, svrad,
|
|
658
|
+
def from_arrays(cls, star, time, vrad, svrad, instrument:str, **kwargs):
|
|
659
|
+
if 'inst' in kwargs:
|
|
660
|
+
logger.warning('`inst` is deprecated. Use `instrument` instead.')
|
|
661
|
+
instrument = kwargs.pop('inst')
|
|
662
|
+
|
|
655
663
|
s = cls(star, _child=True)
|
|
656
664
|
time, vrad, svrad = map(np.atleast_1d, (time, vrad, svrad))
|
|
657
665
|
|
|
@@ -673,8 +681,12 @@ class RV(ISSUES, REPORTS):
|
|
|
673
681
|
for k, v in kwargs.items():
|
|
674
682
|
setattr(s, k, np.atleast_1d(v))
|
|
675
683
|
|
|
676
|
-
s.instruments = [inst]
|
|
677
684
|
s._quantities = np.array(list(kwargs.keys()))
|
|
685
|
+
_instrument = instrument.replace(' ', '_').replace('-', '_')
|
|
686
|
+
s.instruments = [_instrument]
|
|
687
|
+
|
|
688
|
+
setattr(s, _instrument, deepcopy(s))
|
|
689
|
+
s._child = False
|
|
678
690
|
|
|
679
691
|
return s
|
|
680
692
|
|
|
@@ -1039,7 +1051,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1039
1051
|
time = np.array([i.bjd for i in CCFs])
|
|
1040
1052
|
vrad = np.array([i.RV*1e3 for i in CCFs])
|
|
1041
1053
|
svrad = np.array([i.RVerror*1e3 for i in CCFs])
|
|
1042
|
-
_s = RV.from_arrays(star, time, vrad, svrad,
|
|
1054
|
+
_s = RV.from_arrays(star, time, vrad, svrad, instrument=instrument)
|
|
1043
1055
|
|
|
1044
1056
|
_quantities = []
|
|
1045
1057
|
|
|
@@ -1066,9 +1078,13 @@ class RV(ISSUES, REPORTS):
|
|
|
1066
1078
|
_s.texp = np.array([i.HDU[0].header['EXPTIME'] for i in CCFs])
|
|
1067
1079
|
_quantities.append('texp')
|
|
1068
1080
|
|
|
1069
|
-
|
|
1081
|
+
try:
|
|
1082
|
+
_s.berv = np.array([i.HDU[0].header['HIERARCH ESO QC BERV'] for i in CCFs])
|
|
1083
|
+
except KeyError:
|
|
1084
|
+
_s.berv = np.full_like(time, np.nan)
|
|
1070
1085
|
_quantities.append('berv')
|
|
1071
1086
|
|
|
1087
|
+
|
|
1072
1088
|
_s.date_night = np.array([
|
|
1073
1089
|
i.HDU[0].header['DATE-OBS'].split('T')[0] for i in CCFs
|
|
1074
1090
|
])
|
|
@@ -1567,6 +1583,11 @@ class RV(ISSUES, REPORTS):
|
|
|
1567
1583
|
condition (ndarray):
|
|
1568
1584
|
Boolean array of the same length as the observations
|
|
1569
1585
|
"""
|
|
1586
|
+
condition = np.asarray(condition, dtype=bool)
|
|
1587
|
+
if not np.any(condition):
|
|
1588
|
+
if self.verbose:
|
|
1589
|
+
logger.info('no points to remove')
|
|
1590
|
+
return
|
|
1570
1591
|
if self.verbose:
|
|
1571
1592
|
inst = np.unique(self.instrument_array[condition])
|
|
1572
1593
|
logger.info(f"Removing {condition.sum()} points from instruments {inst}")
|
|
@@ -1657,6 +1678,20 @@ class RV(ISSUES, REPORTS):
|
|
|
1657
1678
|
for inst in singles:
|
|
1658
1679
|
self.remove_instrument(inst, strict=True)
|
|
1659
1680
|
|
|
1681
|
+
def remove_more_than_n_per_night(self, n=2):
|
|
1682
|
+
""" Remove whenever there are more than `n` observations per night """
|
|
1683
|
+
ind = np.array([], dtype=int)
|
|
1684
|
+
for s in self:
|
|
1685
|
+
# how many observations per night
|
|
1686
|
+
n_night = (np.abs(s.time[:, None] - s.time[None, :]) < 0.5).sum(axis=0)
|
|
1687
|
+
# indices for this instrument
|
|
1688
|
+
ind_s = np.where(n_night >= n)[0]
|
|
1689
|
+
# translate to indices in self
|
|
1690
|
+
ind_self = self._index_from_instrument_index(ind_s, s.instruments[0], masked=False)
|
|
1691
|
+
ind = np.r_[ind, ind_self]
|
|
1692
|
+
if len(ind) > 0:
|
|
1693
|
+
self.remove_point(ind)
|
|
1694
|
+
|
|
1660
1695
|
def remove_prog_id(self, prog_id):
|
|
1661
1696
|
""" Remove observations from a given program ID """
|
|
1662
1697
|
from glob import has_magic
|
|
@@ -1695,7 +1730,7 @@ class RV(ISSUES, REPORTS):
|
|
|
1695
1730
|
ind = np.where(to_remove)[0]
|
|
1696
1731
|
self.remove_point(ind)
|
|
1697
1732
|
|
|
1698
|
-
def choose_n_points(self, n: int,
|
|
1733
|
+
def choose_n_points(self, n: int, instrument=None, seed=None):
|
|
1699
1734
|
""" Randomly choose `n` observations and mask out the remaining ones
|
|
1700
1735
|
|
|
1701
1736
|
Args:
|
|
@@ -1706,21 +1741,21 @@ class RV(ISSUES, REPORTS):
|
|
|
1706
1741
|
instrument (str or list, optional):
|
|
1707
1742
|
For which instrument to choose points (default is all).
|
|
1708
1743
|
"""
|
|
1709
|
-
|
|
1744
|
+
if not self._check_instrument(instrument):
|
|
1745
|
+
return
|
|
1746
|
+
# instruments = self._check_instrument(instrument)
|
|
1747
|
+
mask_for_this_inst = self._instrument_mask(instrument)
|
|
1710
1748
|
rng = np.random.default_rng(seed=seed)
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
i = rng.choice(available, size=n, replace=False)
|
|
1722
|
-
# mask the others out
|
|
1723
|
-
self.mask[np.setdiff1d(available, i)] = False
|
|
1749
|
+
# only choose if there are more than n points
|
|
1750
|
+
if self.mask[mask_for_this_inst].sum() > n:
|
|
1751
|
+
if self.verbose:
|
|
1752
|
+
logger.info(f'selecting {n} points from {instrument}')
|
|
1753
|
+
# indices of points for this instrument which are not masked already
|
|
1754
|
+
available = np.where(self.mask & mask_for_this_inst)[0]
|
|
1755
|
+
# choose n randomly
|
|
1756
|
+
i = rng.choice(available, size=n, replace=False)
|
|
1757
|
+
# mask the others out
|
|
1758
|
+
self.mask[np.setdiff1d(available, i)] = False
|
|
1724
1759
|
self._propagate_mask_changes()
|
|
1725
1760
|
|
|
1726
1761
|
|
|
@@ -1924,10 +1959,14 @@ class RV(ISSUES, REPORTS):
|
|
|
1924
1959
|
if np.isnan(d[m]).all():
|
|
1925
1960
|
continue
|
|
1926
1961
|
|
|
1927
|
-
result = dosigmaclip(d[m], low=sigma, high=sigma)
|
|
1962
|
+
result = dosigmaclip(d[m & self.mask], low=sigma, high=sigma)
|
|
1928
1963
|
# n = self.vrad[m].size - result.clipped.size
|
|
1929
1964
|
|
|
1930
|
-
|
|
1965
|
+
# NOTE: result.lower and result.upper are updated values, calculated
|
|
1966
|
+
# *after* the last point has been removed. So the previous solution
|
|
1967
|
+
# getting points outside the range [result.lower, result.upper] is
|
|
1968
|
+
# not correct and we need to use result.clipped instead.
|
|
1969
|
+
ind = m & self.mask & ~np.isin(d, result.clipped)
|
|
1931
1970
|
n = ind.sum()
|
|
1932
1971
|
|
|
1933
1972
|
if self.verbose and n > 0:
|
|
@@ -2020,9 +2059,9 @@ class RV(ISSUES, REPORTS):
|
|
|
2020
2059
|
|
|
2021
2060
|
|
|
2022
2061
|
|
|
2023
|
-
def bin(self):
|
|
2062
|
+
def bin(self, daily=False):
|
|
2024
2063
|
"""
|
|
2025
|
-
|
|
2064
|
+
Bin the observations, nightly by default.
|
|
2026
2065
|
|
|
2027
2066
|
!!! Warning
|
|
2028
2067
|
This creates and returns a new object and does not modify self.
|
|
@@ -2033,6 +2072,8 @@ class RV(ISSUES, REPORTS):
|
|
|
2033
2072
|
# store original object
|
|
2034
2073
|
snew._unbinned = deepcopy(self)
|
|
2035
2074
|
|
|
2075
|
+
time_offset = 0.5 if daily else 0.0
|
|
2076
|
+
|
|
2036
2077
|
all_bad_quantities = []
|
|
2037
2078
|
|
|
2038
2079
|
for inst in snew.instruments:
|
|
@@ -2046,7 +2087,8 @@ class RV(ISSUES, REPORTS):
|
|
|
2046
2087
|
if s.mtime.size == 0:
|
|
2047
2088
|
continue
|
|
2048
2089
|
|
|
2049
|
-
tb, vb, svb = binRV(s.mtime, s.mvrad, s.msvrad)
|
|
2090
|
+
tb, vb, svb = binRV(s.mtime + time_offset, s.mvrad, s.msvrad)
|
|
2091
|
+
tb -= time_offset
|
|
2050
2092
|
s.vrad = vb
|
|
2051
2093
|
s.svrad = svb
|
|
2052
2094
|
|
|
@@ -2057,14 +2099,14 @@ class RV(ISSUES, REPORTS):
|
|
|
2057
2099
|
|
|
2058
2100
|
# treat date_night specially, basically doing a group-by
|
|
2059
2101
|
if q == 'date_night':
|
|
2060
|
-
inds = binRV(s.mtime, None, None, binning_indices=True)
|
|
2102
|
+
inds = binRV(s.mtime + time_offset, None, None, binning_indices=True)
|
|
2061
2103
|
setattr(s, q, Q[s.mask][inds])
|
|
2062
2104
|
continue
|
|
2063
2105
|
|
|
2064
2106
|
# treat ccf_mask specially, doing a 'unique' bin
|
|
2065
2107
|
if q == 'ccf_mask':
|
|
2066
2108
|
ccf_mask = getattr(s, q)[s.mask]
|
|
2067
|
-
setattr(s, q, bin_ccf_mask(s.mtime, ccf_mask))
|
|
2109
|
+
setattr(s, q, bin_ccf_mask(s.mtime + time_offset, ccf_mask))
|
|
2068
2110
|
continue
|
|
2069
2111
|
|
|
2070
2112
|
if Q.dtype != np.float64:
|
|
@@ -2079,12 +2121,14 @@ class RV(ISSUES, REPORTS):
|
|
|
2079
2121
|
elif q + '_err' in s._quantities:
|
|
2080
2122
|
Qerr = getattr(s, q + '_err')
|
|
2081
2123
|
if (Qerr == 0.0).all(): # if all errors are NaN, don't use them
|
|
2082
|
-
_, yb = binRV(s.mtime, Q[s.mask],
|
|
2124
|
+
_, yb = binRV(s.mtime + time_offset, Q[s.mask],
|
|
2125
|
+
stat='mean', tstat='mean')
|
|
2083
2126
|
else:
|
|
2084
2127
|
if (Qerr <= 0.0).any(): # if any error is <= 0, set it to NaN
|
|
2085
2128
|
Qerr[Qerr <= 0.0] = np.nan
|
|
2086
2129
|
|
|
2087
|
-
_, yb, eb = binRV(s.mtime, Q[s.mask], Qerr[s.mask],
|
|
2130
|
+
_, yb, eb = binRV(s.mtime + time_offset, Q[s.mask], Qerr[s.mask],
|
|
2131
|
+
remove_nans=False)
|
|
2088
2132
|
setattr(s, q + '_err', eb)
|
|
2089
2133
|
|
|
2090
2134
|
setattr(s, q, yb)
|
|
@@ -2093,7 +2137,7 @@ class RV(ISSUES, REPORTS):
|
|
|
2093
2137
|
with warnings.catch_warnings():
|
|
2094
2138
|
warnings.filterwarnings('ignore', category=RuntimeWarning)
|
|
2095
2139
|
try:
|
|
2096
|
-
_, yb = binRV(s.mtime, Q[s.mask],
|
|
2140
|
+
_, yb = binRV(s.mtime + time_offset, Q[s.mask],
|
|
2097
2141
|
stat=np.nanmean, tstat=np.nanmean)
|
|
2098
2142
|
setattr(s, q, yb)
|
|
2099
2143
|
except TypeError:
|
|
@@ -2395,7 +2439,7 @@ class RV(ISSUES, REPORTS):
|
|
|
2395
2439
|
if new_units not in possible:
|
|
2396
2440
|
msg = f"new_units must be one of 'm/s', 'km/s', 'ms', 'kms', got '{new_units}'"
|
|
2397
2441
|
raise ValueError(msg)
|
|
2398
|
-
|
|
2442
|
+
|
|
2399
2443
|
new_units = possible[new_units]
|
|
2400
2444
|
if new_units == self.units:
|
|
2401
2445
|
return
|
|
@@ -2403,11 +2447,14 @@ class RV(ISSUES, REPORTS):
|
|
|
2403
2447
|
if self.verbose:
|
|
2404
2448
|
logger.info(f"changing units from {self.units} to {new_units}")
|
|
2405
2449
|
|
|
2406
|
-
if new_units == 'm/s' and self.units
|
|
2450
|
+
if new_units == 'm/s' and self.units in ('km/s', 'kms'):
|
|
2407
2451
|
factor = 1e3
|
|
2408
|
-
elif new_units == 'km/s' and self.units
|
|
2452
|
+
elif new_units == 'km/s' and self.units in ('m/s', 'ms'):
|
|
2409
2453
|
factor = 1e-3
|
|
2410
|
-
|
|
2454
|
+
else:
|
|
2455
|
+
logger.warning(f"no known conversion from {self.units} to {new_units}")
|
|
2456
|
+
return
|
|
2457
|
+
|
|
2411
2458
|
for inst in self.instruments:
|
|
2412
2459
|
s = getattr(self, inst)
|
|
2413
2460
|
s.vrad *= factor
|
|
@@ -2469,6 +2516,10 @@ class RV(ISSUES, REPORTS):
|
|
|
2469
2516
|
by_last_observation (bool, optional):
|
|
2470
2517
|
Sort by last observation date
|
|
2471
2518
|
"""
|
|
2519
|
+
if self.N == 0:
|
|
2520
|
+
if self.verbose:
|
|
2521
|
+
logger.warning("no observations to sort")
|
|
2522
|
+
return
|
|
2472
2523
|
if by_last_observation:
|
|
2473
2524
|
by_first_observation = False
|
|
2474
2525
|
if by_first_observation:
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
arvi/HZ.py,sha256=u7rguhlILRBW-LOczlY3dkIB4LM8p8W7Xfg4FnNaYG0,2850
|
|
2
|
-
arvi/__init__.py,sha256=
|
|
2
|
+
arvi/__init__.py,sha256=XpHKf-hlJvZvjnhGia_0DAoL0OHagtR7zknIJwIx_UY,853
|
|
3
3
|
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
|
-
arvi/config.py,sha256=
|
|
7
|
-
arvi/dace_wrapper.py,sha256
|
|
6
|
+
arvi/config.py,sha256=DbOhDKGbNoKVWMd965wY6gAfYf0TdbjR5_WIlHvilcA,2422
|
|
7
|
+
arvi/dace_wrapper.py,sha256=-FHY9xc2Oyf7b_qzbZWy0RtQmLvm770yJeWVV8_8Zwc,27893
|
|
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=JiD0BRix7wD3LXcnaAxWyRkC2M91pVJ2P9DhtzrBavM,4793
|
|
11
11
|
arvi/headers.py,sha256=uvdJebw1M5YkGjE3vJJwYBOnLikib75uuZE9FXB5JJM,1673
|
|
12
12
|
arvi/instrument_specific.py,sha256=94oMb6UeH6tp7H8YXnXHpxEhIz2evz0iYsT_HrNOCTo,12105
|
|
13
13
|
arvi/kepmodel_wrapper.py,sha256=mmHudetAZ4cBxKDwzQzgUydzkjhomCWw5VVuyiKfXq8,10288
|
|
14
|
-
arvi/kima_wrapper.py,sha256=
|
|
14
|
+
arvi/kima_wrapper.py,sha256=T_NjUcbhwPh4gKW4uS2Bki1xKNvZ2LApcYfoJVrkbz8,4541
|
|
15
15
|
arvi/lbl_wrapper.py,sha256=_ViGVkpakvuBR_xhu9XJRV5EKHpj5Go6jBZGJZMIS2Y,11850
|
|
16
16
|
arvi/nasaexo_wrapper.py,sha256=ZKY3IUClqsJuysxDv0Gu51EnzMX7101zQb7UQy_urhI,7431
|
|
17
|
-
arvi/plots.py,sha256=
|
|
18
|
-
arvi/programs.py,sha256=
|
|
17
|
+
arvi/plots.py,sha256=7u-EqZRYod1arakelhNwNZ_EJwxYDcplxn9KgcS33aQ,36131
|
|
18
|
+
arvi/programs.py,sha256=2gTvHcJPEmmf4hXQcHvG487PXe__qsS-S-L_Ip6tgNM,8622
|
|
19
19
|
arvi/reports.py,sha256=a38EZNhyGoSSzJh63wBQCAt3_xhqbpVGcDOXaZWTLXs,11127
|
|
20
|
-
arvi/setup_logger.py,sha256=
|
|
21
|
-
arvi/simbad_wrapper.py,sha256=
|
|
22
|
-
arvi/sophie_wrapper.py,sha256=
|
|
20
|
+
arvi/setup_logger.py,sha256=bRZ0CdYM406IoIKyaLurqGLxq-sQrHry8nSSiZGoMBw,656
|
|
21
|
+
arvi/simbad_wrapper.py,sha256=ID43g5mlORx5pOsk3cMX2dGkKktrFBbzxhzEHeZ-0mw,10937
|
|
22
|
+
arvi/sophie_wrapper.py,sha256=SUNGeOhS8FSlHsF9PTK3QIx8EUbEvmGlyIfogwjhtSc,3441
|
|
23
23
|
arvi/spectra.py,sha256=ebF1ocodTastLx0CyqLSpE8EZNDXBF8riyfxMr3L6H0,7491
|
|
24
|
-
arvi/stats.py,sha256=
|
|
24
|
+
arvi/stats.py,sha256=oV1ouTV_c5bx-akTCXh6WKhoit9LpGHUw0xhR7RF0kY,3566
|
|
25
25
|
arvi/stellar.py,sha256=GQ7yweuBRnfkJ0M5eWjvLd8uvGq_by81PbXfidBvWis,4918
|
|
26
|
-
arvi/timeseries.py,sha256=
|
|
26
|
+
arvi/timeseries.py,sha256=shQxIjbsWS3l2x5dh9VWk61bTbmZvQmMIvXjMHPDPDI,106826
|
|
27
27
|
arvi/translations.py,sha256=PUSrn4zvYO2MqGzUxlFGwev_tBkgJaJrIYs6NKHzbWo,951
|
|
28
28
|
arvi/utils.py,sha256=MuAgjyXr297Sm_T6QmB1riVUktyT9ud1qngGMgKlXMc,10863
|
|
29
29
|
arvi/data/info.svg,sha256=0IMI6W-eFoTD8acnury79WJJakpBwLa4qKS4JWpsXiI,489
|
|
@@ -32,8 +32,8 @@ arvi/data/obs_affected_blue_cryostat_issues.dat,sha256=z4AK17xfz8tGTDv1FjRvQFnio
|
|
|
32
32
|
arvi/data/extra/HD86226_PFS1.rdb,sha256=vfAozbrKHM_j8dYkCBJsuHyD01KEM1asghe2KInwVao,3475
|
|
33
33
|
arvi/data/extra/HD86226_PFS2.rdb,sha256=F2P7dB6gVyzCglUjNheB0hIHVClC5RmARrGwbrY1cfo,4114
|
|
34
34
|
arvi/data/extra/metadata.json,sha256=C69hIw6CohyES6BI9vDWjxwSz7N4VOYX0PCgjXtYFmU,178
|
|
35
|
-
arvi-0.2.
|
|
36
|
-
arvi-0.2.
|
|
37
|
-
arvi-0.2.
|
|
38
|
-
arvi-0.2.
|
|
39
|
-
arvi-0.2.
|
|
35
|
+
arvi-0.3.2.dist-info/licenses/LICENSE,sha256=6JfQgl7SpM55t0EHMFNMnNh-AdkpGW25MwMiTnhdWQg,1068
|
|
36
|
+
arvi-0.3.2.dist-info/METADATA,sha256=FmP8zMlErd55jcJNCbH_KSG5ergHedbcpwQOBpCOwZw,1932
|
|
37
|
+
arvi-0.3.2.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
38
|
+
arvi-0.3.2.dist-info/top_level.txt,sha256=4EeiKDVLD45ztuflTGfQ3TU8GVjJg5Y95xS5XjI-utU,5
|
|
39
|
+
arvi-0.3.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|