Skip to content

Commit 7b076a9

Browse files
committed
Calc continuum using AFS
1 parent c477537 commit 7b076a9

File tree

4 files changed

+333
-0
lines changed

4 files changed

+333
-0
lines changed

Project.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,10 @@ version = "0.0.2"
55

66
[deps]
77
AstroLib = "c7932e45-9af1-51e7-9da9-f004cd3a462b"
8+
Atom = "c52e3926-4ff0-5f6e-af25-54175e0327b1"
89
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
910
ColorSchemes = "35d6a980-a343-548e-a6ea-1d62b119f2f4"
11+
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
1012
DataFrames = "a93c6f00-e57d-5684-b7b6-d8193f3e46c0"
1113
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
1214
EchelleCCFs = "5d9f57b1-d7b5-417c-8d79-eedbcaad0187"
@@ -15,15 +17,19 @@ FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
1517
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
1618
GPLinearODEMaker = "27ef9b34-1325-4cec-ba33-00f2f4637873"
1719
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
20+
Juno = "e5e0dc1b-0480-54bc-9374-aad01c23163d"
1821
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1922
LsqFit = "2fda8390-95c7-5789-9bda-21331edee243"
2023
Missings = "e1d29d7a-bbdc-5cf2-9ac0-f12de2c33e28"
2124
MultivariateStats = "6f286f6a-111f-5878-ab1e-185364afe411"
25+
NaNMath = "77ba4419-2d1f-58cd-9bb1-8ffee604a2e3"
2226
Optim = "429524aa-4258-5aef-a3af-852621145aeb"
2327
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
2428
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
2529
PyCall = "438e738f-606a-5dbb-bf0a-cddfbfd45ab0"
2630
Query = "1a8c2f83-1ff3-5112-b086-8aa67b057ba1"
31+
RCall = "6f49c342-dc21-5d91-9882-a32aef131414"
32+
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
2733
RvSpectML = "1f61ac2c-3a1c-440a-925a-2707197041c8"
2834
RvSpectMLBase = "c48404b2-35ea-40e7-ac7f-06a53de703d6"
2935
RvSpectMLPlots = "6ad363e8-653f-4efd-a04b-f033e69a984c"

analyze_daily_aves.jl

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
if occursin(r"RvSpectMLEcoSystem$", pwd()) cd("NeidSolarScripts") end
2+
using Pkg
3+
Pkg.activate(".")
4+
using HDF5, JLD2, FITSIO, FileIO, DataFrames, Query, RvSpectMLBase, Statistics, MultivariateStats, Plots
5+
6+
if occursin(r"NeidSolarScripts$", pwd()) cd("output56") end
7+
files = DataFrame(:filename=>readdir())
8+
jld_files = files |> @filter(contains(_.filename,"new.jld2")) |> DataFrame
9+
10+
plt = plot()
11+
for day in eachrow(jld_files)
12+
#f = h5open("solar_20210104_new.jld2")
13+
f = h5open(day.filename)
14+
ccfs = read(f,"ccfs_espresso")
15+
M = fit(PCA,ccfs[401:end-401,60:end-60],maxoutdim=10,pratio=1.0)
16+
plot!(plt,M.mean./maximum(M.mean), label="Mean")
17+
map(i->plot!(plt,sign(M.proj[200,i]).*M.proj[:,i]./maximum(abs.(extrema(M.proj[:,i]))), label=string(i)),1:4);
18+
break
19+
end
20+
display(plt)
21+
#savefig("ccf_pca_20120104.png")
22+
23+
v_grid =read(h5open(jld_files.filename[1]),"v_grid")
24+
v_grid = 100.0 * (-616:616)
25+
jld_files.mean_ccf = Vector{Vector{Float64}}(undef,size(jld_files,1))
26+
jld_files.smooth_ccf = Vector{Vector{Float64}}(undef,size(jld_files,1))
27+
jld_files.ccf_resid = Vector{Array{Float64,2}}(undef,size(jld_files,1))
28+
#plt = plot()
29+
for (i,day) in enumerate(eachrow(jld_files))
30+
#f = h5open("solar_20210104_new.jld2")
31+
f = h5open(day.filename)
32+
#jld_files.mean_ccf[i] = read(f,"mean_ccf")
33+
#jld_files.smooth_ccf[i] = read(f,"ccf_template_smooth")
34+
jld_files.ccf_resid[i] = read(f,"ccf_resid_minus_rv_proj")
35+
end
36+
#display(plt)
37+
#savefig("ccf_pca_20120104.png")
38+
mean_ccf_matrix = reduce(hcat,jld_files.mean_ccf)
39+
smooth_ccf_matrix = reduce(hcat,jld_files.smooth_ccf)
40+
41+
norm_mean = vec((mean(mean_ccf_matrix[1:300,:],dims=1).+mean(mean_ccf_matrix[end-300:end,:],dims=1))/2)
42+
norm_smooth = vec((mean(smooth_ccf_matrix[1:300,:],dims=1).+mean(smooth_ccf_matrix[end-300:end,:],dims=1))/2)
43+
norm_mean = vec((mean(mean_ccf_matrix[600:632,:],dims=1))/2)
44+
norm_smooth = vec((mean(smooth_ccf_matrix[600:632,:],dims=1))/2)
45+
46+
plot(v_grid,mean_ccf_matrix./norm_mean'.-smooth_ccf_matrix./norm_smooth')
47+
plot(v_grid,(mean_ccf_matrix.-smooth_ccf_matrix)./norm_smooth')
48+
xlims!(-12e3,12e3)
49+
50+
plot(v_grid,(mean_ccf_matrix-smooth_ccf_matrix)[:,1])
51+
52+
cols_use = 301:(size(mean_ccf_matrix,1)-301)
53+
M = fit(PCA,mean_ccf_matrix[cols_use,:],maxoutdim=10,pratio=1.0)
54+
principalvars(M)
55+
scatter(log10.(principalvars(M)./tprincipalvar(M)));
56+
xlabel!("Number of PCs");
57+
ylabel!("log frac variance remaining")
58+
59+
plot(v_grid[cols_use,:],mean(mean_ccf_matrix[cols_use,:],dims=2),label="Mean");
60+
plot!(v_grid[cols_use,:],M.proj[:,1].+0.5,label="1");
61+
plot!(v_grid[cols_use,:],M.proj[:,2].+0.4,label="2");
62+
plot!(v_grid[cols_use,:],M.proj[:,3].+0.25,label="3");
63+
plot!(v_grid[cols_use,:],M.proj[:,4].+0.15,label="4");
64+
plot!(v_grid[cols_use,:],M.proj[:,5].+0.,label="5");
65+
xlims!(-1e4,1e4)
66+
#savefig("daily_ccf_PCA.png")
67+
68+
f8 = h5open(jld_files.filename[8])
69+
ccfs =read(f8,"ccfs_espresso")
70+
71+
plot(v_grid,ccfs[:,100:120].-mean(ccfs[:,100:120],dims=2))
72+
73+
plot(v_grid,ccfs[:,100:120].-mean(ccfs[:,100:120],dims=2))
74+
xlims!(-1.2e3,1.2e3)

examples/calc_continuum.jl

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
if occursin(r"RvSpectMLEcoSystem$", pwd())
2+
cd("NeidSolarScripts")
3+
using Pkg
4+
Pkg.activate(".")
5+
end
6+
7+
verbose = true
8+
make_plots = true
9+
if verbose && !isdefined(Main,:RvSpectML) println("# Loading RvSpecML") end
10+
using RvSpectMLBase
11+
using EchelleInstruments, EchelleInstruments.NEID
12+
using EchelleCCFs
13+
#=
14+
using RvSpectML
15+
using NeidSolarScripts
16+
using NeidSolarScripts.SolarRotation
17+
if verbose println("# Loading other packages") end
18+
=#
19+
using CSV, DataFrames, Query, StatsBase, Statistics, Dates
20+
using JLD2, FileIO
21+
using NaNMath
22+
23+
target_subdir = "good_days/DRPv0.7" # USER: Replace with directory of your choice
24+
fits_target_str = "Sun"
25+
output_dir = "output/continuum"
26+
#outputs = Dict{String,Any}()
27+
paths_to_search_for_param = [pwd(),"examples",joinpath(pkgdir(RvSpectMLBase),"..","RvSpectML","examples"), "/gpfs/scratch/jpn23/"]
28+
# NOTE: make_manifest does not update its paths_to_search when default_paths_to_search is defined here, so if you change the line above, you must also include "paths_to_search=default_paths_to_search" in the make_manifest() function call below
29+
pipeline_plan = PipelinePlan()
30+
dont_make_plot!(pipeline_plan, :movie)
31+
32+
reset_all_needs!(pipeline_plan)
33+
#if need_to(pipeline_plan,:read_spectra)
34+
if verbose println("# Finding what data files are avaliable.") end
35+
if isfile("manifest.csv")
36+
df_files = CSV.read("manifest.csv", DataFrame)
37+
@assert size(df_files,1) >= 1
38+
@assert hasproperty(df_files,:Filename)
39+
@assert hasproperty(df_files,:target)
40+
@assert hasproperty(df_files,:bjd)
41+
@assert hasproperty(df_files,:ssbz)
42+
@assert hasproperty(df_files,:exptime)
43+
else
44+
eval(read_data_paths(paths_to_search=paths_to_search_for_param))
45+
@assert isdefined(Main,:neid_data_path)
46+
df_files = make_manifest(neid_data_path, target_subdir, NEID )
47+
CSV.write("manifest.csv", df_files)
48+
end
49+
50+
if verbose println("# Reading in customized parameters from param.jl.") end
51+
if !@isdefined(idx_day_to_use)
52+
idx_day_to_use = 1
53+
end
54+
eval(code_to_include_param_jl(paths_to_search=paths_to_search_for_param))
55+
if match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1] == match(r"neidL1_(\d+)[T_](\d+)\.fits$", last(df_files_use.Filename))[1]
56+
date_str = match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1]
57+
else
58+
date_str = string(match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1]) * "-" * string(match(r"neidL1_(\d+)[T_](\d+)\.fits$", last(df_files_use.Filename))[1])
59+
end
60+
#=
61+
outputs["df_files_use"] = df_files_use
62+
63+
outputs_filename = joinpath(output_dir,"solar_" * date_str * "_new.jld2")
64+
if isfile(outputs_filename) && false
65+
times_already_processed = load(outputs_filename, "times")
66+
files_in_day_to_process = size(df_files_solar_by_day.data[idx_day_to_use],1)
67+
if files_in_day_to_process == length(times_already_processed)
68+
println("# Already processed all ", length(times_already_processed), " files for ", date_str)
69+
exit()
70+
end
71+
end
72+
=#
73+
74+
using Distributed
75+
addprocs(4)
76+
77+
@everywhere using RCall
78+
@everywhere afs_src = joinpath(pwd(),"src","AFS.R")
79+
@everywhere R"source($afs_src)"
80+
@everywhere using Pkg
81+
@everywhere Pkg.activate(".")
82+
@everywhere using RvSpectMLBase
83+
@everywhere using EchelleInstruments
84+
85+
@everywhere function calc_continuum_model(spectrum::AbstractSpectra2D; order_idx::Integer )
86+
possible_pix = get_pixel_range(get_inst(spectrum),order_idx)
87+
bad_pix = bad_col_ranges(get_inst(spectrum),order_idx)
88+
pix_rng = EchelleInstruments.calc_complement_index_ranges(possible_pix,bad_pix)
89+
pix = mapreduce(p->collect(p),vcat,pix_rng)
90+
afs_inputs = zeros(Float64,length(pix),2)
91+
afs_inputs[:,1] .= spectrum.λ[pix,order_idx]
92+
afs_inputs[:,2] .= spectrum.flux[pix,order_idx]
93+
@assert !any(isnan.(afs_inputs))
94+
#=
95+
wv = mapreduce(p->spec.λ[p,order_idx],vcat,pix_rng)
96+
@assert !any(isnan.(wv))
97+
inten = mapreduce(p->convert(Vector{Float64},spec.flux[p,order_idx]),vcat,pix_rng)
98+
@assert !any(isnan.(inten))
99+
afs_inputs = hcat(wv,inten)
100+
=#
101+
#df = DataFrame("wv"=>wv,"intes"=>inten)
102+
afs_output_R = R"AFS($afs_inputs,0.95,0.25)"
103+
afs_output = rcopy(afs_output_R) 
104+
continuum = zeros(eltype(spectrum.flux),size(spectrum.flux[:,order_idx]))
105+
continuum = fill(NaN,size(spectrum.flux[:,order_idx]))
106+
continuum[pix] .= afs_output
107+
return continuum
108+
end
109+
110+
111+
112+
@everywhere using EchelleInstruments.NEID
113+
@everywhere function calc_continuum_model(spectrum::AbstractSpectra2D )
114+
vec_of_orders = pmap(ord->calc_continuum_model(spectrum,order_idx=ord), min_order(get_inst(spectrum)):max_order(get_inst(spectrum)) )
115+
output = fill(NaN, size(spectrum.flux))
116+
for (i,ord) in enumerate(min_order(get_inst(spectrum)):max_order(get_inst(spectrum)))
117+
output[:,ord] .= vec_of_orders[i]
118+
end
119+
return output
120+
end
121+
122+
num_days_to_process = size(df_files_solar_by_day,1)
123+
for idx_day_to_use in 1:num_days_to_process
124+
df_files_use = df_files_solar_by_day[idx_day_to_use,:data] |> @orderby(_.bjd) |> DataFrame
125+
126+
println("# *** Working on day ", idx_day_to_use, " with ", size(df_files_use,1), "files. ***" )
127+
for row in eachrow(df_files_use)
128+
spec = NEID.read_data(row)
129+
m = match(r"neidL1_(\d+)[T_](\d+)\.fits$",row.Filename)
130+
output_filename = "neidL1_" * m.captures[1] * "T" * m.captures[2] * ".jld2"
131+
output_filename = joinpath(output_dir,output_filename)
132+
println("# Working on ", output_filename)
133+
continuum = calc_continuum_model(spec)
134+
@save output_filename continuum
135+
end
136+
137+
end

examples/plot_continuum.jl

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
if occursin(r"RvSpectMLEcoSystem$", pwd())
2+
cd("NeidSolarScripts")
3+
using Pkg
4+
Pkg.activate(".")
5+
elseif occursin(r"NeidSolarScripts$", pwd())
6+
using Pkg
7+
Pkg.activate(".")
8+
elseif occursin(r"examples$", pwd())
9+
cd("..")
10+
using Pkg
11+
Pkg.activate(".")
12+
end
13+
14+
using JLD2, FileIO
15+
using CSV, DataFrames, Query
16+
#using StatsBase, Statistics
17+
using Dates, NaNMath
18+
using RvSpectMLBase
19+
using EchelleInstruments
20+
21+
using Plots
22+
23+
target_subdir = "good_days/DRPv0.7" # USER: Replace with directory of your choice
24+
fits_target_str = "Sun"
25+
output_dir = "output/continuum"
26+
#outputs = Dict{String,Any}()
27+
paths_to_search_for_param = [pwd(),"examples",joinpath(pkgdir(RvSpectMLBase),"..","RvSpectML","examples"), "/gpfs/scratch/jpn23/"]
28+
# NOTE: make_manifest does not update its paths_to_search when default_paths_to_search is defined here, so if you change the line above, you must also include "paths_to_search=default_paths_to_search" in the make_manifest() function call below
29+
pipeline_plan = PipelinePlan()
30+
dont_make_plot!(pipeline_plan, :movie)
31+
32+
verbose = false
33+
reset_all_needs!(pipeline_plan)
34+
#if need_to(pipeline_plan,:read_spectra)
35+
if verbose println("# Finding what data files are avaliable.") end
36+
if isfile("manifest.csv")
37+
df_files = CSV.read("manifest.csv", DataFrame)
38+
@assert size(df_files,1) >= 1
39+
@assert hasproperty(df_files,:Filename)
40+
@assert hasproperty(df_files,:target)
41+
@assert hasproperty(df_files,:bjd)
42+
@assert hasproperty(df_files,:ssbz)
43+
@assert hasproperty(df_files,:exptime)
44+
else
45+
eval(read_data_paths(paths_to_search=paths_to_search_for_param))
46+
@assert isdefined(Main,:neid_data_path)
47+
df_files = make_manifest(neid_data_path, target_subdir, NEID )
48+
CSV.write("manifest.csv", df_files)
49+
end
50+
51+
idx_day_to_use = 1
52+
if verbose println("# Reading in customized parameters from param.jl.") end
53+
if !@isdefined(idx_day_to_use)
54+
idx_day_to_use = 1
55+
end
56+
eval(code_to_include_param_jl(paths_to_search=paths_to_search_for_param))
57+
#=
58+
if match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1] == match(r"neidL1_(\d+)[T_](\d+)\.fits$", last(df_files_use.Filename))[1]
59+
match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1]date_str = match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1]
60+
else
61+
date_str = string(match(r"neidL1_(\d+)[T_](\d+)\.fits$", first(df_files_use.Filename))[1]) * "-" * string(match(r"neidL1_(\d+)[T_](\d+)\.fits$", last(df_files_use.Filename))[1])
62+
end
63+
outputs["df_files_use"] = df_files_use
64+
65+
outputs_filename = joinpath(output_dir,"solar_" * date_str * "_new.jld2")
66+
if isfile(outputs_filename) && false
67+
times_already_processed = load(outputs_filename, "times")
68+
files_in_day_to_process = size(df_files_solar_by_day.data[idx_day_to_use],1)
69+
if files_in_day_to_process == length(times_already_processed)
70+
println("# Already processed all ", length(times_already_processed), " files for ", date_str)
71+
exit()
72+
end
73+
end
74+
=#
75+
76+
continua = Vector{Array{Float32,2}}()
77+
for row in eachrow(df_files_use)
78+
m = match(r"(neidL1_\d+[T_]\d+)\.fits$", row.Filename)
79+
continuum_filename = joinpath(output_dir, m.captures[1] * ".jld2")
80+
jldopen(continuum_filename,"r") do file
81+
push!(continua,file["continuum"])
82+
end
83+
end
84+
85+
using Plots
86+
using StatsBase
87+
88+
ord = 90
89+
pix = get_pixel_range(NEID2D(),ord)
90+
plt = plot()
91+
for obs in vcat(100:105,150:155,200:205)
92+
plot!(continua[obs][pix,ord], label=string(obs) )
93+
end
94+
display(plt)
95+
96+
nobs = size(df_files_use,1)
97+
mean_continuum = mapreduce(obs->continua[obs][get_pixel_range(NEID2D(),ord),ord],.+,1:nobs) ./ nobs
98+
99+
plt = plot()#legend=:none)
100+
mean_mean_continuum = Float64[]
101+
for obs in 1:nobs
102+
#plot!(continua[obs][pix,ord]./mean_continuum, label=string(obs) )
103+
push!(mean_mean_continuum,NaNMath.mean((continua[obs][pix,ord]./mean_continuum)[1000:end-1000] ))
104+
end
105+
scatter!(plt, 1:nobs,mean_mean_continuum)
106+
#display(plt)
107+
108+
plt = plot(legend=:none)
109+
for obs in 1:nobs# vcat(100:105,150:155,200:205)
110+
pix = get_pixel_range(NEID2D(),ord)
111+
plot!(continua[obs][pix,ord]./(mean_continuum.*mean_mean_continuum[obs]), label=string(obs) )
112+
end
113+
display(plt)
114+
115+
ylims!(plt,0.99,1.01)
116+
ylims!(plt,0.9,1.1)

0 commit comments

Comments
 (0)