Skip to content

Commit a66d78f

Browse files
committed
update aspcap model
1 parent 38b0774 commit a66d78f

File tree

1 file changed

+33
-168
lines changed

1 file changed

+33
-168
lines changed

src/astra/models/aspcap.py

Lines changed: 33 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -22,34 +22,6 @@
2222

2323
APOGEE_FERRE_MASK = get_apogee_pixel_mask()
2424

25-
"""
26-
@cached_property
27-
def ferre_flux(self):
28-
return self._get_pixel_array("params/flux.input")
29-
30-
@cached_property
31-
def ferre_e_flux(self):
32-
return self._get_pixel_array("params/e_flux.input")
33-
34-
#@cached_property
35-
#def model_flux(self):
36-
# return self._get_pixel_array("params/model_flux.output")
37-
38-
@cached_property
39-
def rectified_model_flux(self):
40-
return self._get_pixel_array("params/rectified_model_flux.output")
41-
42-
@cached_property
43-
def rectified_flux(self):
44-
return self._get_pixel_array("params/rectified_flux.output")
45-
46-
@cached_property
47-
def e_rectified_flux(self):
48-
continuum = self.ferre_flux / self.rectified_flux
49-
return self.ferre_e_flux / continuum
50-
51-
"""
52-
5325
class ASPCAPPixelArrayAccessor(BasePixelArrayAccessor):
5426

5527
def __get__(self, instance, instance_type=None):
@@ -73,56 +45,22 @@ def __get__(self, instance, instance_type=None):
7345

7446
else:
7547
# Chemical abundance pixel array.
76-
x_h = self.name[len("model_flux_"):]
77-
#isntance._get_output_pixel_array("abundances", "")
78-
raise NotImplementedError
48+
label = self.name[len("model_flux_"):]
49+
species = label[:-2] if label.endswith("_h") else label
50+
try:
51+
masked_model_flux = instance._get_output_pixel_array(f"abundances", f"{species.title()}/rectified_model_flux.output")
52+
except FileNotFoundError:
53+
instance.__pixel_data__.setdefault(self.name, np.nan * np.ones(8575))
54+
else:
55+
instance.__pixel_data__.setdefault(self.name, instance._unmask_pixel_array(masked_model_flux))
7956

8057
return instance.__pixel_data__[self.name]
8158
return self.field
82-
83-
84-
85-
class ChemicalAbundancePixelAccessor(BasePixelArrayAccessor):
86-
87-
def __get__(self, instance, instance_type=None):
88-
if instance is not None:
89-
try:
90-
return instance.__pixel_data__[self.name]
91-
except (AttributeError, KeyError):
92-
instance.__pixel_data__ = {}
93-
94-
x_h = self.name[len("model_flux_"):]
95-
upstream = FerreChemicalAbundances.get(getattr(instance, f"{x_h}_task_pk"))
96-
97-
try:
98-
instance.__pixel_data__.setdefault(self.name, upstream.unmask(upstream.rectified_model_flux))
99-
except:
100-
instance.__pixel_data__[self.name] = np.nan * np.ones(8575)
101-
102-
finally:
103-
return instance.__pixel_data__[self.name]
104-
105-
return self.field
106-
107-
108-
class ChemicalAbundanceModelFluxArray(PixelArray):
10959

110-
def __init__(self, ext=None, column_name=None, transform=None, accessor_class=ChemicalAbundancePixelAccessor, help_text=None, **kwargs):
111-
super(ChemicalAbundanceModelFluxArray, self).__init__(
112-
ext=ext,
113-
column_name=column_name,
114-
transform=transform,
115-
accessor_class=accessor_class,
116-
help_text=help_text,
117-
**kwargs
118-
)
119-
120-
12160
class ASPCAP(PipelineOutputModel):
12261

12362
""" APOGEE Stellar Parameter and Chemical Abundances Pipeline (ASPCAP) """
12463

125-
12664
#> Spectral Data
12765
wavelength = PixelArray(
12866
accessor_class=LogLambdaArrayAccessor,
@@ -132,40 +70,32 @@ class ASPCAP(PipelineOutputModel):
13270
naxis=8575,
13371
),
13472
)
135-
model_flux = PixelArray(
136-
accessor_class=ASPCAPPixelArrayAccessor,
137-
help_text="Model flux at optimized stellar parameters"
138-
)
139-
continuum = PixelArray(
140-
accessor_class=ASPCAPPixelArrayAccessor,
141-
help_text="Continuum"
142-
)
73+
model_flux = PixelArray(help_text="Model flux at optimized stellar parameters", accessor_class=ASPCAPPixelArrayAccessor)
74+
continuum = PixelArray(help_text="Continuum", accessor_class=ASPCAPPixelArrayAccessor)
14375

14476
#> Model Fluxes from Chemical Abundance Fits
145-
model_flux_al_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Al/H]")
146-
model_flux_c_12_13 = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized C12/13")
147-
model_flux_ca_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Ca/H]")
148-
model_flux_ce_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Ce/H]")
149-
model_flux_c_1_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [C 1/H]")
150-
model_flux_c_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [C/H]")
151-
model_flux_co_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Co/H]")
152-
model_flux_cr_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Cr/H]")
153-
model_flux_cu_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Cu/H]")
154-
model_flux_fe_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Fe/H]")
155-
model_flux_k_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [K/H]")
156-
model_flux_mg_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Mg/H]")
157-
model_flux_mn_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Mn/H]")
158-
model_flux_na_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Na/H]")
159-
model_flux_nd_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Nd/H]")
160-
model_flux_ni_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Ni/H]")
161-
model_flux_n_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [N/H]")
162-
model_flux_o_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [O/H]")
163-
model_flux_p_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [P/H]")
164-
model_flux_si_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Si/H]")
165-
model_flux_s_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [S/H]")
166-
model_flux_ti_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Ti/H]")
167-
model_flux_ti_2_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [Ti 2/H]")
168-
model_flux_v_h = ChemicalAbundanceModelFluxArray(help_text="Model flux at optimized [V/H]")
77+
model_flux_al_h = PixelArray(help_text="Model flux at optimized [Al/H]", accessor_class=ASPCAPPixelArrayAccessor)
78+
model_flux_c_12_13 = PixelArray(help_text="Model flux at optimized C12/13", accessor_class=ASPCAPPixelArrayAccessor)
79+
model_flux_ca_h = PixelArray(help_text="Model flux at optimized [Ca/H]", accessor_class=ASPCAPPixelArrayAccessor)
80+
model_flux_ce_h = PixelArray(help_text="Model flux at optimized [Ce/H]", accessor_class=ASPCAPPixelArrayAccessor)
81+
model_flux_c_h = PixelArray(help_text="Model flux at optimized [C/H]", accessor_class=ASPCAPPixelArrayAccessor)
82+
model_flux_co_h = PixelArray(help_text="Model flux at optimized [Co/H]", accessor_class=ASPCAPPixelArrayAccessor)
83+
model_flux_cr_h = PixelArray(help_text="Model flux at optimized [Cr/H]", accessor_class=ASPCAPPixelArrayAccessor)
84+
model_flux_cu_h = PixelArray(help_text="Model flux at optimized [Cu/H]", accessor_class=ASPCAPPixelArrayAccessor)
85+
model_flux_fe_h = PixelArray(help_text="Model flux at optimized [Fe/H]", accessor_class=ASPCAPPixelArrayAccessor)
86+
model_flux_k_h = PixelArray(help_text="Model flux at optimized [K/H]", accessor_class=ASPCAPPixelArrayAccessor)
87+
model_flux_mg_h = PixelArray(help_text="Model flux at optimized [Mg/H]", accessor_class=ASPCAPPixelArrayAccessor)
88+
model_flux_mn_h = PixelArray(help_text="Model flux at optimized [Mn/H]", accessor_class=ASPCAPPixelArrayAccessor)
89+
model_flux_na_h = PixelArray(help_text="Model flux at optimized [Na/H]", accessor_class=ASPCAPPixelArrayAccessor)
90+
model_flux_nd_h = PixelArray(help_text="Model flux at optimized [Nd/H]", accessor_class=ASPCAPPixelArrayAccessor)
91+
model_flux_ni_h = PixelArray(help_text="Model flux at optimized [Ni/H]", accessor_class=ASPCAPPixelArrayAccessor)
92+
model_flux_n_h = PixelArray(help_text="Model flux at optimized [N/H]", accessor_class=ASPCAPPixelArrayAccessor)
93+
model_flux_o_h = PixelArray(help_text="Model flux at optimized [O/H]", accessor_class=ASPCAPPixelArrayAccessor)
94+
model_flux_p_h = PixelArray(help_text="Model flux at optimized [P/H]", accessor_class=ASPCAPPixelArrayAccessor)
95+
model_flux_si_h = PixelArray(help_text="Model flux at optimized [Si/H]", accessor_class=ASPCAPPixelArrayAccessor)
96+
model_flux_s_h = PixelArray(help_text="Model flux at optimized [S/H]", accessor_class=ASPCAPPixelArrayAccessor)
97+
model_flux_ti_h = PixelArray(help_text="Model flux at optimized [Ti/H]", accessor_class=ASPCAPPixelArrayAccessor)
98+
model_flux_v_h = PixelArray(help_text="Model flux at optimized [V/H]", accessor_class=ASPCAPPixelArrayAccessor)
16999

170100
#> IRFM Effective Temperatures from V-Ks (Gonzalez Hernandez and Bonifacio 2009)
171101
irfm_teff = FloatField(null=True, help_text=Glossary.teff)
@@ -221,7 +151,6 @@ class ASPCAP(PipelineOutputModel):
221151
flag_c_12_13_warn_teff = c_12_13_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
222152
flag_c_12_13_warn_m_h = c_12_13_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
223153

224-
225154
ca_h = FloatField(null=True, help_text=Glossary.ca_h)
226155
e_ca_h = FloatField(null=True, help_text=Glossary.e_ca_h)
227156
ca_h_flags = BitField(default=0, help_text=Glossary.ca_h_flags)
@@ -234,8 +163,6 @@ class ASPCAP(PipelineOutputModel):
234163
flag_ca_h_warn_teff = ca_h_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
235164
flag_ca_h_warn_m_h = ca_h_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
236165

237-
238-
239166
ce_h = FloatField(null=True, help_text=Glossary.ce_h)
240167
e_ce_h = FloatField(null=True, help_text=Glossary.e_ce_h)
241168
ce_h_flags = BitField(default=0, help_text=Glossary.ce_h_flags)
@@ -253,23 +180,6 @@ class ASPCAP(PipelineOutputModel):
253180
flag_ce_h_warn_teff = ce_h_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
254181
flag_ce_h_warn_m_h = ce_h_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
255182

256-
c_1_h = FloatField(null=True, help_text=Glossary.c_1_h)
257-
e_c_1_h = FloatField(null=True, help_text=Glossary.e_c_1_h)
258-
c_1_h_flags = BitField(default=0, help_text=Glossary.c_1_h_flags)
259-
c_1_h_rchi2 = FloatField(null=True, help_text=Glossary.c_1_h_rchi2)
260-
flag_c_1_h_upper_limit_t1 = c_1_h_flags.flag(2**0, "At least one line is an upper limit by the 1% threshold in Hayes et al. (2022, ApJ, 262, 34)")
261-
flag_c_1_h_upper_limit_t2 = c_1_h_flags.flag(2**1, "At least one line is an upper limit by the 2% threshold in Hayes et al. (2022, ApJ, 262, 34)")
262-
flag_c_1_h_upper_limit_t3 = c_1_h_flags.flag(2**2, "At least one line is an upper limit by the 3% threshold in Hayes et al. (2022, ApJ, 262, 34)")
263-
flag_c_1_h_upper_limit_t4 = c_1_h_flags.flag(2**3, "At least one line is an upper limit by the 4% threshold in Hayes et al. (2022, ApJ, 262, 34)")
264-
flag_c_1_h_upper_limit_t5 = c_1_h_flags.flag(2**4, "At least one line is an upper limit by the 5% threshold in Hayes et al. (2022, ApJ, 262, 34)")
265-
flag_c_1_h_censored_high_teff = c_1_h_flags.flag(2**5, "Censored value because abundances known to be wrong for this Teff")
266-
flag_c_1_h_censored_low_teff_vmicro = c_1_h_flags.flag(2**6, "Censored value because it has low Teff and v_micro")
267-
flag_c_1_h_censored_unphysical = c_1_h_flags.flag(2**7, "Censored value because FERRE returned unphysical value")
268-
flag_c_1_h_bad_grid_edge = c_1_h_flags.flag(2**8, "Grid edge bad")
269-
flag_c_1_h_warn_grid_edge = c_1_h_flags.flag(2**9, "Grid edge warning")
270-
flag_c_1_h_warn_teff = c_1_h_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
271-
flag_c_1_h_warn_m_h = c_1_h_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
272-
273183
c_h = FloatField(null=True, help_text=Glossary.c_h)
274184
e_c_h = FloatField(null=True, help_text=Glossary.e_c_h)
275185
c_h_flags = BitField(default=0, help_text=Glossary.c_h_flags)
@@ -514,18 +424,6 @@ class ASPCAP(PipelineOutputModel):
514424
flag_ti_h_warn_teff = ti_h_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
515425
flag_ti_h_warn_m_h = ti_h_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
516426

517-
ti_2_h = FloatField(null=True, help_text=Glossary.ti_2_h)
518-
e_ti_2_h = FloatField(null=True, help_text=Glossary.e_ti_2_h)
519-
ti_2_h_flags = BitField(default=0, help_text=Glossary.ti_2_h_flags)
520-
ti_2_h_rchi2 = FloatField(null=True, help_text=Glossary.ti_2_h_rchi2)
521-
flag_ti_2_h_censored_high_teff = ti_2_h_flags.flag(2**5, "Censored value because abundances known to be wrong for this Teff")
522-
flag_ti_2_h_censored_low_teff_vmicro = ti_2_h_flags.flag(2**6, "Censored value because it has low Teff and v_micro")
523-
flag_ti_2_h_censored_unphysical = ti_2_h_flags.flag(2**7, "Censored value because FERRE returned unphysical value")
524-
flag_ti_2_h_bad_grid_edge = ti_2_h_flags.flag(2**8, "Grid edge bad")
525-
flag_ti_2_h_warn_grid_edge = ti_2_h_flags.flag(2**9, "Grid edge warning")
526-
flag_ti_2_h_warn_teff = ti_2_h_flags.flag(2**10, "These abundances are known to be unreliable for this Teff")
527-
flag_ti_2_h_warn_m_h = ti_2_h_flags.flag(2**11, "These abundances are known to be unreliable for this [M/H]")
528-
529427
v_h = FloatField(null=True, help_text=Glossary.v_h)
530428
e_v_h = FloatField(null=True, help_text=Glossary.e_v_h)
531429
v_h_flags = BitField(default=0, help_text=Glossary.v_h_flags)
@@ -556,7 +454,6 @@ class ASPCAP(PipelineOutputModel):
556454
flag_initial_guess_from_user = initial_flags.flag(2**2, help_text="Initial guess specified by user")
557455

558456
#> Summary Statistics
559-
snr = FloatField(null=True, help_text=Glossary.snr)
560457
rchi2 = FloatField(null=True, help_text=Glossary.rchi2)
561458
ferre_log_snr_sq = FloatField(null=True, help_text="FERRE-reported log10(snr**2)")
562459
ferre_time_coarse = FloatField(null=True, help_text="Total core-second by FERRE for coarse stage [s]")
@@ -665,35 +562,6 @@ def flag_bad(self):
665562

666563
pwd = TextField(null=True, help_text="Working directory")
667564
ferre_index = IntegerField(null=True, help_text="Index of the FERRE run")
668-
669-
"""
670-
#> Task Primary Keys
671-
stellar_parameters_task_pk = ForeignKeyField(FerreStellarParameters, unique=True, null=True, lazy_load=False, help_text="Task primary key for stellar parameters")
672-
al_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Al/H]")
673-
c_12_13_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for C12/C13")
674-
ca_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Ca/H]")
675-
ce_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Ce/H]")
676-
c_1_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [C 1/H]")
677-
c_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [C/H]")
678-
co_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Co/H]")
679-
cr_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Cr/H]")
680-
cu_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Cu/H]")
681-
fe_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Fe/H]")
682-
k_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [K/H]")
683-
mg_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Mg/H]")
684-
mn_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Mn/H]")
685-
na_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Na/H]")
686-
nd_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Nd/H]")
687-
ni_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Ni/H]")
688-
n_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [N/H]")
689-
o_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [O/H]")
690-
p_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [P/H]")
691-
si_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Si/H]")
692-
s_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [S/H]")
693-
ti_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Ti/H]")
694-
ti_2_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [Ti 2/H]")
695-
v_h_task_pk = ForeignKeyField(FerreChemicalAbundances, unique=True, null=True, lazy_load=False, help_text="Task primary key for [V/H]")
696-
"""
697565

698566
#> Calibration flags
699567
calibrated_flags = BitField(null=True, help_text="Calibration flags")
@@ -730,8 +598,6 @@ def flag_bad(self):
730598
raw_e_ca_h = FloatField(null=True, help_text=Glossary.raw_e_ca_h)
731599
raw_ce_h = FloatField(null=True, help_text=Glossary.raw_ce_h)
732600
raw_e_ce_h = FloatField(null=True, help_text=Glossary.raw_e_ce_h)
733-
raw_c_1_h = FloatField(null=True, help_text=Glossary.raw_c_1_h)
734-
raw_e_c_1_h = FloatField(null=True, help_text=Glossary.raw_e_c_1_h)
735601
raw_c_h = FloatField(null=True, help_text=Glossary.raw_c_h)
736602
raw_e_c_h = FloatField(null=True, help_text=Glossary.raw_e_c_h)
737603
raw_co_h = FloatField(null=True, help_text=Glossary.raw_co_h)
@@ -766,8 +632,6 @@ def flag_bad(self):
766632
raw_e_s_h = FloatField(null=True, help_text=Glossary.raw_e_s_h)
767633
raw_ti_h = FloatField(null=True, help_text=Glossary.raw_ti_h)
768634
raw_e_ti_h = FloatField(null=True, help_text=Glossary.raw_e_ti_h)
769-
raw_ti_2_h = FloatField(null=True, help_text=Glossary.raw_ti_2_h)
770-
raw_e_ti_2_h = FloatField(null=True, help_text=Glossary.raw_e_ti_2_h)
771635
raw_v_h = FloatField(null=True, help_text=Glossary.raw_v_h)
772636
raw_e_v_h = FloatField(null=True, help_text=Glossary.raw_e_v_h)
773637

@@ -802,6 +666,7 @@ def _get_output_pixel_array(self, stage, name, P=7514):
802666

803667

804668

669+
805670
def apply_noise_model():
806671
import pickle
807672
from astra import __version__

0 commit comments

Comments
 (0)