Commit b58e95699323617a2f84fdcc25c92eb0b727591c
1 parent
ab47fb7c
Exists in
master
First commit
Showing
4 changed files
with
817 additions
and
0 deletions
Show diff stats
@@ -0,0 +1,319 @@ | @@ -0,0 +1,319 @@ | ||
1 | +PRO dustem_fit_intensity_emiles_example,model=model $ | ||
2 | + ,sed_file=sed_file $ | ||
3 | + ,Nitermax=Nitermax $ | ||
4 | + ,postscript=postscript $ | ||
5 | + ,fits_save=fits_save $ | ||
6 | + ,help=help $ | ||
7 | + ,wait=wait $ | ||
8 | + ,noobj=noobj $ | ||
9 | + ,verbose=verbose | ||
10 | + | ||
11 | +;+ | ||
12 | +; NAME: | ||
13 | +; dustem_fit_intensity_emiles_example | ||
14 | +; | ||
15 | +; PURPOSE: | ||
16 | +; This routine is an example of how to fit an observational SED | ||
17 | +; (StokesI only) with DustEM and DustEMWrap, and using the EMiles Strellar template pluggin | ||
18 | +; | ||
19 | +; For this example, the code uses the SED in the file example_SED_1.xcat, | ||
20 | +; which is distributed in the Data/EXAMPLE_OBSDATA/ directory | ||
21 | +; | ||
22 | +; The example SED has Stokes I photometric data points from | ||
23 | +; IRAC, MIPS and IRAS. Examples illustrating running DustEMWrap to | ||
24 | +; fit spectral data, polarisation data and extinction data | ||
25 | +; are provided in other _example routines in the src/idl/ | ||
26 | +; directory. See the DustEMWrap User Guide for more information. | ||
27 | +; | ||
28 | +; CATEGORY: | ||
29 | +; DustEMWrap, Distributed, High-Level, User Example | ||
30 | +; | ||
31 | +; CALLING SEQUENCE: | ||
32 | +; dustem_fit_intensity_emiles_example[,model=][sed_file=][,postscript=][,Nitermax=][,fits_save=][,/help,/wait,/verbose] | ||
33 | +; | ||
34 | +; INPUTS: | ||
35 | +; None | ||
36 | +; | ||
37 | +; OPTIONAL INPUT PARAMETERS: | ||
38 | +; None | ||
39 | +; | ||
40 | +; OUTPUTS: | ||
41 | +; None | ||
42 | +; | ||
43 | +; OPTIONAL OUTPUT PARAMETERS: | ||
44 | +; Plots, results structure in binary FITS table format | ||
45 | +; | ||
46 | +; ACCEPTED KEY-WORDS: | ||
47 | +; model = specifies the interstellar dust mixture used by | ||
48 | +; DustEM. See userguide or dustem_test_model_exists.pro | ||
49 | +; for more details about available models in current release. | ||
50 | +; sed_file = string naming the path to text file in .xcat format that | ||
51 | +; describes the observational SED. If not set, the file | ||
52 | +; 'Data/EXAMPLE_OBSDATA/example_SED_1.xcat' is used. | ||
53 | +; postscript = if set, final plot is saved as postscript file | ||
54 | +; Nitermax = maximum number of fit iterations. Default is 5. | ||
55 | +; fits_save = if set, save the fit results in a binary | ||
56 | +; FITS file. | ||
57 | +; help = if set, print this help | ||
58 | +; wait = if set, wait this many seconds between each step of | ||
59 | +; the code (for illustration purposes) | ||
60 | +; verbose = if set, subroutines will run in verbose mode | ||
61 | +; noobj = if set, runs with no object graphics | ||
62 | +; | ||
63 | +; COMMON BLOCKS: | ||
64 | +; None | ||
65 | +; | ||
66 | +; SIDE EFFECTS: | ||
67 | +; None | ||
68 | +; | ||
69 | +; RESTRICTIONS: | ||
70 | +; The DustEM fortran code must be installed | ||
71 | +; The DustEMWrap IDL code must be installed | ||
72 | +; | ||
73 | +; PROCEDURES AND SUBROUTINES USED: | ||
74 | +; | ||
75 | +; EXAMPLES | ||
76 | +; dustem_fit_intensity_example | ||
77 | +; dustem_fit_intensity_example,Nitermax=1,fits_save='/tmp/mysavefile.fits' | ||
78 | +; dustem_fit_intensity_example,model='DBP90' | ||
79 | +; | ||
80 | +; MODIFICATION HISTORY: | ||
81 | +; Written by JPB Apr-2011 | ||
82 | +; Evolution details on the DustEMWrap gitlab. | ||
83 | +; See http://dustemwrap.irap.omp.eu/ for FAQ and help. | ||
84 | +;- | ||
85 | + | ||
86 | +IF keyword_set(help) THEN BEGIN | ||
87 | + doc_library,'dustem_fit_intensity_emiles_example' | ||
88 | + goto,the_end | ||
89 | +END | ||
90 | + | ||
91 | +IF keyword_set(model) THEN BEGIN | ||
92 | + use_model=strupcase(model) | ||
93 | +ENDIF ELSE BEGIN | ||
94 | + use_model='DBP90' ;Example with default keywords uses the DBP90 model | ||
95 | +ENDELSE | ||
96 | + | ||
97 | +exists=dustem_test_model_exists(use_model) | ||
98 | +if exists ne 1 then $ | ||
99 | + message,'Unknown dust model' | ||
100 | + | ||
101 | +use_polarization=0 ; initialize Dustemwrap in no polarization mode | ||
102 | +use_window=2 ; default graphics window number to use for plotting the results | ||
103 | +use_verbose=0 | ||
104 | +if keyword_set(verbose) then use_verbose=1 | ||
105 | +use_Nitermax=5 ; maximum number of iterations for the fit | ||
106 | +IF keyword_set(Nitermax) THEN use_Nitermax=Nitermax | ||
107 | + | ||
108 | +dustem_define_la_common | ||
109 | + | ||
110 | +;=== Set the (model-dependent) parameters that you want to fit (pd), | ||
111 | +;=== their initial values (iv) | ||
112 | +;=== and whether they are bounded (ulimed,llimed,llims,ulims). | ||
113 | +;=== Fixed parameters (fpd) and their values (fiv) are also set here. | ||
114 | +;=== Refer to the DustEM and DustEMWrap User guides for an explanation | ||
115 | +;=== of the physical meaning of dust model and plug-in parameters, and | ||
116 | +;=== how to specify them. | ||
117 | + | ||
118 | +;=== Examples are provided for some of the dust models. | ||
119 | +;=== To try them, uncomment the model that you want to try and re-run | ||
120 | + | ||
121 | +;=== AN EXAMPLE FOR DBP90 | ||
122 | +;=== Here we fit the dust abundances of the DBP90 model, the | ||
123 | +;=== intensity of the dust-heating radiation field, as well as a plug-in | ||
124 | +;=== for synchrotron emission | ||
125 | +;=== The free parameters are all lower-bounded at zero. | ||
126 | +;=== use_model='DBP90' ; you should specify this above! | ||
127 | + | ||
128 | +age_values=[0.03, 0.05, 0.08, 0.15, 0.25, 0.40, 0.60, 1.0, 1.75, 3.0, 5.0, 8.5, 13.5] | ||
129 | +metalicity_values=[-1.49, -0.96, -0.35, +0.06, +0.26, +0.4] | ||
130 | +Nage=n_elements(age_values) | ||
131 | +Nmetalicity=n_elements(metalicity_values) | ||
132 | +ia=where(age_values EQ 0.2500,counta) | ||
133 | +iz=where(metalicity_values EQ -0.35,countb) | ||
134 | +ij=lonarr(1,2) | ||
135 | +ij[0,0]=ia & ij[0,1]=iz | ||
136 | +ind1=ij2index(ij,[Nage,Nmetalicity])+1 | ||
137 | +ia=where(age_values EQ 0.05,counta) | ||
138 | +iz=where(metalicity_values EQ +0.06,countb) | ||
139 | +ij=lonarr(1,2) | ||
140 | +ij[0,0]=ia & ij[0,1]=iz | ||
141 | +ind2=ij2index(ij,[Nage,Nmetalicity])+1 | ||
142 | + | ||
143 | +; pd = [ $ | ||
144 | +; '(*!dustem_params).G0', $ ;G0 | ||
145 | +; '(*!dustem_params).grains(0).mdust_o_mh',$ ;PAH0 mass fraction | ||
146 | +; '(*!dustem_params).grains(1).mdust_o_mh',$ ;VSG mass fraction | ||
147 | +; '(*!dustem_params).grains(2).mdust_o_mh',$ ;BG mass fraction | ||
148 | +; 'dustem_plugin_emiles_stellar_continuum_'+strtrim(ind1[0]+1,2), $ ;Emiles coefficient for 0.25Gyr,Z/H=-0.35 | ||
149 | +; 'dustem_plugin_emiles_stellar_continuum_'+strtrim(ind2[0]+1,2)] ;Emiles coefficient for 0.05Gyr,Z/H=+0.06 | ||
150 | + | ||
151 | +; ; initial values vector for run without synchrotron plugin | ||
152 | +; iv = [1.6, 2.2e-4, 5.7e-4, 3.4e-3,100.,100.] | ||
153 | + | ||
154 | +pd = [ $ | ||
155 | + '(*!dustem_params).G0', $ ;G0 | ||
156 | + '(*!dustem_params).grains(0).mdust_o_mh',$ ;PAH0 mass fraction | ||
157 | + '(*!dustem_params).grains(1).mdust_o_mh',$ ;VSG mass fraction | ||
158 | + '(*!dustem_params).grains(2).mdust_o_mh',$ ;BG mass fraction | ||
159 | + 'dustem_plugin_emiles_stellar_continuum_1', $ ;tau factor to apply for reddening [-] | ||
160 | + 'dustem_plugin_emiles_stellar_continuum_'+strtrim(ind1[0]+1,2), $ ;Emiles coefficient for 0.25Gyr,Z/H=-0.35 | ||
161 | + 'dustem_plugin_emiles_stellar_continuum_'+strtrim(ind2[0]+1,2)] ;Emiles coefficient for 0.05Gyr,Z/H=+0.06 | ||
162 | + | ||
163 | +iv = [1.6, 2.2e-4, 5.7e-4, 3.4e-3,0.5,33.,31.] | ||
164 | +Npar=n_elements(pd) | ||
165 | +ulimed=replicate(0,Npar) | ||
166 | +llimed=replicate(1,Npar) | ||
167 | +llims=replicate(1.e-15,Npar) | ||
168 | +ulims=replicate(1.e-15,Npar) | ||
169 | +ulimed[4]=1. & ulims[4]=1. | ||
170 | +fpd=[] & fiv=[] | ||
171 | + | ||
172 | +; pd = [ $ | ||
173 | +; '(*!dustem_params).G0', $ ;G0 | ||
174 | +; '(*!dustem_params).grains(0).mdust_o_mh',$ ;PAH0 mass fraction | ||
175 | +; '(*!dustem_params).grains(1).mdust_o_mh',$ ;VSG mass fraction | ||
176 | +; '(*!dustem_params).grains(2).mdust_o_mh',$ ;BG mass fraction | ||
177 | +; 'dustem_plugin_phangs_stellar_continuum_1', $ ;tau factor to apply for reddening [-] | ||
178 | +; 'dustem_plugin_phangs_stellar_continuum_'+strtrim(ind1[0]+1,2), $ ;Emiles coefficient for 0.25Gyr,Z/H=-0.35 | ||
179 | +; 'dustem_plugin_phangs_stellar_continuum_'+strtrim(ind2[0]+1,2)] ;Emiles coefficient for 0.25Gyr,Z/H=-0.35 | ||
180 | +; ; | ||
181 | +; ; initial values vector for run without synchrotron plugin | ||
182 | +; iv = [1.6, 2.2e-4, 5.7e-4, 3.4e-3,0.1,100.,100.] | ||
183 | +; Npar=n_elements(pd) | ||
184 | +; ulimed=replicate(0,Npar) | ||
185 | +; llimed=replicate(1,Npar) | ||
186 | +; llims=replicate(1.e-15,Npar) | ||
187 | +; ulims=replicate(1.e-15,Npar) | ||
188 | +; fpd=[] & fiv=[] | ||
189 | + | ||
190 | + | ||
191 | +if keyword_set(wait) then begin | ||
192 | + message,'Finished setting dust model and plug-in parameters: '+use_model,/info | ||
193 | + wait,wait | ||
194 | +end | ||
195 | + | ||
196 | +;== INITIALISE DUSTEM | ||
197 | +dustem_init,model=use_model,polarization=use_polarization | ||
198 | +!dustem_nocatch=1 | ||
199 | +!dustem_verbose=use_verbose | ||
200 | +IF keyword_set(noobj) THEN !dustem_noobj=1 | ||
201 | +!EXCEPT=2 ; for debugging | ||
202 | + | ||
203 | +;=== READ EXAMPLE SED DATA | ||
204 | +dir=!dustem_wrap_soft_dir+'/Data/EXAMPLE_OBSDATA/' | ||
205 | +file=dir+'example_SED_5.xcat' | ||
206 | +IF keyword_set(sed_file) THEN file=sed_file | ||
207 | +sed=read_xcat(file,/silent) | ||
208 | + | ||
209 | +if keyword_set(wait) then begin | ||
210 | + message,'Finished reading SED data: '+file,/info | ||
211 | + wait,wait | ||
212 | +end | ||
213 | + | ||
214 | +;;=== ADJUST THE UNCERTAINTIES FROM WITHIN THE CODE (FOR ILLUSTRATION) | ||
215 | +ind=where(sed.sigmaII LT (0.2*sed.StokesI)^2,count) | ||
216 | +IF count NE 0 THEN sed[ind].sigmaII=(0.2*sed[ind].StokesI)^2 | ||
217 | + | ||
218 | +;== SET THE OBSERVATIONAL STRUCTURE | ||
219 | +;== sed is passed twice in the call -- the first occurrence is the SED that you | ||
220 | +;== wish to fit, the second occurrence is the SED that you wish to visualise. | ||
221 | +dustem_set_data,m_fit=sed,m_show=sed | ||
222 | + | ||
223 | +;== SET INITIAL VALUES AND LIMITS OF THE PARAMETERS THAT WILL BE | ||
224 | +;== ADJUSTED DURING THE FIT | ||
225 | +dustem_init_params,use_model,pd,iv,fpd=fpd,fiv=fiv,ulimed=ulimed,llimed=llimed,ulims=ulims,llims=llims | ||
226 | + | ||
227 | + | ||
228 | +if keyword_set(wait) then begin | ||
229 | + message,'Finished initializing DustEMWrap, including plugins and fixed parameters',/info | ||
230 | + wait,wait | ||
231 | +end | ||
232 | + | ||
233 | +;=== INFORMATION TO RUN THE FIT | ||
234 | +tol=1.e-16 ;fit tolerence | ||
235 | + | ||
236 | +;=== INFORMATION TO MAKE THE PLOT | ||
237 | +yr=[1.00e-4,1.00E2] ; y-axis limits | ||
238 | +xr=[1.00E-1,6.00e4] ; x-axis limits | ||
239 | +tit='FIT INTENSITY EXAMPLE' ; plot title | ||
240 | +ytit=textoidl('I_\nu (MJy/sr) for N_H=10^{20} H/cm^2') ; y-axis title | ||
241 | +xtit=textoidl('\lambda (\mum)') ; x-axis title | ||
242 | + | ||
243 | + | ||
244 | +;=== RUN THE FIT | ||
245 | +t1=systime(0,/sec) | ||
246 | +res=dustem_mpfit_data(tol=tol,Nitermax=use_Nitermax,gtol=gtol $ | ||
247 | + ,/xlog,/ylog,xr=xr,yr=yr,xtit=xtit,ytit=ytit,title=tit $ | ||
248 | + ,legend_xpos=legend_xpos,legend_ypos=legend_ypos $ | ||
249 | + ,errors=errors,chi2=chi2,rchi2=rchi2,show_plot=show_plot) | ||
250 | +t2=systime(0,/sec) | ||
251 | + | ||
252 | +if keyword_set(wait) then begin | ||
253 | + message,'Finished running DustEMWrap, using Niters: '+strtrim(string(use_Nitermax),2),/info | ||
254 | + message,'Time taken [sec]: '+sigfig(t2-t1,2,/sci),/info | ||
255 | + wait,wait | ||
256 | +end | ||
257 | + | ||
258 | +;=== MAKE THE FINAL PLOT | ||
259 | +IF keyword_set(postscript) THEN BEGIN | ||
260 | +; dir_ps='./' | ||
261 | + mydevice=!d.name | ||
262 | + set_plot,'PS' | ||
263 | +; ps_file=dir_ps+postscript | ||
264 | + ps_file=postscript | ||
265 | + device,filename=ps_file,/color | ||
266 | +ENDIF | ||
267 | + | ||
268 | +;stop | ||
269 | + | ||
270 | +IF !dustem_noobj THEN BEGIN | ||
271 | + dustemwrap_plot_noobj,*(*!dustem_fit).CURRENT_PARAM_VALUES,st=dummy,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (Final fit)' | ||
272 | + ENDIF ELSE BEGIN | ||
273 | + dustemwrap_plot,*(*!dustem_fit).CURRENT_PARAM_VALUES,st=dummy,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (Final fit)' | ||
274 | +ENDELSE | ||
275 | + | ||
276 | +IF keyword_set(postscript) THEN BEGIN | ||
277 | + device,/close | ||
278 | + set_plot,mydevice | ||
279 | + message,'Wrote '+ps_file,/info | ||
280 | +ENDIF | ||
281 | + | ||
282 | +if keyword_set(wait) then begin | ||
283 | + message,'Made the plot of the final results',/info | ||
284 | + wait,wait | ||
285 | +end | ||
286 | + | ||
287 | +IF keyword_set(fits_save) THEN BEGIN | ||
288 | + message,'Writing out results structure: '+fits_save,/info | ||
289 | + dustem_write_fits_table,filename=fits_save,help=help | ||
290 | +;=== At this point, you could erase all dustem system variables, or exit idl... all the | ||
291 | +;=== information needed to recover the results and remake the plots has been saved in the FITS table | ||
292 | + | ||
293 | +;=== Moved the following to dustem_fits_io_example | ||
294 | + ;; dustem_read_fits_table,filename=fits_save,dustem_st=dustem_spectra_st | ||
295 | + ;; ;stop | ||
296 | + ;; ;!dustem_show=ptr_new(*!dustem_data) ;test | ||
297 | + ;; !dustem_noobj=1 | ||
298 | + ;; ;==== plot result taken from the saved fits table | ||
299 | + ;; res=*(*!dustem_fit).CURRENT_PARAM_VALUES | ||
300 | + ;; IF !dustem_noobj THEN BEGIN | ||
301 | + ;; ;dustemwrap_plot_noobj,res,st=dustem_spectra_st,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (From Saved FITS file)' | ||
302 | + ;; dustemwrap_plot_noobj,res,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (From Saved FITS file)' | ||
303 | + ;; ENDIF ELSE BEGIN | ||
304 | + ;; ;dustemwrap_plot,res,st=dustem_spectra_st,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (From Saved FITS file)' | ||
305 | + ;; dustemwrap_plot,res,xr=xr,/xstyle,yr=yr,/ysty,/ylog,/xlog,title=tit+' (From Saved FITS file)' | ||
306 | + ;; ENDELSE | ||
307 | + ;; ;stop | ||
308 | + | ||
309 | + IF keyword_set(wait) THEN BEGIN | ||
310 | + message,'Saved the results as FITS in the file: '+fits_save,/info | ||
311 | + wait,wait | ||
312 | + ENDIF | ||
313 | +ENDIF | ||
314 | + | ||
315 | + | ||
316 | +the_end: | ||
317 | +message,'Finished dustem_fit_intensity_example',/info | ||
318 | + | ||
319 | +END |
@@ -0,0 +1,177 @@ | @@ -0,0 +1,177 @@ | ||
1 | +FUNCTION dustem_plugin_emiles_stellar_continuum,key=key $ | ||
2 | + ,val=val $ | ||
3 | + ,scope=scope $ | ||
4 | + ,paramtag=paramtag $ | ||
5 | + ,paramdefault=paramdefault $ | ||
6 | + ,help=help | ||
7 | + | ||
8 | +;+ | ||
9 | +; NAME: | ||
10 | +; dustem_plugin_emiles_stellar_continuum | ||
11 | +; PURPOSE: | ||
12 | +; DustEMWrap plugin to add EMILES stellar template emission to Dustemwrap SEDs | ||
13 | +; CATEGORY: | ||
14 | +; DustEM, Distributed, Mid-Level, Plugin | ||
15 | +; CALLING SEQUENCE: | ||
16 | +; stellar_brightness=dustem_plugin_emiles_stellar_continuum([,key=][,val=][,scope=][,paramtag=][paramdefault=][,/help]) | ||
17 | +; INPUTS: | ||
18 | +; None | ||
19 | +; OPTIONAL INPUT PARAMETERS: | ||
20 | +; key = input parameter number | ||
21 | +; First parameter: factor to apply to tau for redenning (1 means value derived from emission SED) | ||
22 | +; Following 13*6 parameters are weights by which to multiply the MILES templates [Msun/pc^2] | ||
23 | +; val = corresponding input parameter value | ||
24 | +; OUTPUTS: | ||
25 | +; stellar_brightness = stellar spectrum spectrum resampled on dustem wavelengths [MJy/sr] | ||
26 | +; OPTIONAL OUTPUT PARAMETERS: | ||
27 | +; scope = scope of the plugin | ||
28 | +; paramdefault = default values of parameters | ||
29 | +; paramtag = plugin parameter names as strings | ||
30 | +; ACCEPTED KEY-WORDS: | ||
31 | +; help = if set, print this help | ||
32 | +; COMMON BLOCKS: | ||
33 | +; None | ||
34 | +; SIDE EFFECTS: | ||
35 | +; None | ||
36 | +; RESTRICTIONS: | ||
37 | +; The DustEMWrap IDL code must be installed | ||
38 | +; PROCEDURE: | ||
39 | +; This is a DustEMWrap plugin | ||
40 | +; EXAMPLES | ||
41 | +; dustem_init | ||
42 | +; vec=dustem_plugin_emiles_stellar_continuum(scope=scope) | ||
43 | +; MODIFICATION HISTORY: | ||
44 | +; Written by JPB June 2023 | ||
45 | +; Evolution details on the DustEMWrap gitlab. | ||
46 | +; See http://dustemwrap.irap.omp.eu/ for FAQ and help. | ||
47 | +;- | ||
48 | + | ||
49 | +IF keyword_set(help) THEN BEGIN | ||
50 | + doc_library,'dustem_plugin_emiles_stellar_continuum' | ||
51 | + output=0. | ||
52 | + goto,the_end | ||
53 | +ENDIF | ||
54 | + | ||
55 | +;stop | ||
56 | + | ||
57 | +;default values of input parameters | ||
58 | +scope='ADD_SED' | ||
59 | + | ||
60 | +age_values=[0.03, 0.05, 0.08, 0.15, 0.25, 0.40, 0.60, 1.0, 1.75, 3.0, 5.0, 8.5, 13.5] | ||
61 | +metalicity_values=[-1.48630, -0.961400, -0.351200, +0.0600000, +0.255900, +0.397100] | ||
62 | + | ||
63 | +;read template info | ||
64 | +info_st=dustem_read_emiles_stellar_templates(age_values,metalicity_values,/info_only) | ||
65 | +age_values_emiles=info_st.age | ||
66 | +order=sort(age_values_emiles) | ||
67 | +age_values_emiles=age_values_emiles[order] | ||
68 | +un=uniq(age_values_emiles) | ||
69 | +age_values_emiles=age_values_emiles[un] | ||
70 | +met_values_emiles=info_st.z | ||
71 | +order=sort(met_values_emiles) | ||
72 | +met_values_emiles=met_values_emiles[order] | ||
73 | +un=uniq(met_values_emiles) | ||
74 | +met_values_emiles=met_values_emiles[un] | ||
75 | + | ||
76 | +Nage=n_elements(age_values) | ||
77 | +Nmetalicity=n_elements(metalicity_values) | ||
78 | +Nparam=Nage*Nmetalicity+1 ;+1 is for opacity | ||
79 | +paramtag=strarr(Nparam) | ||
80 | +paramdefault=dblarr(Nparam) | ||
81 | +paramdefault[*]=0.D0 | ||
82 | +i=0L | ||
83 | +paramtag[0]='tau_f' | ||
84 | +ii=1L | ||
85 | +FOR i=1L,Nparam-1 DO BEGIN | ||
86 | + ij=index2ij([i-1],[Nage,Nmetalicity]) | ||
87 | + paramtag[ii]='Age'+strtrim(ij[0,0],2)+'Met'+strtrim(ij[0,1],2) | ||
88 | + ii=ii+1 | ||
89 | +ENDFOR | ||
90 | +paramvalues=paramdefault | ||
91 | +IF keyword_set(key) THEN BEGIN | ||
92 | + ind=where(key EQ 1,count) | ||
93 | + IF count NE 0 THEN paramvalues[0]=val[ind[0]] | ||
94 | + FOR i=1L,Nparam-1 DO BEGIN | ||
95 | + ind=where(key EQ i+1,count) | ||
96 | + IF count NE 0 THEN paramvalues[i]=val[ind[0]] | ||
97 | + ENDFOR | ||
98 | +ENDIF | ||
99 | + | ||
100 | +;==== initialize templates if not present | ||
101 | +defsysv,'!dustem_plugin_emiles_stellar_continuum',exist=exist | ||
102 | +IF exist EQ 0 THEN BEGIN | ||
103 | + st={ssps:ptr_new(),wavs:ptr_new(),Mstars:ptr_new()} | ||
104 | + defsysv,'!dustem_plugin_emiles_stellar_continuum',st | ||
105 | +ENDIF | ||
106 | +IF not ptr_valid(!dustem_plugin_emiles_stellar_continuum.ssps) THEN BEGIN | ||
107 | + message,'Initializing SSP templates',/continue | ||
108 | + template_flux=dustem_read_emiles_stellar_templates(age_values,metalicity_values,template_wav=template_wav,Mstars=Mstars) | ||
109 | + !dustem_plugin_emiles_stellar_continuum.ssps=ptr_new(template_flux) | ||
110 | + !dustem_plugin_emiles_stellar_continuum.wavs=ptr_new(template_wav) | ||
111 | + !dustem_plugin_emiles_stellar_continuum.mstars=ptr_new(Mstars) | ||
112 | +ENDIF | ||
113 | + | ||
114 | + | ||
115 | +lambir=dustem_get_wavelengths() | ||
116 | +Nwavs=n_elements(lambir) | ||
117 | +output=fltarr(Nwavs,3) | ||
118 | +wavs=*!dustem_plugin_emiles_stellar_continuum.wavs | ||
119 | +Mstars=*!dustem_plugin_emiles_stellar_continuum.mstars | ||
120 | +;==== sum up the stellar spectrum | ||
121 | +;stop | ||
122 | +FOR i=1L,Nparam-1 DO BEGIN | ||
123 | + ;IF paramvalues[i] NE 0. AND ptr_valid((*!phangs_ssps)[i-1]) THEN BEGIN | ||
124 | + IF paramvalues[i] NE 0. THEN BEGIN | ||
125 | + ;stop | ||
126 | + ;only interpolate within the template wavelengths | ||
127 | + ;ind=where(lambir LE max(*!phangs_wavs) AND lambir GE min(*!phangs_wavs),count) | ||
128 | + ind=where(lambir LE max(wavs) AND lambir GE min(wavs),count) | ||
129 | + ;Mstar=(*!phangs_Mstars)[i] | ||
130 | + Mstar=Mstars[i-1] | ||
131 | + IF count NE 0 THEN BEGIN | ||
132 | + ;output[ind,0]=output[ind,0]+paramvalues[i]*interpol(*(*!phangs_ssps)[i-1],*!phangs_wavs,lambir[ind]) | ||
133 | + ;spectrum=*(*!phangs_ssps)[i-1] | ||
134 | + ;ssp=*(*!phangs_ssps)[i-1] | ||
135 | + ssp=*(*!dustem_plugin_emiles_stellar_continuum.ssps)[i-1] | ||
136 | + ;stop | ||
137 | + output[ind,0]=output[ind,0]+paramvalues[i]*Mstar*interpol(ssp,wavs,lambir[ind]) | ||
138 | + ENDIF | ||
139 | + ENDIF | ||
140 | +ENDFOR | ||
141 | +;==== Caution: at this point, output is in Lsun/pc^2/Angstroem | ||
142 | +;Caution: I am not sure about the nomalisation of the extinction curve that is in | ||
143 | +IF ptr_valid(!dustem_current) THEN BEGIN | ||
144 | + ;stop | ||
145 | + tau_fact=paramvalues[0] | ||
146 | + extinction_curve=((*!dustem_current).ext).ext_tot*(*!dustem_HCD)/1.0e21 ;This is tau | ||
147 | + ;*(*!dustem_HCD)/1.0e21 | ||
148 | + ;wav_ref=551.e-9*1.e6 ;visible 551 nm in microns | ||
149 | + ;tau_ref=interpol(extinction_curve,lambir,wav_ref) | ||
150 | + ;normalize extinction curve by given tau fact | ||
151 | + extinction_curve=extinction_curve*tau_fact | ||
152 | + ;stop | ||
153 | + output[*,0]=output[*,0]*exp(-1.*extinction_curve) | ||
154 | +ENDIF | ||
155 | + | ||
156 | +;no polarization for now | ||
157 | +output[*,1]=0. | ||
158 | +output[*,2]=0. | ||
159 | + | ||
160 | +;at that stage, output is F_lambda in Lsun/A/pc^2 | ||
161 | +;goint to MJy/sr (1e-20 W/m2/sr/hz) | ||
162 | +pc=3.085677581e16 ;m | ||
163 | +;kpc=3.085677581e19 ;m | ||
164 | +Lsun=3.828e26 ;Watts | ||
165 | +c=3.e5*1e3 ;m/s | ||
166 | +;Fact=Lsun ;Watts/A | ||
167 | +;fact=fact*c ;Watts/hz | ||
168 | +;fact=fact/4./!pi ;Watts/Hz/sr | ||
169 | +;fact=fact/pc^2 ;Watts/m2/Hz/sr | ||
170 | + | ||
171 | +fact=Lsun/pc*c/4./!pi/pc | ||
172 | +output=output*fact | ||
173 | + | ||
174 | +the_end: | ||
175 | +RETURN,output | ||
176 | + | ||
177 | +END |
@@ -0,0 +1,165 @@ | @@ -0,0 +1,165 @@ | ||
1 | +FUNCTION dustem_plugin_phangs_stellar_continuum,key=key $ | ||
2 | + ,val=val $ | ||
3 | + ,scope=scope $ | ||
4 | + ,paramtag=paramtag $ | ||
5 | + ,paramdefault=paramdefault $ | ||
6 | + ,help=help | ||
7 | + | ||
8 | +;+ | ||
9 | +; NAME: | ||
10 | +; dustem_plugin_phangs_stellar_continuum | ||
11 | +; PURPOSE: | ||
12 | +; DustEMWrap plugin to add EMILES stellar template emission to Dustemwrap SEDs | ||
13 | +; CATEGORY: | ||
14 | +; DustEM, Distributed, Mid-Level, Plugin | ||
15 | +; CALLING SEQUENCE: | ||
16 | +; stellar_brightness=dustem_plugin_phangs_stellar_continuum([,key=][,val=][,scope=][,paramtag=][paramdefault=][,/help]) | ||
17 | +; INPUTS: | ||
18 | +; None | ||
19 | +; OPTIONAL INPUT PARAMETERS: | ||
20 | +; key = input parameter number | ||
21 | +; First parameter: E(B-V) for extinction applied to the template, as used in Phangs | ||
22 | +; Following 13*6 parameters are weights by which to multiply the MILES templates [Msun/pc^2] | ||
23 | +; val = corresponding input parameter value | ||
24 | +; OUTPUTS: | ||
25 | +; stellar_brightness = stellar spectrum spectrum resampled on dustem wavelengths [MJy/sr] | ||
26 | +; OPTIONAL OUTPUT PARAMETERS: | ||
27 | +; scope = scope of the plugin | ||
28 | +; paramdefault = default values of parameters | ||
29 | +; paramtag = plugin parameter names as strings | ||
30 | +; ACCEPTED KEY-WORDS: | ||
31 | +; help = if set, print this help | ||
32 | +; COMMON BLOCKS: | ||
33 | +; None | ||
34 | +; SIDE EFFECTS: | ||
35 | +; None | ||
36 | +; RESTRICTIONS: | ||
37 | +; The DustEMWrap IDL code must be installed | ||
38 | +; PROCEDURE: | ||
39 | +; This is a DustEMWrap plugin for phangs | ||
40 | +; It differs from dustem_plugin_emiles_stellar_continuum.pro only by the way the extinction is applied to the output spectrum | ||
41 | +; EXAMPLES | ||
42 | +; dustem_init | ||
43 | +; vec=dustem_plugin_phangs_stellar_continuum(scope=scope) | ||
44 | +; MODIFICATION HISTORY: | ||
45 | +; Written by JPB June 2023 | ||
46 | +; Evolution details on the DustEMWrap gitlab. | ||
47 | +; See http://dustemwrap.irap.omp.eu/ for FAQ and help. | ||
48 | +;- | ||
49 | + | ||
50 | +IF keyword_set(help) THEN BEGIN | ||
51 | + doc_library,'dustem_plugin_phangs_stellar_continuum' | ||
52 | + output=0. | ||
53 | + goto,the_end | ||
54 | +ENDIF | ||
55 | + | ||
56 | +;stop | ||
57 | + | ||
58 | +;default values of input parameters | ||
59 | +scope='ADD_SED' | ||
60 | + | ||
61 | +age_values=[0.03, 0.05, 0.08, 0.15, 0.25, 0.40, 0.60, 1.0, 1.75, 3.0, 5.0, 8.5, 13.5] | ||
62 | +metalicity_values=[-1.48630, -0.961400, -0.351200, +0.0600000, +0.255900, +0.397100] | ||
63 | + | ||
64 | +;read template info | ||
65 | +info_st=dustem_read_emiles_stellar_templates(age_values,metalicity_values,/info_only) | ||
66 | +age_values_emiles=info_st.age | ||
67 | +order=sort(age_values_emiles) | ||
68 | +age_values_emiles=age_values_emiles[order] | ||
69 | +un=uniq(age_values_emiles) | ||
70 | +age_values_emiles=age_values_emiles[un] | ||
71 | +met_values_emiles=info_st.z | ||
72 | +order=sort(met_values_emiles) | ||
73 | +met_values_emiles=met_values_emiles[order] | ||
74 | +un=uniq(met_values_emiles) | ||
75 | +met_values_emiles=met_values_emiles[un] | ||
76 | + | ||
77 | +Nage=n_elements(age_values) | ||
78 | +Nmetalicity=n_elements(metalicity_values) | ||
79 | +Nparam=Nage*Nmetalicity+1 ;+1 is for opacity | ||
80 | +paramtag=strarr(Nparam) | ||
81 | +paramdefault=dblarr(Nparam) | ||
82 | +paramdefault[*]=0.D0 | ||
83 | +i=0L | ||
84 | +paramtag[0]='E(B-V)' | ||
85 | +ii=1L | ||
86 | +FOR i=1L,Nparam-1 DO BEGIN | ||
87 | + ij=index2ij([i-1],[Nage,Nmetalicity]) | ||
88 | + paramtag[ii]='Age'+strtrim(ij[0,0],2)+'Met'+strtrim(ij[0,1],2) | ||
89 | + ii=ii+1 | ||
90 | +ENDFOR | ||
91 | +paramvalues=paramdefault | ||
92 | +IF keyword_set(key) THEN BEGIN | ||
93 | + ind=where(key EQ 1,count) | ||
94 | + IF count NE 0 THEN paramvalues[0]=val[ind[0]] | ||
95 | + FOR i=1L,Nparam-1 DO BEGIN | ||
96 | + ind=where(key EQ i+1,count) | ||
97 | + IF count NE 0 THEN paramvalues[i]=val[ind[0]] | ||
98 | + ENDFOR | ||
99 | +ENDIF | ||
100 | + | ||
101 | +;==== initialize templates if not present | ||
102 | +defsysv,'!dustem_plugin_phangs_stellar_continuum',exist=exist | ||
103 | +IF exist EQ 0 THEN BEGIN | ||
104 | + st={ssps:ptr_new(),wavs:ptr_new(),Mstars:ptr_new()} | ||
105 | + defsysv,'!dustem_plugin_phangs_stellar_continuum',st | ||
106 | +ENDIF | ||
107 | +IF not ptr_valid(!dustem_plugin_phangs_stellar_continuum.ssps) THEN BEGIN | ||
108 | + message,'Initializing SSP templates',/continue | ||
109 | + template_flux=dustem_read_emiles_stellar_templates(age_values,metalicity_values,template_wav=template_wav,Mstars=Mstars) | ||
110 | + !dustem_plugin_phangs_stellar_continuum.ssps=ptr_new(template_flux) | ||
111 | + !dustem_plugin_phangs_stellar_continuum.wavs=ptr_new(template_wav) | ||
112 | + !dustem_plugin_phangs_stellar_continuum.mstars=ptr_new(Mstars) | ||
113 | +ENDIF | ||
114 | + | ||
115 | +;stop | ||
116 | + | ||
117 | +lambir=dustem_get_wavelengths() | ||
118 | +Nwavs=n_elements(lambir) | ||
119 | +output=fltarr(Nwavs,3) | ||
120 | +wavs=*!dustem_plugin_phangs_stellar_continuum.wavs | ||
121 | +Mstars=*!dustem_plugin_phangs_stellar_continuum.mstars | ||
122 | +;==== sum up the stellar spectrum | ||
123 | +;stop | ||
124 | +FOR i=1L,Nparam-1 DO BEGIN | ||
125 | + IF paramvalues[i] NE 0. THEN BEGIN | ||
126 | + ;stop | ||
127 | + ;only interpolate within the template wavelengths | ||
128 | + ind=where(lambir LE max(wavs) AND lambir GE min(wavs),count) | ||
129 | + Mstar=Mstars[i-1] | ||
130 | + IF count NE 0 THEN BEGIN | ||
131 | + ssp=*(*!dustem_plugin_phangs_stellar_continuum.ssps)[i-1] | ||
132 | + output[ind,0]=output[ind,0]+paramvalues[i]*Mstar*interpol(ssp,wavs,lambir[ind]) | ||
133 | + ENDIF | ||
134 | + ENDIF | ||
135 | +ENDFOR | ||
136 | +;==== Caution: at this point, output is unredenned Flambda in Lsun/pc^2/Angstroem | ||
137 | + | ||
138 | +;==== reden spectrum using Calzetti's extinction law (which is what Phangs does) | ||
139 | +flux=output[*,0] | ||
140 | +;factor -1 is to reden, instead of unreden. factor 1e4 is to go from microns to Angstroem | ||
141 | +calz_unred, lambir*1.e4, flux, -1.*paramvalues[0], flux_red, R_V = R_V | ||
142 | +output[*,0]=flux_red | ||
143 | + | ||
144 | +;no polarization for now | ||
145 | +output[*,1]=0. | ||
146 | +output[*,2]=0. | ||
147 | + | ||
148 | +;at that stage, output is F_lambda in Lsun/A/pc^2 | ||
149 | +;goint to MJy/sr (1e-20 W/m2/sr/hz) | ||
150 | +pc=3.085677581e16 ;m | ||
151 | +;kpc=3.085677581e19 ;m | ||
152 | +Lsun=3.828e26 ;Watts | ||
153 | +c=3.e5*1e3 ;m/s | ||
154 | +;Fact=Lsun ;Watts/A | ||
155 | +;fact=fact*c ;Watts/hz | ||
156 | +;fact=fact/4./!pi ;Watts/Hz/sr | ||
157 | +;fact=fact/pc^2 ;Watts/m2/Hz/sr | ||
158 | + | ||
159 | +fact=Lsun/pc*c/4./!pi/pc | ||
160 | +output=output*fact | ||
161 | + | ||
162 | +the_end: | ||
163 | +RETURN,output | ||
164 | + | ||
165 | +END |
@@ -0,0 +1,156 @@ | @@ -0,0 +1,156 @@ | ||
1 | +FUNCTION dustem_read_emiles_stellar_templates,age_values, $ | ||
2 | + metalicity_values, $ | ||
3 | + template_wav=template_wav, $ | ||
4 | + Mstars=Mstars, $ | ||
5 | + info_only=info_only, $ | ||
6 | + info_st=info_st, $ | ||
7 | + help=help | ||
8 | + | ||
9 | +;+ | ||
10 | +; NAME: | ||
11 | +; dustem_read_emiles_stellar_templates | ||
12 | +; PURPOSE: | ||
13 | +; reads EMILES stellar population templates | ||
14 | +; CATEGORY: | ||
15 | +; DustEMWrap, Distributed, High-Level, User Example | ||
16 | +; CALLING SEQUENCE: | ||
17 | +; templates=dustem_read_emiles_stellar_templates(age_values,metalicity_values[,template_waves=][,Mstars=][,/info_only][,info_st=][,/help]) | ||
18 | +; INPUTS: | ||
19 | +; age_values : array of age values | ||
20 | +; metalicity_values : array of metalicity values | ||
21 | +; OPTIONAL INPUT PARAMETERS: | ||
22 | +; None | ||
23 | +; OUTPUTS: | ||
24 | +; templates : SSP templates (F_lambda) [Lsun Msun^-1 A^-1] | ||
25 | +; OPTIONAL OUTPUT PARAMETERS: | ||
26 | +; template_wav = common wavelength array for templates [Angstroem] | ||
27 | +; Mstars = Mass of stars [Msun] | ||
28 | +; info_st = info structure for the templates | ||
29 | +; ACCEPTED KEY-WORDS: | ||
30 | +; info_only : if set, read only the information structure | ||
31 | +; help : if set, prints this help | ||
32 | +; COMMON BLOCKS: | ||
33 | +; None | ||
34 | +; SIDE EFFECTS: | ||
35 | +; None | ||
36 | +; RESTRICTIONS: | ||
37 | +; The DustEM fortran code must be installed | ||
38 | +; The DustEMWrap IDL code must be installed | ||
39 | +; PROCEDURES AND SUBROUTINES USED: | ||
40 | +; | ||
41 | +; EXAMPLES | ||
42 | +; | ||
43 | +; MODIFICATION HISTORY: | ||
44 | +; Written by JPB June-2023 | ||
45 | +; Evolution details on the DustEMWrap gitlab. | ||
46 | +; See http://dustemwrap.irap.omp.eu/ for FAQ and help. | ||
47 | +;- | ||
48 | + | ||
49 | +IF keyword_set(help) THEN BEGIN | ||
50 | + doc_library,'dustem_read_emiles_stellar_templates' | ||
51 | + templates=-1 | ||
52 | + goto,the_end | ||
53 | +END | ||
54 | + | ||
55 | +dir_templates='/Users/jpb/Soft_Libraries/dustem-wrapper_idl/Data/SSPs/ssp_emiles-ch/' | ||
56 | + | ||
57 | +;read templates info file | ||
58 | +;IMF slope Z Age Mtotal M(*+remn) M* Mremn Mgas M(*+remn)/Lv M*/Lv Mv unknown | ||
59 | +file=dir_templates+'templates_info.txt' | ||
60 | +format='A,F,F,F,F,F,F,F,F,F,F,F,F' | ||
61 | +readcol,file,imf,slope,z,age,Mtot,Mstar_rem,Mstar,Mremn,Mgas,Mstar_rem_o_Lv,Mstar_o_Lv,Mv,unknown,format=format | ||
62 | +one_st={imf:'',slope:0.,z:0.,age:0.,Mtot:0.,Mstar_rem:0.,Mstar:0.,Mremn:0.,Mgas:0.,Mstar_rem_o_Lv:0.,Mstar_o_Lv:0.,Mv:0.,unknown:0.} | ||
63 | +info_st=replicate(one_st,n_elements(imf)) | ||
64 | +info_st.imf=imf | ||
65 | +info_st.slope=slope | ||
66 | +info_st.z=z | ||
67 | +info_st.age=age | ||
68 | +info_st.mtot=Mtot | ||
69 | +info_st.Mstar_rem=Mstar_rem | ||
70 | +info_st.Mstar=Mstar | ||
71 | +info_st.Mremn=Mremn | ||
72 | +info_st.Mgas=Mgas | ||
73 | +info_st.Mstar_rem_o_Lv=Mstar_rem_o_Lv | ||
74 | +info_st.Mstar_o_Lv=Mstar_o_Lv | ||
75 | +info_st.Mv=Mv | ||
76 | +info_st.unknown=unknown | ||
77 | +IF keyword_set(info_only) THEN BEGIN | ||
78 | + templates=info_st | ||
79 | + goto,the_end | ||
80 | +ENDIF | ||
81 | + | ||
82 | +;stop | ||
83 | + | ||
84 | +;file name format is ssp_emiles-ch/Ech1.30Zp0.40T13.5000_iTp0.00_baseFe_linear_FWHM_variable.fits | ||
85 | +;=== producing age and metalicity strings for file names | ||
86 | +age_values_4str=string(age_values,format='(F7.4)') | ||
87 | +FOR i=0L,n_elements(age_values_4str)-1 DO age_values_4str[i]=textoidl_str_replace(age_values_4str[i],' ','0') | ||
88 | +metalicity_values_4str=round(metalicity_values*100.)/100. ;This is the array for metalicity values in fits files names | ||
89 | +metalicity_values_4str=string(metalicity_values_4str,format='(F5.2)') | ||
90 | +FOR i=0L,n_elements(metalicity_values_4str)-1 DO metalicity_values_4str[i]=textoidl_str_replace(metalicity_values_4str[i],' ','p') | ||
91 | +FOR i=0L,n_elements(metalicity_values_4str)-1 DO metalicity_values_4str[i]=textoidl_str_replace(metalicity_values_4str[i],'-','m') | ||
92 | + | ||
93 | +;Ntemplates=n_elements(paramvalues)-1 | ||
94 | +Ntemplates=n_elements(age_values)*n_elements(metalicity_values) | ||
95 | +Nage=n_elements(age_values) | ||
96 | +Nmetalicity=n_elements(metalicity_values) | ||
97 | + | ||
98 | +templates=ptrarr(Ntemplates) | ||
99 | + | ||
100 | +;file names are like: Ech1.30Zm0.35T00.2500_iTp0.00_baseFe_linear_FWHM_variable.fits | ||
101 | +file_start='Ech1.30' | ||
102 | +file_end='_iTp0.00_baseFe_linear_FWHM_variable.fits' | ||
103 | +ii=0L | ||
104 | +Nage_str=6 | ||
105 | +Nmet_str=4 | ||
106 | +Mstars=fltarr(Ntemplates) | ||
107 | +files_not_found=[''] | ||
108 | +FOR i=1L,Ntemplates DO BEGIN | ||
109 | + zsign_str='p' | ||
110 | + ij=index2ij([i-1],[Nage,Nmetalicity]) | ||
111 | + iage=ij[0,0] | ||
112 | + imet=ij[0,1] | ||
113 | + age=age_values[iage] | ||
114 | + met=metalicity_values[imet] | ||
115 | + met_str=metalicity_values_4str[imet] | ||
116 | + age_str=age_values_4str[iage] | ||
117 | + message,'reading template for Age '+age_str+' Met '+met_str,/continue | ||
118 | + file=dir_templates+file_start+'Z'+met_str+'T'+age_str+file_end | ||
119 | + fi=file_info(file) | ||
120 | + IF fi.exists THEN BEGIN | ||
121 | + message,'Reading SSP '+file,/continue | ||
122 | + spec=readfits(file,h,2) | ||
123 | + templates[ii]=ptr_new(spec) | ||
124 | + make_axis,h,wavs | ||
125 | + ind=where(info_st.z EQ met AND info_st.age EQ age,count) | ||
126 | + IF count EQ 0 THEN BEGIN | ||
127 | + message,'age,met not found in template info',/continue | ||
128 | + stop | ||
129 | + ENDIF ELSE BEGIN | ||
130 | + Mstars[i-1]=info_st[ind[0]].Mstar | ||
131 | + ENDELSE | ||
132 | + ENDIF ELSE BEGIN | ||
133 | + message,'file not found '+file,/continue | ||
134 | + files_not_found=[files_not_found,file] | ||
135 | + ENDELSE | ||
136 | + ii=ii+1 | ||
137 | +ENDFOR | ||
138 | + | ||
139 | +IF n_elements(files_not_found) NE 1 THEN BEGIN | ||
140 | + files_not_found=files_not_found[1:*] | ||
141 | + message,strmid(n_elements(files_not_found),2)+' SSP files were not found :',/continue | ||
142 | + hprint,files_not_found | ||
143 | + stop | ||
144 | +ENDIF | ||
145 | + | ||
146 | +;Nspec=n_elements(spec) | ||
147 | +;print,min(wavs),max(wavs) | ||
148 | +; 3500.2000 12000.250 | ||
149 | +angstroem2mic=1.e6/1.e10 | ||
150 | +template_wav=wavs*angstroem2mic ;mic | ||
151 | + | ||
152 | +the_end: | ||
153 | + | ||
154 | +RETURN,templates | ||
155 | + | ||
156 | +END | ||
0 | \ No newline at end of file | 157 | \ No newline at end of file |