ACID-code 0.0.0__py3-none-any.whl → 0.1.0__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.
- ACID_code/ACID.py +104 -91
- ACID_code/LSD_func_faster.py +84 -43
- ACID_code/__init__.py +1 -1
- {ACID_code-0.0.0.dist-info → ACID_code-0.1.0.dist-info}/METADATA +3 -1
- ACID_code-0.1.0.dist-info/RECORD +8 -0
- ACID/ACID.py +0 -839
- ACID/LSD_func_faster.py +0 -1054
- ACID/__init__.py +0 -1
- ACID/easy_test.py +0 -44
- ACID_code/easy_test.py +0 -44
- ACID_code-0.0.0.dist-info/RECORD +0 -13
- {ACID_code-0.0.0.dist-info → ACID_code-0.1.0.dist-info}/LICENSE +0 -0
- {ACID_code-0.0.0.dist-info → ACID_code-0.1.0.dist-info}/WHEEL +0 -0
- {ACID_code-0.0.0.dist-info → ACID_code-0.1.0.dist-info}/top_level.txt +0 -0
ACID_code/ACID.py
CHANGED
|
@@ -2,8 +2,8 @@ import numpy as np
|
|
|
2
2
|
import emcee
|
|
3
3
|
import matplotlib.pyplot as plt
|
|
4
4
|
from scipy.optimize import minimize
|
|
5
|
-
from astropy.io import
|
|
6
|
-
import LSD_func_faster as LSD
|
|
5
|
+
from astropy.io import fits
|
|
6
|
+
import ACID_code.LSD_func_faster as LSD
|
|
7
7
|
import glob
|
|
8
8
|
from scipy.interpolate import interp1d
|
|
9
9
|
from scipy.signal import find_peaks
|
|
@@ -11,6 +11,8 @@ import multiprocessing as mp
|
|
|
11
11
|
from functools import partial
|
|
12
12
|
from multiprocessing import Pool
|
|
13
13
|
from statistics import stdev
|
|
14
|
+
import time
|
|
15
|
+
import warnings
|
|
14
16
|
|
|
15
17
|
from math import log10, floor
|
|
16
18
|
|
|
@@ -29,8 +31,6 @@ directory = '/Users/lucydolan/Starbase/HD189733 old/HD189733/'
|
|
|
29
31
|
# run_name = input('Input nickname for this version of code (for saving figures): ')
|
|
30
32
|
run_name = 'test'
|
|
31
33
|
|
|
32
|
-
ccf_rvs = []
|
|
33
|
-
|
|
34
34
|
def findfiles(directory, file_type):
|
|
35
35
|
|
|
36
36
|
filelist1=glob.glob('%s/*/*%s**A_corrected*.fits'%(directory, file_type)) #finding corrected spectra
|
|
@@ -129,8 +129,8 @@ def read_in_frames(order, filelist, file_type):
|
|
|
129
129
|
if i+binsize<len(reference_wave):
|
|
130
130
|
waves = reference_wave[i:i+binsize]
|
|
131
131
|
flux = div_frame[i:i+binsize]
|
|
132
|
-
waves = waves[abs(flux-np.median(
|
|
133
|
-
flux = flux[abs(flux-np.median(
|
|
132
|
+
waves = waves[abs(flux-np.median(flux))<0.1]
|
|
133
|
+
flux = flux[abs(flux-np.median(flux))<0.1]
|
|
134
134
|
binned.append(np.median(flux))
|
|
135
135
|
binned_waves.append(np.median(waves))
|
|
136
136
|
|
|
@@ -150,6 +150,19 @@ def read_in_frames(order, filelist, file_type):
|
|
|
150
150
|
|
|
151
151
|
return frame_wavelengths, frames, errors, sns, telluric_spec
|
|
152
152
|
|
|
153
|
+
def calc_deltav(wavelengths):
|
|
154
|
+
"""Calculates velocity pixel size
|
|
155
|
+
|
|
156
|
+
Calculates the velocity pixel size for the LSD velocity grid based off the spectral wavelengths.
|
|
157
|
+
|
|
158
|
+
Args:
|
|
159
|
+
wavelengths (array): Wavelengths for ACID input spectrum (in Angstroms).
|
|
160
|
+
|
|
161
|
+
Returns:
|
|
162
|
+
float: Velocity pixel size in km/s
|
|
163
|
+
"""
|
|
164
|
+
resol1 = (wavelengths[-1]-wavelengths[0])/len(wavelengths)
|
|
165
|
+
return resol1/(wavelengths[0]+((wavelengths[-1]-wavelengths[0])/2))*2.99792458e5
|
|
153
166
|
|
|
154
167
|
def combine_spec(wavelengths_f, spectra_f, errors_f, sns_f):
|
|
155
168
|
|
|
@@ -157,6 +170,10 @@ def combine_spec(wavelengths_f, spectra_f, errors_f, sns_f):
|
|
|
157
170
|
#combine all spectra to one spectrum
|
|
158
171
|
for n in range(len(wavelengths_f)):
|
|
159
172
|
|
|
173
|
+
global reference_wave
|
|
174
|
+
idx_ref = (sns_f==np.max(sns_f))
|
|
175
|
+
reference_wave = wavelengths_f[idx_ref][0]
|
|
176
|
+
|
|
160
177
|
idx = np.where(wavelengths_f[n] != 0)[0]
|
|
161
178
|
|
|
162
179
|
f2 = interp1d(wavelengths_f[n][idx], spectra_f[n][idx], kind = 'linear', bounds_error=False, fill_value = 'extrapolate')
|
|
@@ -256,7 +273,7 @@ def log_likelihood(theta, x, y, yerr):
|
|
|
256
273
|
|
|
257
274
|
return lnlike
|
|
258
275
|
|
|
259
|
-
## imposes the prior restrictions on the inputs - rejects if profile point
|
|
276
|
+
## imposes the prior restrictions on the inputs - rejects if profile point is less than -10 or greater than 0.5.
|
|
260
277
|
def log_prior(theta):
|
|
261
278
|
|
|
262
279
|
check = 0
|
|
@@ -269,7 +286,6 @@ def log_prior(theta):
|
|
|
269
286
|
else:
|
|
270
287
|
check = 1
|
|
271
288
|
|
|
272
|
-
|
|
273
289
|
if check==0:
|
|
274
290
|
|
|
275
291
|
# excluding the continuum points in the profile (in flux)
|
|
@@ -305,67 +321,41 @@ def residual_mask(wavelengths, data_spec_in, data_err, initial_inputs, poly_ord,
|
|
|
305
321
|
a = 2/(np.max(wavelengths)-np.min(wavelengths))
|
|
306
322
|
b = 1 - a*np.max(wavelengths)
|
|
307
323
|
|
|
308
|
-
# plt.figure()
|
|
309
324
|
mdl1=0
|
|
310
325
|
for i in range(k_max,len(initial_inputs)-1):
|
|
311
326
|
mdl1 = mdl1 + (initial_inputs[i]*((wavelengths*a)+b)**(i-k_max))
|
|
312
327
|
|
|
313
328
|
mdl1 = mdl1 * initial_inputs[-1]
|
|
314
329
|
|
|
315
|
-
# residuals = data_spec_in/mdl1 -1
|
|
316
|
-
# ### finds consectuative sections where at least 40 points have no conitnuum points in between - these are masked
|
|
317
|
-
# flag = ['False']*len(residuals)
|
|
318
|
-
# flagged = []
|
|
319
|
-
# for i in range(len(residuals)):
|
|
320
|
-
# if abs(residuals[i])>0.1:
|
|
321
|
-
# flag[i] = 'True'
|
|
322
|
-
# if i>0 and flag[i-1] == 'True':
|
|
323
|
-
# flagged.append(i-1)
|
|
324
|
-
# else:
|
|
325
|
-
# if len(flagged)>0:
|
|
326
|
-
# flagged.append(i-1)
|
|
327
|
-
# # print(abs(np.median(residuals[flagged[0]:flagged[-1]])))
|
|
328
|
-
# if len(flagged)<300:
|
|
329
|
-
# for no in flagged:
|
|
330
|
-
# flag[no] = 'False'
|
|
331
|
-
# else:
|
|
332
|
-
# idx = np.logical_and(wavelengths>=wavelengths[np.min(flagged)]-1, wavelengths<=wavelengths[np.max(flagged)]+1)
|
|
333
|
-
# data_err[idx]=10000000000000000000
|
|
334
|
-
# flagged = []
|
|
335
|
-
|
|
336
330
|
residuals = (data_spec_in - np.min(data_spec_in))/(np.max(data_spec_in)-np.min(data_spec_in)) - (forward - np.min(forward))/(np.max(forward)-np.min(forward))
|
|
337
331
|
|
|
332
|
+
data_err_compare = data_err.copy()
|
|
333
|
+
|
|
338
334
|
### finds consectuative sections where at least pix_chunk points have residuals greater than 0.25 - these are masked
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
idx = np.logical_and(wavelengths>=wavelengths[np.min(flagged)]-1, wavelengths<=wavelengths[np.max(flagged)]+1)
|
|
354
|
-
data_err[idx]=10000000000000000000
|
|
355
|
-
flagged = []
|
|
335
|
+
idx = (abs(residuals)>dev_perc/100)
|
|
336
|
+
|
|
337
|
+
flag_min = 0
|
|
338
|
+
flag_max = 0
|
|
339
|
+
for value in range(len(idx)):
|
|
340
|
+
if idx[value] == True and flag_min <= value:
|
|
341
|
+
flag_min = value
|
|
342
|
+
flag_max = value
|
|
343
|
+
elif idx[value] == True and flag_max < value:
|
|
344
|
+
flag_max = value
|
|
345
|
+
elif idx[value] == False and flag_max-flag_min>=pix_chunk:
|
|
346
|
+
data_err[flag_min:flag_max]=10000000000000000000
|
|
347
|
+
flag_min = value
|
|
348
|
+
flag_max = value
|
|
356
349
|
|
|
357
350
|
##############################################
|
|
358
351
|
# TELLURICS #
|
|
359
352
|
##############################################
|
|
360
353
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
limit_wave =21/2.99792458e5 #needs multiplied by wavelength to give actual limit
|
|
364
|
-
limit_pix = limit_wave/((max(wavelengths)-min(wavelengths))/len(wavelengths))
|
|
354
|
+
# data_err_compare = data_err.copy()
|
|
365
355
|
|
|
366
|
-
|
|
356
|
+
## masking tellurics
|
|
367
357
|
for line in tell_lines:
|
|
368
|
-
limit =
|
|
358
|
+
limit = (21/2.99792458e5)*line +3
|
|
369
359
|
idx = np.logical_and((line-limit)<=wavelengths, wavelengths<=(limit+line))
|
|
370
360
|
data_err[idx] = 1000000000000000000
|
|
371
361
|
|
|
@@ -398,7 +388,7 @@ def residual_mask(wavelengths, data_spec_in, data_err, initial_inputs, poly_ord,
|
|
|
398
388
|
|
|
399
389
|
return data_err, np.concatenate((profile, poly_inputs)), residual_masks
|
|
400
390
|
|
|
401
|
-
def get_profiles(all_frames,
|
|
391
|
+
def get_profiles(all_frames, order, poly_cos, continuum_error, counter):
|
|
402
392
|
flux = frames[counter]
|
|
403
393
|
error = frame_errors[counter]
|
|
404
394
|
wavelengths = frame_wavelengths[counter]
|
|
@@ -412,33 +402,18 @@ def get_profiles(all_frames, counter, order, poly_cos):
|
|
|
412
402
|
mdl1 = mdl1+poly_cos[i]*((a*wavelengths)+b)**(i)
|
|
413
403
|
mdl1 = mdl1*poly_cos[-1]
|
|
414
404
|
|
|
415
|
-
#masking based off residuals
|
|
416
|
-
|
|
417
|
-
|
|
405
|
+
#masking based off residuals interpolated onto new wavelength grid
|
|
406
|
+
if len(frame_wavelengths)>1:
|
|
407
|
+
reference_wave = frame_wavelengths[sns==max(sns)][0]
|
|
408
|
+
else:
|
|
409
|
+
reference_wave = frame_wavelengths[0]
|
|
418
410
|
mask_pos = np.ones(reference_wave.shape)
|
|
419
411
|
mask_pos[mask_idx]=10000000000000000000
|
|
420
412
|
f2 = interp1d(reference_wave, mask_pos, bounds_error = False, fill_value = np.nan)
|
|
421
413
|
interp_mask_pos = f2(wavelengths)
|
|
422
414
|
interp_mask_idx = tuple([interp_mask_pos>=10000000000000000000])
|
|
423
|
-
|
|
424
415
|
|
|
425
416
|
error[interp_mask_idx]=10000000000000000000
|
|
426
|
-
|
|
427
|
-
# finding error for the continuuum fit
|
|
428
|
-
inds = np.random.randint(len(flat_samples), size=50)
|
|
429
|
-
conts = []
|
|
430
|
-
for ind in inds:
|
|
431
|
-
sample = flat_samples[ind]
|
|
432
|
-
mdl = model_func(sample, wavelengths)
|
|
433
|
-
#mdl = model_func(sample, x)
|
|
434
|
-
#mdl = mdl[idx]
|
|
435
|
-
mdl1_temp = 0
|
|
436
|
-
for i in np.arange(k_max, len(sample)-1):
|
|
437
|
-
mdl1_temp = mdl1_temp+sample[i]*((a*wavelengths)+b)**(i-k_max)
|
|
438
|
-
mdl1_temp = mdl1_temp*sample[-1]
|
|
439
|
-
conts.append(mdl1_temp)
|
|
440
|
-
|
|
441
|
-
continuum_error = np.std(np.array(conts), axis = 0)
|
|
442
417
|
|
|
443
418
|
# corrrecting continuum
|
|
444
419
|
error = (error/flux) + (continuum_error/mdl1)
|
|
@@ -521,7 +496,7 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
521
496
|
line (str): Path to linelist. Takes VALD linelist in long or short format as input. Minimum line depth input into VALD must be less than 1/(3*SN) where SN is the highest signal-to-noise ratio of the spectra.
|
|
522
497
|
frame_sns (list): Average signal-to-noise ratio for each frame (used to calculate minimum line depth to consider from line list.
|
|
523
498
|
vgrid (array): Velocity grid for LSD profiles (in km/s).
|
|
524
|
-
all_frames (str or array, optional): Output array for resulting profiles. Only neccessary if looping ACID function over many wavelength regions or order (in the case of echelle spectra). General shape needs to be (no. of frames,
|
|
499
|
+
all_frames (str or array, optional): Output array for resulting profiles. Only neccessary if looping ACID function over many wavelength regions or order (in the case of echelle spectra). General shape needs to be (no. of frames, 1, 2, no. of velocity pixels).
|
|
525
500
|
poly_or (int, optional): Order of polynomial to fit as the continuum.
|
|
526
501
|
pix_chunk (int, optional): Size of 'bad' regions in pixels. 'bad' areas are identified by the residuals between an inital model and the data. If a residual deviates by a specified percentage (dev_perv) for a specified number of pixels (pix_chunk) it is masked. The smaller the region the less aggresive the masking applied will be.
|
|
527
502
|
dev_perc (int, optional): Allowed deviation percentage. 'bad' areas are identified by the residuals between an inital model and the data. If a residual deviates by a specified percentage (dev_perv) for a specified number of pixels (pix_chunk) it is masked. The smaller the deviation percentage the less aggresive the masking applied will be.
|
|
@@ -532,6 +507,9 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
532
507
|
Returns:
|
|
533
508
|
array: Resulting profiles and errors for spectra.
|
|
534
509
|
"""
|
|
510
|
+
print('Initialising...')
|
|
511
|
+
|
|
512
|
+
t0 = time.time()
|
|
535
513
|
|
|
536
514
|
global velocities
|
|
537
515
|
velocities = vgrid.copy()
|
|
@@ -550,8 +528,9 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
550
528
|
frame_errors = np.array(input_spectral_errors)
|
|
551
529
|
sns = np.array(frame_sns)
|
|
552
530
|
|
|
553
|
-
if all_frames
|
|
554
|
-
all_frames
|
|
531
|
+
if type(all_frames)!=np.ndarray:
|
|
532
|
+
if all_frames=='default':
|
|
533
|
+
all_frames = np.zeros((len(frames), 1, 2, len(velocities)))
|
|
555
534
|
|
|
556
535
|
fw = frame_wavelengths.copy()
|
|
557
536
|
f = frames.copy()
|
|
@@ -562,15 +541,20 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
562
541
|
wavelengths, fluxes, flux_error_order, sn = combine_spec(fw, f, fe, s)
|
|
563
542
|
else: wavelengths, fluxes, flux_error_order, sn = fw[0], f[0], fe[0], s[0]
|
|
564
543
|
|
|
565
|
-
|
|
544
|
+
### getting the initial polynomial coefficents
|
|
566
545
|
a = 2/(np.max(wavelengths)-np.min(wavelengths))
|
|
567
546
|
b = 1 - a*np.max(wavelengths)
|
|
568
547
|
poly_inputs, fluxes1, flux_error_order1, fit = continuumfit(fluxes, (wavelengths*a)+b, flux_error_order, poly_ord)
|
|
569
548
|
|
|
549
|
+
# t2 = time.time()
|
|
550
|
+
# print('Set up before LSD %s'%(t2-t0))
|
|
570
551
|
#### getting the initial profile
|
|
571
552
|
global alpha
|
|
572
553
|
velocities, profile, profile_errors, alpha, continuum_waves, continuum_flux, no_line= LSD.LSD(wavelengths, fluxes1, flux_error_order1, linelist, 'False', poly_ord, sn, 30, run_name, velocities)
|
|
573
554
|
|
|
555
|
+
# t3 = time.time()
|
|
556
|
+
# print('LSD run takes: %s'%(t3-t2))
|
|
557
|
+
|
|
574
558
|
## Setting the number of points in vgrid (k_max)
|
|
575
559
|
global k_max
|
|
576
560
|
k_max = len(profile)
|
|
@@ -590,6 +574,9 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
590
574
|
|
|
591
575
|
yerr, model_inputs_resi, mask_idx = residual_mask(x, y, yerr, model_inputs, poly_ord, linelist, pix_chunk=pix_chunk, dev_perc=dev_perc, tell_lines = telluric_lines, n_sig=n_sig)
|
|
592
576
|
|
|
577
|
+
# t4 = time.time()
|
|
578
|
+
# print('residual masking takes: %s' %(t4-t3))
|
|
579
|
+
|
|
593
580
|
## setting number of walkers and their start values(pos)
|
|
594
581
|
ndim = len(model_inputs)
|
|
595
582
|
nwalkers= ndim*3
|
|
@@ -612,12 +599,17 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
612
599
|
## the number of steps is how long it runs for - if it doesn't look like it's settling at a value try increasing the number of steps
|
|
613
600
|
steps_no = 8000
|
|
614
601
|
|
|
615
|
-
|
|
616
|
-
|
|
602
|
+
t1 = time.time()
|
|
603
|
+
# print('MCMC set up takes: %s'%(t1-t4))
|
|
604
|
+
# print('Initialised in %ss'%round((t1-t0), 2))
|
|
605
|
+
|
|
606
|
+
print('Fitting the Continuum...')
|
|
607
|
+
# sampler = emcee.EnsembleSampler(nwalkers, ndim, log_probability, args=(x, y, yerr))
|
|
608
|
+
# sampler.run_mcmc(pos, steps_no, progress=True)
|
|
617
609
|
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
610
|
+
with Pool() as pool:
|
|
611
|
+
sampler = emcee.EnsembleSampler(nwalkers, ndim, log_probability, args=(x, y, yerr), pool=pool)
|
|
612
|
+
sampler.run_mcmc(pos, steps_no, progress=True)
|
|
621
613
|
|
|
622
614
|
## discarding all vales except the last 1000 steps.
|
|
623
615
|
dis_no = int(np.floor(steps_no-1000))
|
|
@@ -648,7 +640,6 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
648
640
|
profile = np.array(profile)
|
|
649
641
|
profile_err = np.array(profile_err)
|
|
650
642
|
|
|
651
|
-
|
|
652
643
|
fig_opt = 'n'
|
|
653
644
|
if fig_opt =='y':
|
|
654
645
|
|
|
@@ -748,13 +739,34 @@ def ACID(input_wavelengths, input_spectra, input_spectral_errors, line, frame_sn
|
|
|
748
739
|
ax0.legend()
|
|
749
740
|
plt.savefig('figures/final_profile_%s'%(run_name))
|
|
750
741
|
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
#
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
for
|
|
757
|
-
|
|
742
|
+
print('Getting the final profiles...')
|
|
743
|
+
|
|
744
|
+
# finding error for the continuuum fit
|
|
745
|
+
inds = np.random.randint(len(flat_samples), size=50)
|
|
746
|
+
conts = []
|
|
747
|
+
for ind in inds:
|
|
748
|
+
sample = flat_samples[ind]
|
|
749
|
+
mdl = model_func(sample, wavelengths)
|
|
750
|
+
#mdl = model_func(sample, x)
|
|
751
|
+
#mdl = mdl[idx]
|
|
752
|
+
mdl1_temp = 0
|
|
753
|
+
for i in np.arange(k_max, len(sample)-1):
|
|
754
|
+
mdl1_temp = mdl1_temp+sample[i]*((a*wavelengths)+b)**(i-k_max)
|
|
755
|
+
mdl1_temp = mdl1_temp*sample[-1]
|
|
756
|
+
conts.append(mdl1_temp)
|
|
757
|
+
|
|
758
|
+
continuum_error = np.std(np.array(conts), axis = 0)
|
|
759
|
+
|
|
760
|
+
task_part = partial(get_profiles, all_frames, order, poly_cos, continuum_error)
|
|
761
|
+
if len(frames)>1:
|
|
762
|
+
with mp.Pool(mp.cpu_count()) as pool:
|
|
763
|
+
results=[pool.map(task_part, np.arange(len(frames)))]
|
|
764
|
+
results = np.array(results[0])
|
|
765
|
+
for i in range(len(frames)):
|
|
766
|
+
all_frames[i]=results[i][i]
|
|
767
|
+
# for counter in range(len(frames)):
|
|
768
|
+
# all_frames = get_profiles(all_frames, order, poly_cos, continuum_error, counter)
|
|
769
|
+
else: all_frames = get_profiles(all_frames, order, poly_cos, continuum_error, 0)
|
|
758
770
|
|
|
759
771
|
return all_frames
|
|
760
772
|
|
|
@@ -797,6 +809,7 @@ def ACID_HARPS(filelist, line, vgrid, poly_or=3, order_range=np.arange(10,70), s
|
|
|
797
809
|
global frame_errors
|
|
798
810
|
global sns
|
|
799
811
|
|
|
812
|
+
|
|
800
813
|
for order in order_range:
|
|
801
814
|
|
|
802
815
|
print('Running for order %s/%s...'%(order-min(order_range)+1, max(order_range)-min(order_range)+1))
|
ACID_code/LSD_func_faster.py
CHANGED
|
@@ -3,12 +3,15 @@ from scipy import linalg
|
|
|
3
3
|
from astropy.io import fits
|
|
4
4
|
import glob
|
|
5
5
|
import matplotlib.pyplot as plt
|
|
6
|
-
|
|
6
|
+
import time
|
|
7
7
|
from scipy.signal import find_peaks
|
|
8
8
|
from scipy.interpolate import interp1d,LSQUnivariateSpline
|
|
9
|
+
import warnings
|
|
9
10
|
|
|
10
11
|
def LSD(wavelengths, flux_obs, rms, linelist, adjust_continuum, poly_ord, sn, order, run_name, velocities):
|
|
11
12
|
|
|
13
|
+
# t0 = time.time()
|
|
14
|
+
|
|
12
15
|
#idx = tuple([flux_obs>0])
|
|
13
16
|
# in optical depth space
|
|
14
17
|
rms = rms/flux_obs
|
|
@@ -20,49 +23,76 @@ def LSD(wavelengths, flux_obs, rms, linelist, adjust_continuum, poly_ord, sn, or
|
|
|
20
23
|
linelist_expected = np.genfromtxt('%s'%linelist, skip_header=4, delimiter=',', usecols=(1,9))
|
|
21
24
|
wavelengths_expected1 =np.array(linelist_expected[:,0])
|
|
22
25
|
depths_expected1 = np.array(linelist_expected[:,1])
|
|
23
|
-
# print(len(depths_expected1))
|
|
24
26
|
|
|
25
27
|
wavelength_min = np.min(wavelengths)
|
|
26
28
|
wavelength_max = np.max(wavelengths)
|
|
27
29
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
pass
|
|
40
|
-
|
|
41
|
-
depths_expected1 = np.array(depths_expected)
|
|
42
|
-
depths_expected = -np.log(1-depths_expected1)
|
|
30
|
+
idx = np.logical_and(wavelengths_expected1>=wavelength_min, wavelengths_expected1<=wavelength_max)
|
|
31
|
+
wavelengths_expected=wavelengths_expected1[idx]
|
|
32
|
+
depths_expected=depths_expected1[idx]
|
|
33
|
+
|
|
34
|
+
line_min = 1/(3*sn)
|
|
35
|
+
idx = (depths_expected>=line_min)
|
|
36
|
+
wavelengths_expected = wavelengths_expected[idx]
|
|
37
|
+
depths_expected = depths_expected[idx]
|
|
38
|
+
no_line = len(depths_expected)
|
|
39
|
+
|
|
40
|
+
depths_expected = -np.log(1-depths_expected)
|
|
43
41
|
|
|
44
42
|
blankwaves=wavelengths
|
|
45
43
|
R_matrix=flux_obs
|
|
46
44
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
45
|
+
# t1 = time.time()
|
|
46
|
+
# print('Time is %s'%(t1-t0))
|
|
47
|
+
|
|
48
|
+
# Calculate vdiff for all combinations of blankwaves and wavelengths_expected
|
|
49
|
+
vdiff = ((blankwaves[:, np.newaxis] - wavelengths_expected) * 2.99792458e5) / wavelengths_expected
|
|
50
|
+
|
|
51
|
+
# Create masks for vdiff that satisfy velocity range conditions
|
|
52
|
+
velocity_mask = np.logical_and(vdiff <= (np.max(velocities) + deltav), vdiff >= (np.min(velocities) - deltav))
|
|
53
|
+
|
|
54
|
+
# Find differences and velocities
|
|
55
|
+
diff = blankwaves[:, np.newaxis] - wavelengths_expected
|
|
56
|
+
vel = 2.99792458e5 * (diff / wavelengths_expected)
|
|
57
|
+
|
|
58
|
+
# Calculate x and delta_x for valid velocities
|
|
59
|
+
if len(wavelengths)<= 7000:
|
|
60
|
+
x = (vel[:, :, np.newaxis] - velocities) / deltav
|
|
61
|
+
alpha_mask_1 = np.logical_and(-1. < x, x < 0.)
|
|
62
|
+
alpha_mask_2 = np.logical_and(0. <= x, x < 1.)
|
|
63
|
+
delta_x_1 = 1 + x
|
|
64
|
+
delta_x_2 = 1 - x
|
|
65
|
+
delta_x_1[alpha_mask_1==False]=0
|
|
66
|
+
delta_x_2[alpha_mask_2==False]=0
|
|
67
|
+
|
|
68
|
+
# Update alpha array using calculated delta_x values
|
|
69
|
+
alpha = np.zeros((len(blankwaves), len(velocities)))
|
|
70
|
+
alpha += (depths_expected[:, np.newaxis] * delta_x_1).sum(axis=1)
|
|
71
|
+
alpha += (depths_expected[:, np.newaxis] * delta_x_2).sum(axis=1)
|
|
72
|
+
else:
|
|
73
|
+
warnings.warn('Large wavelength ranges give large computation time. Seperate wavelength range into smaller chunks for faster computation.', DeprecationWarning, stacklevel=2)
|
|
74
|
+
alpha=np.zeros((len(blankwaves), len(velocities)))
|
|
75
|
+
|
|
76
|
+
for j in range(0, len(blankwaves)):
|
|
77
|
+
for i in (range(0,len(wavelengths_expected))):
|
|
78
|
+
vdiff = ((blankwaves[j] - wavelengths_expected[i])*2.99792458e5)/wavelengths_expected[i]
|
|
79
|
+
if vdiff<=(np.max(velocities)+deltav) and vdiff>=(np.min(velocities)-deltav):
|
|
80
|
+
diff=blankwaves[j]-wavelengths_expected[i]
|
|
81
|
+
vel=2.99792458e5*(diff/wavelengths_expected[i])
|
|
82
|
+
for k in range(0, len(velocities)):
|
|
83
|
+
x=(velocities[k]-vel)/deltav
|
|
84
|
+
if -1.<x and x<0.:
|
|
85
|
+
delta_x=(1+x)
|
|
86
|
+
alpha[j, k] = alpha[j, k]+depths_expected[i]*delta_x
|
|
87
|
+
elif 0.<=x and x<1.:
|
|
88
|
+
delta_x=(1-x)
|
|
89
|
+
alpha[j, k] = alpha[j, k]+depths_expected[i]*delta_x
|
|
90
|
+
else:
|
|
91
|
+
pass
|
|
92
|
+
|
|
93
|
+
# t2 = time.time()
|
|
94
|
+
# print('Alpha time: %s'%(t2-t1))
|
|
95
|
+
|
|
66
96
|
id_matrix=np.identity(len(flux_obs))
|
|
67
97
|
S_matrix=(1/rms)*id_matrix
|
|
68
98
|
|
|
@@ -70,7 +100,7 @@ def LSD(wavelengths, flux_obs, rms, linelist, adjust_continuum, poly_ord, sn, or
|
|
|
70
100
|
alpha_transpose=(np.transpose(alpha))
|
|
71
101
|
|
|
72
102
|
RHS_1=np.dot(alpha_transpose, S_squared)
|
|
73
|
-
RHS_final=np.dot(RHS_1, R_matrix
|
|
103
|
+
RHS_final=np.dot(RHS_1, R_matrix)
|
|
74
104
|
|
|
75
105
|
LHS_preinvert=np.dot(RHS_1, alpha)
|
|
76
106
|
LHS_prep=np.matrix(LHS_preinvert)
|
|
@@ -87,6 +117,9 @@ def LSD(wavelengths, flux_obs, rms, linelist, adjust_continuum, poly_ord, sn, or
|
|
|
87
117
|
profile_errors_squared=np.diagonal(LHS_final)
|
|
88
118
|
profile_errors=np.sqrt(profile_errors_squared)
|
|
89
119
|
|
|
120
|
+
# t3 = time.time()
|
|
121
|
+
# print('Matrix multiplication time: %s'%(t3-t2))
|
|
122
|
+
|
|
90
123
|
return velocities, profile, profile_errors, alpha, wavelengths_expected, depths_expected1, no_line
|
|
91
124
|
|
|
92
125
|
def get_wave(data,header):
|
|
@@ -219,24 +252,34 @@ def blaze_correct(file_type, spec_type, order, file, directory, masking, run_nam
|
|
|
219
252
|
# wave=hdu[0].header['CRVAL1']+(hdu[0].header['CRPIX1']+np.arange(spec.shape[0]))*hdu[0].header['CDELT1']
|
|
220
253
|
|
|
221
254
|
wave=hdu[0].header['CRVAL1']+(np.arange(spec.shape[0]))*hdu[0].header['CDELT1']
|
|
255
|
+
|
|
256
|
+
where_are_zeros = (spec<=0)
|
|
257
|
+
spec[where_are_zeros] = 1000000000000
|
|
258
|
+
flux_error = np.sqrt(spec)
|
|
222
259
|
|
|
223
260
|
# print(wave)
|
|
224
261
|
|
|
225
262
|
if spec_type == 'order':
|
|
226
263
|
wavelengths=[]
|
|
227
264
|
fluxes=[]
|
|
265
|
+
errors = []
|
|
228
266
|
for value in range(0, len(wave)):
|
|
229
267
|
l_wave=wave[value]
|
|
230
268
|
l_flux=spec[value]
|
|
269
|
+
l_error=flux_error[value]
|
|
231
270
|
if l_wave>=wavelength_min and l_wave<=wavelength_max:
|
|
232
271
|
wavelengths.append(l_wave)
|
|
233
272
|
fluxes.append(l_flux)
|
|
273
|
+
errors.append(l_error)
|
|
234
274
|
wavelengths = np.array(wavelengths)
|
|
235
275
|
fluxes = np.array(fluxes)
|
|
276
|
+
errors = np.array(errors)
|
|
277
|
+
|
|
236
278
|
|
|
237
279
|
if len(wavelengths)>5144:
|
|
238
280
|
wavelengths = wavelengths[:5144]
|
|
239
281
|
fluxes = fluxes[:5144]
|
|
282
|
+
flux_error = errors[:5144]
|
|
240
283
|
# print(len(wavelengths))
|
|
241
284
|
# print(np.max(wavelengths), np.min(wavelengths))
|
|
242
285
|
# print(min_overlap)
|
|
@@ -258,12 +301,10 @@ def blaze_correct(file_type, spec_type, order, file, directory, masking, run_nam
|
|
|
258
301
|
# if len(spec_check)>0:
|
|
259
302
|
# print('WARNING NEGATIVE/ZERO FLUX - corrected')
|
|
260
303
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
flux_error
|
|
264
|
-
|
|
265
|
-
flux_error[where_are_zeros] = 1000000000000
|
|
266
|
-
|
|
304
|
+
# where_are_zeros = (spec<=0)
|
|
305
|
+
# spec[where_are_zeros] = 1000000000000
|
|
306
|
+
# flux_error = np.sqrt(spec)
|
|
307
|
+
|
|
267
308
|
flux_error_order = flux_error
|
|
268
309
|
masked_waves = []
|
|
269
310
|
masked_waves = np.array(masked_waves)
|
ACID_code/__init__.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.
|
|
1
|
+
__version__ = "0.1.0"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: ACID-code
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: Returns line profiles from input spectra by fitting the stellar continuum and performing LSD
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
Requires-Dist: numpy
|
|
@@ -9,4 +9,6 @@ Requires-Dist: matplotlib
|
|
|
9
9
|
Requires-Dist: scipy
|
|
10
10
|
Requires-Dist: astropy
|
|
11
11
|
Requires-Dist: statistics
|
|
12
|
+
Requires-Dist: sphinx-rtd-theme
|
|
13
|
+
Requires-Dist: tqdm
|
|
12
14
|
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
ACID_code/ACID.py,sha256=EAD-HaAhD4QTJpgLhFI6lIJLPCD8d6irpgwcKhlvZGk,35438
|
|
2
|
+
ACID_code/LSD_func_faster.py,sha256=N52i9bhhZTLb-yBL_Es9ADzgiy-adD2ZbkfTrN9noJA,44056
|
|
3
|
+
ACID_code/__init__.py,sha256=Pru0BlFBASFCFo7McHdohtKkUtgMPDwbGfyUZlE2_Vw,21
|
|
4
|
+
ACID_code-0.1.0.dist-info/LICENSE,sha256=L6dUgqjvHmRoobrBCPSHKC4UtRM5Ldp1DJBC4bnLk3w,1070
|
|
5
|
+
ACID_code-0.1.0.dist-info/METADATA,sha256=sx8ZAIwoH87--HJHbQ4cdNUXxbKV5t9vxl4SuofLL88,368
|
|
6
|
+
ACID_code-0.1.0.dist-info/WHEEL,sha256=2wepM1nk4DS4eFpYrW1TTqPcoGNfHhhO_i5m4cOimbo,92
|
|
7
|
+
ACID_code-0.1.0.dist-info/top_level.txt,sha256=O4OaSabv1ebFYQmHgftr1PGAv6BvC2l81Y3HjgNehQI,10
|
|
8
|
+
ACID_code-0.1.0.dist-info/RECORD,,
|