Commit 36e8b8799e318bbbda46193285659ccf8b166d62
1 parent
427f1205
Exists in
master
update from deborah
Showing
22 changed files
with
939 additions
and
276 deletions
Show diff stats
src/idl/dustem_cc.pro
... | ... | @@ -78,8 +78,8 @@ instrus=dustem_filter2instru(filter_names) |
78 | 78 | inst_tags=tag_names((*!dustem_filters)) |
79 | 79 | |
80 | 80 | ;DEBUG VG |
81 | -j=where(instrus eq 'HFI',count) | |
82 | -if count gt 0 then instrus(j) = 'HFI_V3P02' | |
81 | +;j=where(instrus eq 'HFI',count) | |
82 | +;if count gt 0 then instrus(j) = 'HFI_V3P02' | |
83 | 83 | |
84 | 84 | Nbands=n_elements(filter_names) |
85 | 85 | sed=dblarr(Nbands) | ... | ... |
src/idl/dustem_compute_polsed.pro
src/idl/dustem_data_tag.pro
src/idl/dustem_grains_colors.pro
1 | -FUNCTION dustem_grains_colors,Ngrains | |
1 | +FUNCTION dustem_grains_colors,Ngrains,ls,ps=ps | |
2 | 2 | |
3 | -colmax=210 & colmin=30 | |
4 | -colors=findgen(Ngrains)/(1.*Ngrains-1)*(colmax-colmin)+colmin | |
3 | +fixed_colors = [0,210,50,210,50,30,50,80,120,150,180,210,230,250] | |
4 | +;last_color = n_elements(fixed_colors)-1 | |
5 | +;colors = [0,fixed_colors(last_color-Ngrains+1:last_color)] | |
6 | +colors = [0,fixed_colors(1:Ngrains)] | |
7 | + | |
8 | +ls = [ [ 0,4,3,5,1 ], [ 0,4,3,5,1 ],[ 0,4,3,5,1 ] ] | |
9 | + | |
10 | +if keyword_set(ps) then begin | |
11 | + ; Postscript | |
12 | + !y.thick = 5 | |
13 | + !x.thick = 5 | |
14 | + !p.thick = 7 | |
15 | + !p.charsize = 1.3 | |
16 | + !p.charthick = 5 | |
17 | + !x.ticklen = 0.04 | |
18 | +endif else begin | |
19 | + j=where(colors eq 0) | |
20 | + colors(j)=255 | |
21 | +endelse | |
5 | 22 | |
6 | 23 | RETURN,colors |
7 | 24 | ... | ... |
src/idl/dustem_init.pro
... | ... | @@ -81,7 +81,8 @@ if keyword_set(pol) then begin |
81 | 81 | polsed: ptr_new(), $ |
82 | 82 | polfrac: ptr_new() $ |
83 | 83 | } |
84 | - rchi2_weight = {sed: 0.,ext: 0.,polext: 0.,polsed: 0.,polfrac:0.} | |
84 | + rchi2_weight = {sed: 0.,ext: 0.,polext: 0.,polsed: 0.,polfrac:0.} | |
85 | + | |
85 | 86 | endif else begin |
86 | 87 | defsysv, '!dustem_data', { $ ;Data to fit |
87 | 88 | sed: ptr_new(), $ |
... | ... | @@ -293,7 +294,7 @@ endif ; /noerase |
293 | 294 | IF keyword_set(wraptest) THEN BEGIN |
294 | 295 | dir_out=!dustem_dat |
295 | 296 | dustem_write_all,st_model,dir_out |
296 | - stop | |
297 | + ; stop | |
297 | 298 | st=dustem_run() |
298 | 299 | IF keyword_set(plot_it) THEN BEGIN |
299 | 300 | loadct,13 | ... | ... |
src/idl/dustem_mpfit_data.pro
... | ... | @@ -88,13 +88,14 @@ for j=0,n_elements(fields)-1 do begin |
88 | 88 | endelse |
89 | 89 | ;print,"WEIGHT",i,j,weight,n_elements((*!dustem_data.(i)).sigma),"/",n_elements(wav) |
90 | 90 | |
91 | - instruc += ', (*!dustem_data.(' + strtrim(i,2) + ')).'+fields(j)+'*'+strtrim(weight,2) | |
91 | + instruc += ', (*!dustem_data.(' + strtrim(ind_data_tag(i),2) + ')).'+fields(j)+'*'+strtrim(weight,2) | |
92 | 92 | ;print,"INSTRUC",instruc |
93 | 93 | |
94 | 94 | endfor |
95 | 95 | instruc += '])(1:*)' ; from 1 to exclude first 0 |
96 | 96 | ;print,'-> INSTRUC: ',instruc |
97 | - toto=execute(instruc) ; Variables wav, values & sigma are created | |
97 | + toto=execute(instruc) ; Variables wav, values & sigma are created | |
98 | + | |
98 | 99 | endfor |
99 | 100 | |
100 | 101 | p_min = dustem_mpfitfun(func_name,wav,values,sigma, $ | ... | ... |
src/idl/dustem_mpfit_run.pro
1 | -;VG | |
2 | - | |
3 | 1 | FUNCTION dustem_mpfit_run,x,p_min,_EXTRA=extra |
4 | 2 | |
5 | 3 | ;+ |
6 | 4 | ; NAME: |
7 | -; dustem_mpfit_run | |
5 | +; dustem_mpfit_run_vg | |
8 | 6 | ; PURPOSE: |
9 | 7 | ; function used to fit dustem model with dustem_mpfit_sed |
10 | 8 | ; CATEGORY: |
11 | 9 | ; Dustem |
12 | 10 | ; CALLING SEQUENCE: |
13 | -; res=dustem_mpfit_run(x,params[,_EXTRA=extra][,cc_sed=cc_sed][,/help]) | |
11 | +; res=dustem_mpfit_run_vg(x,params[,_EXTRA=extra][,cc_sed=cc_sed][,/help]) | |
14 | 12 | ; INPUTS: |
15 | 13 | ; x = necessary for interface but unused |
16 | 14 | ; params = Dustem Model parameters normalized to initial values |
... | ... | @@ -32,7 +30,7 @@ FUNCTION dustem_mpfit_run,x,p_min,_EXTRA=extra |
32 | 30 | ; PROCEDURE: |
33 | 31 | ; None |
34 | 32 | ; EXAMPLES |
35 | -; res=dustem_mpfit_run(x,params[,_EXTRA=extra][,cc_sed=cc_sed][,/help]) | |
33 | +; res=dustem_mpfit_run_vg(x,params[,_EXTRA=extra][,cc_sed=cc_sed][,/help]) | |
36 | 34 | ; MODIFICATION HISTORY: |
37 | 35 | ; Adapted to extinction and polarization by Vincent Guillet (IAS) |
38 | 36 | ; Written by J.-Ph. Bernard |
... | ... | @@ -42,16 +40,17 @@ FUNCTION dustem_mpfit_run,x,p_min,_EXTRA=extra |
42 | 40 | |
43 | 41 | ;note that x is not used. |
44 | 42 | |
43 | +;COMMON MPFIT_ERROR, ERROR_CODE | |
44 | + | |
45 | 45 | IF keyword_set(help) THEN BEGIN |
46 | - doc_library,'dustem_mpfit_run' | |
46 | + doc_library,'dustem_mpfit_run_vg' | |
47 | 47 | sed=0. |
48 | 48 | goto,the_end |
49 | 49 | ENDIF |
50 | -;stop | |
51 | 50 | |
52 | 51 | p_dim=p_min*(*(*!dustem_fit).param_init_values) |
52 | +;Run dustem with as an interface to mpfitfun | |
53 | 53 | |
54 | -;CALCULATE THE CONTINUUM | |
55 | 54 | IF !dustem_idl_continuum THEN cont=dustem_create_continuum() |
56 | 55 | |
57 | 56 | ;CALL THE DUSTEM_CREATE FUNCTIONS |
... | ... | @@ -66,173 +65,361 @@ dustem_create_functions,p_dim/(*(*!dustem_fit).param_init_values),cont=cont,res= |
66 | 65 | ;this call only if IONFRACPAH master-keyword in GRAIN.DAT |
67 | 66 | ;Removed for now (JPB). Use of ionfrac should be fully revisited. |
68 | 67 | IF !run_ionfrac gt 0. THEN toto = dustem_create_ionfrac() |
69 | - | |
70 | 68 | ;RUN THE MODEL AND GET THE SPECTRUM |
71 | 69 | st = dustem_run(p_dim) |
72 | - | |
73 | -;st_model=dustem_read_all(!dustem_soft_dir) | |
70 | +st_model=dustem_read_all(!dustem_soft_dir) | |
74 | 71 | |
75 | 72 | chi2_sed = 0 |
76 | 73 | chi2_ext = 0 |
77 | 74 | chi2_polext = 0 |
75 | +chi2_polsed = 0 | |
76 | +chi2_polfrac = 0 | |
78 | 77 | rchi2_sed = 0 |
79 | 78 | rchi2_ext = 0 |
80 | 79 | rchi2_polext = 0 |
80 | +rchi2_polsed = 0 | |
81 | +rchi2_polfrac = 0 | |
81 | 82 | wrchi2_sed = 0 |
82 | 83 | wrchi2_ext = 0 |
83 | 84 | wrchi2_polext = 0 |
85 | +wrchi2_polsed = 0 | |
86 | +wrchi2_polfrac = 0 | |
84 | 87 | n_sed = 0 |
85 | 88 | n_ext = 0 |
86 | 89 | n_polext = 0 |
90 | +n_polsed = 0 | |
91 | +n_polfrac = 0 | |
92 | + | |
93 | +win = 0 | |
87 | 94 | |
88 | 95 | tagnames=tag_names(!dustem_data) |
89 | 96 | dustem_out = [0] |
90 | -for i=0,n_tags(!dustem_data)-1 do begin | |
97 | +ind_data_tag=dustem_data_tag(count=count_data_tag) | |
98 | + | |
99 | +;if exist('./noplot') then !dustem_show_plot = 0 else if !dustem_show_plot eq 0 then !dustem_show_plot = 1 | |
91 | 100 | |
92 | - if !dustem_data.(i) eq ptr_new() then continue | |
101 | +for i_tag=0,count_data_tag-1 do begin | |
93 | 102 | |
94 | - CASE tagnames(i) OF | |
103 | +;print,i_tag,ind_data_tag(i_tag) | |
104 | +;print,tagnames(ind_data_tag(i_tag)) | |
105 | + CASE tagnames(ind_data_tag(i_tag)) OF | |
95 | 106 | |
96 | 107 | 'SED' : BEGIN |
97 | 108 | |
98 | - | |
99 | 109 | dustem_sed = dustem_compute_sed(p_dim,st,cont=cont) |
100 | - dustem_out = [ dustem_out, dustem_sed ] | |
101 | 110 | |
102 | - ; Plot if needed | |
103 | - IF !dustem_show_plot NE 0 THEN BEGIN | |
104 | - | |
105 | - window,1 | |
106 | - ;dustem_plot_fit_sed,st,dustem_sed,cont,_extra=extra,res=p_min*(*IDO),chi2=(*!dustem_fit).chi2,rchi2=(*!dustem_fit).rchi2 | |
107 | - dustem_plot_fit_sed,st,dustem_sed,cont,_extra=extra,res=p_min*(*(*!dustem_fit).param_init_values),chi2=(*!dustem_fit).chi2,rchi2=(*!dustem_fit).rchi2 | |
108 | - ; wait,0.5 ;Sorry for efficiency but needed to see the plot | |
109 | - | |
110 | - ENDIF | |
111 | + ; We normalize to 353 | |
112 | + ;x=min(((*!dustem_data.sed).wav-850)^2,j353) | |
113 | + ;dustem_sed = dustem_sed/dustem_sed(j353)*(*!dustem_data.sed).values(j353) | |
111 | 114 | |
112 | 115 | chi2_sed = total(((*!dustem_data.sed).values-dustem_sed)^2/(*!dustem_data.sed).sigma^2) |
113 | 116 | n_sed = n_elements((*!dustem_data.sed).values) |
114 | 117 | rchi2_sed = chi2_sed / n_sed |
115 | 118 | wrchi2_sed = rchi2_sed * !fit_rchi2_weight.sed |
116 | - print,"chi2 SED = ",chi2_sed," rchi2 SED = ",rchi2_sed | |
119 | + print,"chi2 SED = ",chi2_sed," rchi2 SED = ",rchi2_sed;," weighted rchi2 SED=",wrchi2_sed | |
120 | + ;print,'wl ',(*!dustem_data.sed).wav | |
121 | + ;print,"Delta SED per wl: ",(*!dustem_data.sed).values-dustem_sed | |
122 | + ;print,"error per wl: ",(*!dustem_data.sed).sigma | |
123 | + ;print,"chi2 per wl: ",((*!dustem_data.sed).values-dustem_sed)^2/(*!dustem_data.sed).sigma^2 | |
124 | + alpha = total(((*!dustem_data.sed).values*dustem_sed)/(*!dustem_data.sed).sigma^2) $ | |
125 | + / total(((*!dustem_data.sed).values)^2/(*!dustem_data.sed).sigma^2) | |
126 | + beta = total(((*!dustem_data.sed).values*dustem_sed)/(*!dustem_data.sed).sigma^2) $ | |
127 | + / total(dustem_sed^2/(*!dustem_data.sed).sigma^2) | |
128 | + | |
129 | + print,"Best SED chi2 obtained if f_HI = ",alpha, " or if we multiply model by ",beta | |
130 | + | |
131 | + ;dustem_plot_nuinu_em,st,dustem_sed,cont,/print_radiance,p_dim=p_dim | |
132 | + | |
133 | + ; Plot if needed | |
134 | + IF !dustem_show_plot NE 0 THEN BEGIN | |
135 | + window,0 | |
136 | + dustem_plot_fit_sed,st,dustem_sed,cont,_extra=extra,res=p_min*(*(*!dustem_fit).param_init_values),chi2=(*!dustem_fit).chi2,rchi2=(*!dustem_fit).rchi2 | |
137 | + ;ytit='Total intensity' | |
138 | + ;xtit=textoidl('\lambda (\mum)') | |
139 | + ;win+=1 | |
140 | + ;xr=[10,5e3] | |
141 | + ;yr=[5e-33,5.e-28] | |
142 | + ;nodiff = 0 | |
143 | + ;dustem_plot_nuinu_em_vg,st,dustem_sed,cont,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,/donotclose,multi=1,nodiff=nodiff | |
144 | + ;dustem_plot_nuinu_em_vg,st,dustem_sed,cont,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,multi=2,nodiff=nodiff | |
145 | + | |
146 | + ENDIF | |
147 | + | |
148 | + dustem_out = [ dustem_out, dustem_sed ] | |
117 | 149 | |
118 | 150 | END |
119 | 151 | |
120 | 152 | 'EXT' : BEGIN |
121 | 153 | |
122 | 154 | dustem_ext = interpol(st.ext.ext_tot,st.ext.wav,(*!dustem_data.ext).wav) |
123 | - dustem_out = [ dustem_out, dustem_ext ] | |
124 | - | |
125 | - ; Plot if needed | |
126 | - IF !dustem_show_plot NE 0 THEN BEGIN | |
127 | - window,2 | |
128 | - dustem_plot_ext,st,(*!dustem_params),yr=[1.e-6,1.e0],/ysty,xr=[1,400],/xsty | |
129 | - window,3 | |
130 | - dustem_plot_ext,st,(*!dustem_params),/UV,yr=[0,2.5],/ysty,xr=[0,10],/xsty | |
131 | - ENDIF | |
132 | - | |
133 | - dustem_ext = interpol(st.ext.ext_tot,st.ext.wav,(*!dustem_data.ext).wav) | |
134 | 155 | chi2_ext = total(((*!dustem_data.ext).values-dustem_ext)^2/(*!dustem_data.ext).sigma^2) |
135 | 156 | n_ext = n_elements((*!dustem_data.ext).values) |
136 | 157 | rchi2_ext = chi2_ext / n_ext |
137 | 158 | wrchi2_ext = rchi2_ext * !fit_rchi2_weight.ext |
138 | - print,"chi2 EXT = ",chi2_ext," rchi2 EXT = ",rchi2_ext | |
159 | + print,"chi2 EXT = ",chi2_ext," rchi2 EXT = ",rchi2_ext;," weighted rchi2 EXT=",wrchi2_ext | |
160 | + ;print,"chi2 per wl: ",((*!dustem_data.ext).values-dustem_ext)^2/(*!dustem_data.ext).sigma^2 | |
161 | + | |
162 | + ; Plot if needed | |
163 | + IF !dustem_show_plot NE 0 THEN BEGIN | |
164 | + | |
165 | + win+=1 | |
166 | + ;dustem_plot_ext,st,yr=[1.e-6,1.e0],/ysty,xr=[0.5,40],/xsty,win=win | |
167 | + xr=[0.3,40] | |
168 | + yr=[1.e-26,1.e-21] | |
169 | + dustem_plot_ext,st,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,/donotclose,multi=1 | |
170 | + dustem_plot_ext,st,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,multi=2 | |
171 | + | |
172 | + win+=1 | |
173 | + ;dustem_plot_ext,st,/UV,yr=[0,2.5],/ysty,xr=[0,10],/xsty,win=win | |
174 | + xr=[0.2,10] | |
175 | + yr=[0,3e-21] | |
176 | + dustem_plot_ext,st,/UV,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,/donotclose,multi=1 | |
177 | + dustem_plot_ext,st,/UV,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,mergePAH=mergePAH,multi=2 | |
178 | + | |
179 | + ENDIF | |
139 | 180 | |
181 | + dustem_plot_ext,st,/print_Rv | |
182 | + | |
183 | + dustem_out = [ dustem_out, dustem_ext ] | |
184 | + | |
140 | 185 | END |
141 | 186 | |
142 | 187 | 'POLEXT': BEGIN |
143 | 188 | |
144 | - dustem_polext = interpol(st.polext.ext_tot,st.polext.wav,(*!dustem_data.polext).wav) | |
145 | - dustem_out = [ dustem_out, dustem_polext ] | |
189 | + IF !dustem_show_plot NE 0 and !run_circ then begin | |
190 | + win+=1 | |
191 | + | |
192 | + dustem_plot_circ,st,win=win,xr=[0.1,5],aligned=st_model.align.grains.aligned,yr=[-0.03,0.03] | |
193 | + endif | |
194 | + | |
195 | + IF !run_lin then begin | |
196 | + | |
197 | + dustem_polext = interpol(st.polext.ext_tot,st.polext.wav,(*!dustem_data.polext).wav) | |
198 | + chi2_polext = total(((*!dustem_data.polext).values-dustem_polext)^2/(*!dustem_data.polext).sigma^2) | |
199 | + n_polext = n_elements((*!dustem_data.polext).values) | |
200 | + rchi2_polext = chi2_polext / n_polext | |
201 | + wrchi2_polext = rchi2_polext * !fit_rchi2_weight.polext | |
202 | + print,"chi2 POLEXT = ",chi2_polext," rchi2 POLEXT = ",rchi2_polext;," weighted rchi2 POLEXT=",wrchi2_polext | |
203 | + ;print,"chi2 per wl: ",((*!dustem_data.polext).values-dustem_polext)^2/(*!dustem_data.polext).sigma^2 | |
204 | + | |
205 | + ; Fit in (pmax,lmax,K) | |
206 | + x=st.polext.wav | |
207 | + logx=alog(x) | |
208 | + logy=alog(st.polext.ext_tot) | |
209 | + ;j=where(st.polext.ext_tot gt 0 and x gt 0.2 and x lt 1) | |
210 | + | |
211 | + ; Whittet+1992 (Table 1) | |
212 | + Uband = 0.36 | |
213 | + Bband = 0.43 | |
214 | + Vband = 0.55 | |
215 | + Rband = 0.63 | |
216 | + Iband = 0.78 | |
217 | + Jband = 1.21 | |
218 | + Hband = 1.64 | |
219 | + Kband = 2.04 | |
220 | + bands = [Uband,Bband,Vband,Rband,Iband,Jband,Hband] | |
221 | + nbands = n_elements(bands) | |
222 | + jband = indgen(nbands)*0 | |
223 | + for k=0,nbands-1 do begin | |
224 | + xx=min(abs(st.polext.wav-bands(k)),j) | |
225 | + jband(k) = j | |
226 | + endfor | |
227 | + ;j=where(st.polext.ext_tot gt 0 and x gt 0.2 and x lt 1) | |
228 | + res = poly_fit(logx(jband),logy(jband),2) | |
229 | + | |
230 | ||
231 | + print,"Serkowski Fit with free K over ",string(st.polext(jband).wav,format='(100F5.2)') | |
232 | + print,"-------------------------" | |
233 | + K = -res(2) | |
234 | + lmax = exp(res(1)/(2*K)) | |
235 | + pmax = exp(res(0)+K*alog(lmax)^2) | |
236 | + print,"* lmax = ",lmax," micron" | |
237 | + print,"* K = ",K | |
238 | + print,"* pmax = ",pmax," for NH=1e21" | |
239 | ||
240 | + | |
241 | + ; Plot if needed | |
242 | + IF !dustem_show_plot NE 0 THEN BEGIN | |
243 | + | |
244 | + ; Polarization fraction in the UV-IR | |
245 | + win+=1 | |
246 | + | |
247 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,yr=[0,0.15],/ysty,xr=[0.1,4],/xsty,win=win | |
248 | + | |
249 | + ; Polarisation curve (Serkowski) | |
250 | + win+=1 | |
251 | + xr=[0.1,50] | |
252 | + yr=[5e-25,5e-23] | |
253 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,/UV,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,cont=cont,/donotclose,multi=1 | |
254 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,/UV,yr=yr,/ysty,xr=xr,/xsty,ps=filename,win=win,cont=cont,multi=2 | |
255 | + | |
256 | + win+=1 | |
257 | + dustem_plot_fpol,win=win,xr=[10,1000],yr=[0,1.1] | |
258 | + | |
259 | + | |
260 | + ENDIF | |
261 | + | |
262 | + ;dustem_plot_polar,st,/print_ratio,cont=cont | |
263 | + | |
264 | + dustem_out = [ dustem_out, dustem_polext ] | |
265 | + | |
266 | + ENDIF | |
267 | + | |
268 | + END | |
269 | + | |
270 | + 'POLFRAC': BEGIN | |
271 | + | |
272 | + IF !run_lin then begin | |
273 | + | |
274 | + dustem_polsed = dustem_compute_polsed(p_dim,st.polsed,cont=cont) | |
275 | + dustem_sed_tmp = dustem_compute_sed(p_dim,st,cont=cont) | |
276 | + dustem_sed = dustem_polsed | |
277 | + ind_filt=where((*!dustem_data.polsed).filt_names NE 'SPECTRUM',count_filt) | |
278 | + for i = 0, count_filt-1 do begin | |
279 | + j=where((*!dustem_data.polsed).filt_names(ind_filt(i)) eq (*!dustem_data.sed).filt_names,count) | |
280 | + if count eq 1 then dustem_sed(i) = dustem_sed_tmp(j(0)) | |
281 | + endfor | |
282 | + dustem_polfrac = dustem_polsed/dustem_sed | |
283 | + | |
284 | + ; We normalize at 353GHz | |
285 | + ;x=min(((*!dustem_data.polfrac).wav-850)^2,j353) | |
286 | + ;dustem_polfrac = dustem_polfrac/dustem_polfrac(j353)*(*!dustem_data.polfrac).values(j353) | |
287 | + | |
288 | + chi2_polfrac = total(((*!dustem_data.polfrac).values-dustem_polfrac)^2/(*!dustem_data.polfrac).sigma^2) | |
289 | + n_polfrac = n_elements((*!dustem_data.polfrac).values) | |
290 | + rchi2_polfrac = chi2_polfrac / n_polfrac | |
291 | + wrchi2_polfrac = rchi2_polfrac * !fit_rchi2_weight.polfrac | |
292 | + print,"chi2 POLFRAC = ",chi2_polfrac," rchi2 POLFRAC = ",rchi2_polfrac;," weighted rchi2 POLFRAC=",wrchi2_polfrac | |
293 | + ;print,"chi2 per wl: ",((*!dustem_data.polfrac).values-dustem_polfrac)^2/(*!dustem_data.polfrac).sigma^2 | |
294 | + | |
295 | + dustem_out = [ dustem_out, dustem_polfrac ] | |
146 | 296 | |
147 | 297 | ; Plot if needed |
148 | 298 | IF !dustem_show_plot NE 0 THEN BEGIN |
149 | 299 | |
150 | - ; Polarization fraction in the UV-IR | |
151 | - window,4 | |
152 | - dustem_plot_polar,st,(*!dustem_params),yr=[0,0.08],/ysty,xr=[0.1,4],/xsty | |
153 | - | |
154 | - ; Polarisation curve (Serkowski) | |
155 | - window,5 | |
156 | - dustem_plot_polar,st,(*!dustem_params),/UV,yr=[1e-3,3e-2],/ysty,xr=[0.1,10],/xsty | |
157 | - | |
158 | - ; Also show prediction for polarized SED | |
159 | - window,6 | |
160 | - tit='Predicted polarization fraction in emission' | |
161 | - ytit='Polarization fraction' | |
162 | - xtit=textoidl('\lambda (\mum)') | |
163 | - xrange = st.sed.wav | |
164 | - Ngrains=n_tags(st.sed)-2 | |
165 | - colors=dustem_grains_colors(Ngrains) | |
166 | - | |
167 | - plot_oi,xrange,st.polsed.(Ngrains+1)/st.sed.(Ngrains+1),/nodata,xtit=xtit,ytit=ytit,tit=tit,yr=[0,0.3],/xlog | |
168 | - for i = 0, Ngrains-1 do oplot,xrange,st.polsed.(i+1)/st.sed.(i+1),color=colors(i),psym=psym,linestyle=2 | |
169 | - oplot,xrange,st.polsed.(Ngrains+1)/st.sed.(Ngrains+1),psym=psym,linestyle=2 | |
300 | + ; Also show prediction for polarized P/I | |
301 | + win+=1 | |
302 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,/Pfrac,win=win,cont=cont,yr=[0,0.25],/ysty,xr=[10,5d3] | |
170 | 303 | |
171 | 304 | ENDIF |
172 | 305 | |
173 | - dustem_polext = interpol(st.polext.ext_tot,st.polext.wav,(*!dustem_data.polext).wav) | |
174 | - chi2_polext = total(((*!dustem_data.polext).values-dustem_polext)^2/(*!dustem_data.polext).sigma^2) | |
175 | - n_polext = n_elements((*!dustem_data.polext).values) | |
176 | - rchi2_polext = chi2_polext / n_polext | |
177 | - wrchi2_polext = rchi2_polext * !fit_rchi2_weight.polext | |
178 | - print,"chi2 POLEXT = ",chi2_polext," rchi2 POLEXT = ",rchi2_polext | |
306 | + ENDIF | |
307 | + | |
308 | + END | |
309 | + | |
310 | + 'POLSED': BEGIN | |
311 | + | |
312 | + IF !run_lin then begin | |
313 | + | |
314 | + dustem_polsed = dustem_compute_polsed(p_dim,st.polsed,cont=cont) | |
315 | + | |
316 | + ; We normalize to 353 | |
317 | + ;x=min(((*!dustem_data.polsed).wav-850)^2,j353) | |
318 | + ;dustem_polsed = dustem_polsed/dustem_polsed(j353)*(*!dustem_data.polsed).values(j353) | |
319 | + | |
320 | + chi2_polsed = total(((*!dustem_data.polsed).values-dustem_polsed)^2/(*!dustem_data.polsed).sigma^2) | |
321 | + n_polsed = n_elements((*!dustem_data.polsed).values) | |
322 | + rchi2_polsed = chi2_polsed / n_polsed | |
323 | + wrchi2_polsed = rchi2_polsed * !fit_rchi2_weight.polsed | |
324 | + print,"chi2 POLSED = ",chi2_polsed," rchi2 POLSED = ",rchi2_polsed;," weighted rchi2 POLSED=",wrchi2_polsed | |
325 | + print,"chi2 per wl: ",((*!dustem_data.polsed).values-dustem_polsed)^2/(*!dustem_data.polsed).sigma^2 | |
326 | + ;print,"SNR per wl: ",(*!dustem_data.polsed).values/(*!dustem_data.polsed).sigma | |
327 | + | |
328 | + dustem_out = [ dustem_out, dustem_polsed ] | |
329 | + | |
330 | + ; Plot if needed | |
331 | + IF !dustem_show_plot NE 0 THEN BEGIN | |
332 | + | |
333 | + win+=1 | |
334 | + xr=[10,5e3] | |
335 | + yr=[1e-34,1e-28] | |
336 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,/SED,ps=filename,win=win,cont=cont,xr=xr,yr=yr,/xsty,/donotclose,multi=1 | |
337 | + dustem_plot_polar,st,aligned=st_model.align.grains.aligned,/SED,ps=filename,win=win,cont=cont,xr=xr,yr=yr,/xsty,multi=2 | |
338 | + | |
339 | + ENDIF | |
340 | + | |
341 | + ENDIF | |
179 | 342 | |
180 | 343 | END |
181 | 344 | |
182 | - | |
183 | - else : stop | |
345 | + ELSE : stop | |
184 | 346 | |
185 | 347 | ENDCASE |
186 | 348 | |
187 | 349 | endfor |
188 | 350 | |
189 | -; Size distribution | |
190 | -;window,7 | |
191 | -;fn = path+'out/SDIST.RES' | |
192 | -;OPENR, uu, fn, /get_lun | |
193 | -;tt = '#' | |
194 | -;WHILE STRPOS(tt,'#') EQ 0 do begin | |
195 | -;READF, uu, tt | |
196 | -;ENDWHILE | |
197 | -;ax = dblarr(ntype,nsz_max) | |
198 | -;ava = dblarr(ntype,nsz_max) | |
199 | -;FOR i=0,ntype-1 do begin | |
200 | -;READF,uu,tt | |
201 | -;for is=0,nsize(i)-1 do begin | |
202 | -;READF, uu, tx, ty | |
203 | -;ax(i,is) = tx | |
204 | -;ava(i,is) = ty | |
205 | -;endfor | |
206 | -;ENDFOR | |
207 | -;close,uu | |
208 | - | |
209 | -;tit='Dust size distributions' | |
210 | -;yscl = 1.D29 | |
211 | -;xr=[0.1,1e3] | |
212 | -;yr=[-2,3] | |
213 | -;xtit='a (nm)' | |
214 | -;ytit='Mass log( 10!u29!n n!dH!u-1!n a dm/da ) ' | |
215 | -;plot_oi, ax(0,0:nsize(0)-1)*1.e7, alog10(ava(0,0:nsize(0)-1)*yscl), line=ls(i+1),xr=xr,/xs,xtit=xtit,/ys,yr=yr,ytit=ytit,tit='DUSTEM' | |
216 | -;FOR i=1,ntype-1 DO begin | |
217 | -; oplot, ax(i,0:nsize(i)-1)*1.e7, alog10(ava(i,0:nsize(i)-1)*yscl), line=ls(i+1) | |
218 | -;ENDFOR | |
219 | - | |
220 | -print,"Total chi2 = ",chi2_sed+chi2_ext+chi2_polext | |
221 | -print,"Total weighted reduced chi2 driving mpfitfun = ", wrchi2_sed+wrchi2_ext+wrchi2_polext | |
222 | - | |
351 | +; 4 bands fit : IRAS 100 and 857 down to 353 GHz | |
352 | +;fit_sed,"~/tmp/out/SED.RES",['IRAS','HFI'],iband=[0,0,0,1,1,1,1,1,1,0],beta=fixbeta,/noplot | |
353 | +DOF = n_elements(p_min) | |
354 | +total_chi2 = 0 | |
355 | +total_rchi2 = 0 | |
356 | +total_n = 0 | |
357 | +if !fit_rchi2_weight.ext ne 0 then begin | |
358 | + total_n += n_ext | |
359 | + total_chi2 += chi2_ext | |
360 | + total_rchi2 += rchi2_ext | |
361 | +endif | |
362 | +if !fit_rchi2_weight.sed ne 0 then begin | |
363 | + total_n += n_sed | |
364 | + total_chi2 += chi2_sed | |
365 | + total_rchi2 += rchi2_sed | |
366 | +endif | |
367 | +if !run_pol then begin | |
368 | +if !fit_rchi2_weight.polext ne 0 then begin | |
369 | + total_n += n_polext | |
370 | + total_chi2 += chi2_polext | |
371 | + total_rchi2 += rchi2_polext | |
372 | +endif | |
373 | +if !fit_rchi2_weight.polsed ne 0 then begin | |
374 | + total_n += n_polsed | |
375 | + total_chi2 += chi2_polsed | |
376 | + total_rchi2 += rchi2_polsed | |
377 | +endif | |
378 | +if !fit_rchi2_weight.polfrac ne 0 then begin | |
379 | + total_n += n_polfrac | |
380 | + total_chi2 += chi2_polfrac | |
381 | + total_rchi2 += rchi2_polfrac | |
382 | +endif | |
383 | +endif | |
384 | + | |
385 | +total_wchi2 = chi2_ext * !fit_rchi2_weight.ext $ | |
386 | + + chi2_sed * !fit_rchi2_weight.sed | |
387 | +if !run_pol then begin | |
388 | + total_wchi2 += chi2_polext * !fit_rchi2_weight.polext $ | |
389 | + + chi2_polsed * !fit_rchi2_weight.polsed $ | |
390 | + + chi2_polfrac * !fit_rchi2_weight.polfrac | |
391 | +endif | |
392 | + | |
393 | ||
394 | +print,"Total weighted chi2 driving mpfitfun = ", total_wchi2 | |
395 | +print,"Nb of data points = ", total_n | |
396 | +print,"DOF = ", DOF | |
397 | +print,"Reduced chi2 EXT/SED/POLEXT/POLSED/POLFRAC",rchi2_ext,rchi2_sed,rchi2_polext,rchi2_polsed,rchi2_polfrac | |
398 | +print,"Weighted reduced chi2 EXT/SED/POLEXT/POLSED/POLFRAC",wrchi2_ext,wrchi2_sed,wrchi2_polext,wrchi2_polsed,wrchi2_polfrac | |
399 | +if !run_pol then print,"Weights",!fit_rchi2_weight.ext,!fit_rchi2_weight.sed,!fit_rchi2_weight.polext,!fit_rchi2_weight.polsed,!fit_rchi2_weight.polfrac $ | |
400 | +else print,"Weights",!fit_rchi2_weight.ext,!fit_rchi2_weight.sed | |
401 | +print,"Mean weighted reduced chi2 = ", total_wchi2/(total_n-DOF) | |
402 | +print,"Unweighted reduced Total chi2 = ", total_chi2/(total_n-DOF) | |
403 | +print,"Unweighted mean reduced chi2 = ", total_rchi2/4*total_n/(total_n-DOF) | |
404 | + | |
405 | +;print,"Total reduced chi2 = ", (wrchi2_sed+wrchi2_ext+wrchi2_polext+wrchi2_polsed+wrchi2_polfrac)/(n_sed+n_ext+n_polext+n_polsed+n_polfrac-DOF) | |
406 | +; Reduced chi2 is like if there were the same nb of data points for each curve | |
407 | +;print,"Mean reduced chi2 = ", (wrchi2_sed+wrchi2_ext+wrchi2_polext+wrchi2_polsed+wrchi2_polfrac) * total_n/(total_n-DOF) | |
408 | + | |
409 | +; Plot size distribution | |
410 | +win+=1 | |
411 | +xr=[0.3,5e3] | |
412 | +yr=[0.1,100] | |
413 | +IF !dustem_show_plot NE 0 THEN dustem_plot_sdist,xr=xr,yr=yr,ps=filename,win=win;,/donotclose | |
223 | 414 | |
224 | 415 | ; Suppress the artificial [0] at the beginning |
225 | 416 | dustem_out = dustem_out[1:*] |
226 | 417 | |
227 | -;=== Caution, do not use message below here, even | |
228 | -;=== with the /info and /contine options, or the | |
229 | -;=== fit procedure will detect an error ! | |
230 | -;=== use print instead. | |
231 | 418 | IF defined(extra) THEN BEGIN |
232 | 419 | IF keyword_set(extra.plot_it) THEN BEGIN |
233 | 420 | ; message,'params='+strtrim(p_min,2),/info,/continue |
234 | 421 | ; stop |
235 | - print,'dustem_mpfit_run: Current parameters values:',p_dim | |
422 | + print,'dustem_mpfit_run_vg: Current parameters values:',p_dim | |
236 | 423 | ENDIF |
237 | 424 | ENDIF |
238 | 425 | ... | ... |
src/idl/dustem_plot_ext.pro
... | ... | @@ -100,7 +100,7 @@ endif else if keyword_set(albedo) then begin |
100 | 100 | ytit=textoidl('albedo') |
101 | 101 | plot,xrange,/nodata,xtit=xtit,ytit=ytit,tit=tit,xlog=xlog,ylog=ylog,yr=yr,ys=ys,xr=xr,xsty=xsty |
102 | 102 | oplot,xrange,sca_tot/(sca_tot+abs_tot) |
103 | - stop | |
103 | + | |
104 | 104 | |
105 | 105 | endif else begin |
106 | 106 | |
... | ... | @@ -116,7 +116,7 @@ endif else begin |
116 | 116 | |
117 | 117 | Ngrains=n_tags(st.sed)-2 |
118 | 118 | colors=dustem_grains_colors(Ngrains,ls,ps=ps) |
119 | - | |
119 | +; stop | |
120 | 120 | ytit=textoidl('\sigma_{ext}/N_H (cm^2/H)') |
121 | 121 | if not keyword_set(ps) then tit='Dustem extinction' |
122 | 122 | ... | ... |
src/idl/dustem_plot_fpol.pro
... | ... | @@ -18,7 +18,8 @@ endif else begin |
18 | 18 | endelse |
19 | 19 | endif |
20 | 20 | |
21 | -st_grains=dustem_read_grain(dir_in+'data/'+(*!dustem_inputs).grain,/silent) | |
21 | +;st_grains=dustem_read_grain(dir_in+'data/'+(*!dustem_inputs).grain,/silent) | |
22 | +st_grains=dustem_read_grain(dir_in+'data/'+'GRAIN.DAT',/silent) | |
22 | 23 | |
23 | 24 | ngrains = st_grains.ngrains |
24 | 25 | colors=dustem_grains_colors(Ngrains,ls,ps=ps) | ... | ... |
src/idl/dustem_plot_nuinu_em.pro
src/idl/dustem_plot_polar.pro
... | ... | @@ -82,7 +82,8 @@ xtit=textoidl('\lambda (\mum)') |
82 | 82 | ; Are observational data defined ? |
83 | 83 | defsysv,'!dustem_data',exists=data_exists |
84 | 84 | |
85 | -if keyword_set(print_ratio) then begin | |
85 | +if ptr_valid(!dustem_data.polext) then begin | |
86 | + if keyword_set(print_ratio) then begin | |
86 | 87 | |
87 | 88 | ; Correction de couleur |
88 | 89 | cc = 1.11 |
... | ... | @@ -112,9 +113,14 @@ if keyword_set(print_ratio) then begin |
112 | 113 | tauV_data = interpol((*!dustem_data.ext).values,(*!dustem_data.ext).wav,Vband) |
113 | 114 | tauB = interpol(st.ext.ext_tot,st.ext.wav,Bband) |
114 | 115 | tauB_data = interpol((*!dustem_data.ext).values,(*!dustem_data.ext).wav,Bband) |
116 | ||
117 | + | |
115 | 118 | |
116 | 119 | ; I353 and P353 are in fact nu_Pnu, in unit of erg/s/H, not erg/s/sr/H |
117 | - ; 1 W/m2/sr/1d20H = 1e-17 erg/s/sr/H | |
120 | + ; 1 W/m2/sr/1d20H = 1e-17 erg/s/sr/H | |
121 | +endif | |
122 | +if ptr_valid(!dustem_data.polsed) then begin | |
123 | + | |
118 | 124 | dustem_polsed = dustem_compute_polsed(p_dim,st.polsed,cont=cont) |
119 | 125 | x=min(((*!dustem_data.polsed).wav-850)^2,jmin) |
120 | 126 | P353 = dustem_polsed(jmin) |
... | ... | @@ -132,26 +138,33 @@ if keyword_set(print_ratio) then begin |
132 | 138 | |
133 | 139 | print,"Observational constraint" |
134 | 140 | print,"-------------------------" |
141 | + print,"I353/NH data ",I353_data," MJy/sr for NH=1e20" | |
142 | + print,"P353/NH data ",P353_data," MJy/sr for NH=1e20" | |
143 | + print,"P353/I353 data ",P353_data/I353_data*100," %" | |
144 | ||
145 | + print,"Model results" | |
146 | + print,"-------------" | |
147 | + print,"I353/NH model ",I353," MJy/sr for NH=1e20" | |
148 | + print,"P353/NH model ",P353," MJy/sr for NH=1e20" | |
149 | + print,"P353/I353 model ",P353/I353*100," %" | |
150 | + | |
151 | + if keyword_set(print_ratio) then begin | |
152 | ||
153 | + print,"Observational constraint" | |
154 | + print,"-------------------------" | |
155 | + | |
135 | 156 | print,"tau_V data ",tauV_data |
136 | 157 | print,"(p/tau)_V data ",pV_data/tauV_data*100," %" |
137 | 158 | print,"p_V/A_V data ",pV_data/(tauV_data*1.086)*100," %" |
138 | 159 | print,"with p_V data ",pV_data," %" |
139 | - print,"I353/NH data ",I353_data," MJy/sr for NH=1e20" | |
140 | - print,"P353/NH data ",P353_data," MJy/sr for NH=1e20" | |
141 | - print,"P353/I353 data ",P353_data/I353_data*100," %" | |
142 | 160 | print,"Rs/v data ",(P353_data/I353_data)/(pv_data/tauv_data) |
143 | 161 | print,"RP/p data ",(P353_data/1e20) / (pv_data*1e-21)," MJy/sr" |
144 | 162 | print,"I353/Av data ",(I353_data/1e20) / (1.086*tauv_data*1e-21)," MJy/sr" |
145 | 163 | |
146 | - print,"Model results" | |
147 | - print,"-------------" | |
148 | 164 | print,"(p/tau)_V model ",pV/tauV*100," %" |
149 | 165 | print,"p_V/A_V model ",pV/(tauV*1.086)*100," %" |
150 | 166 | print,"p_V/E(B-V) model ",pV/((tauB-tauV)*1.086)*100," %" |
151 | 167 | print,"with p_V model ",pV," %" |
152 | - print,"I353/NH model ",I353," MJy/sr for NH=1e20" | |
153 | - print,"P353/NH model ",P353," MJy/sr for NH=1e20" | |
154 | - print,"P353/I353 model ",P353/I353*100," %" | |
155 | 168 | print,"Rs/v model ",P353/I353/(pV/tauV) |
156 | 169 | print,"Rs/EBV model ",P353/I353/(pV/(tauB-tauV)) |
157 | 170 | print,"RP/p model ",(P353/1e20) / (pv*1e-21)," MJy/sr" |
... | ... | @@ -172,13 +185,14 @@ if keyword_set(print_ratio) then begin |
172 | 185 | ;print,"Rs/v P353model/I353data/(pVmodel/tauVdata) ",P353/I353_data/(pV/tauV_data) |
173 | 186 | ;print,"RP/p P353model/pVdata ",(P353/1e20)/(pV_data*1e-21)," MJy/sr" |
174 | 187 | |
175 | - | |
188 | + endif | |
189 | + endif | |
176 | 190 | |
177 | 191 | endif else if keyword_set(UV) then begin |
178 | 192 | |
179 | 193 | if not keyword_set(ps) then tit='Dustem polarization cross-section' |
180 | 194 | ytit=textoidl('\sigma_{pol}/N_H (cm^2/H)') |
181 | - | |
195 | +if ptr_valid(!dustem_data.polext) then begin | |
182 | 196 | if !dustem_show_plot EQ 2 or multi eq 2 then begin |
183 | 197 | ;normpol = polext_tot |
184 | 198 | normpol = st.polext.ext_tot |
... | ... | @@ -193,7 +207,9 @@ endif else if keyword_set(UV) then begin |
193 | 207 | |
194 | 208 | if multi eq 0 then plot_oo,st.polext.wav,st.polext.ext_tot/normpol,/nodata,_Extra=extra,xtit=xtit,ytit=ytit,tit=tit,xr=xr,yr=yr,ylog=ylog |
195 | 209 | if multi eq 1 then plot_oo,st.polext.wav,st.polext.ext_tot/normpol,/nodata,_Extra=extra,xtit='',ytit=ytit,tit=tit,xr=xr,yr=yr,ylog=ylog,position=[0.17,0.35,0.95,0.95],xtickformat='(A1)' |
196 | - if multi eq 2 then plot_oo,st.polext.wav,st.polext.ext_tot/normpol,/nodata,_Extra=extra,xtit=xtit,ytit='Normalized',tit='',xr=xr,yr=[-1,2],ylog=ylog,position=[0.17,0.14,0.95,0.35],/noerase,yticks=3,ymino=5,xticklen=0.1 | |
210 | + if multi eq 2 then plot_oo,st.polext.wav,st.polext.ext_tot/normpol,/nodata,_Extra=extra,xtit=xtit,ytit='Normalized',tit='',xr=xr,yr=[-1,2],ylog=ylog,position=[0.17,0.14,0.95,0.35],/noerase,yticks=3,ymino=5,xticklen=0.1 | |
211 | + | |
212 | + | |
197 | 213 | FOR i=0L,Ngrains-1 DO if aligned(i) then oplot,st.polext.wav,(st.polext.abs_grain(i)+st.polext.sca_grain(i))/normpol,color=colors(i+1),psym=psym,line=ls(i+1) |
198 | 214 | |
199 | 215 | if total(aligned gt 0) then oplot,st.polext.wav,st.polext.ext_tot/normpol,psym=psym |
... | ... | @@ -203,8 +219,8 @@ endif else if keyword_set(UV) then begin |
203 | 219 | oplot, (*!dustem_data.polext).wav,(*!dustem_data.polext).values/dustem_polext,ps=4 |
204 | 220 | if not keyword_set(noerrbars) then err_bar,(*!dustem_data.polext).wav,(*!dustem_data.polext).values/dustem_polext,yrms=(*!dustem_data.polext).sigma/dustem_polext |
205 | 221 | endif |
206 | - | |
207 | -; ; Fit in (pmax,lmax,K) | |
222 | + endif | |
223 | + ; ; Fit in (pmax,lmax,K) | |
208 | 224 | ; x=st.polext.wav |
209 | 225 | ; logx=alog(x) |
210 | 226 | ; |
... | ... | @@ -238,7 +254,7 @@ endif else if keyword_set(UV) then begin |
238 | 254 | ; ; overplot the fit |
239 | 255 | ; ;oplot,x(j),exp(res(0)+logx(j)*res(1)-K*logx(j)^2),col=150 |
240 | 256 | |
241 | -endif else if keyword_set(SED) then begin | |
257 | +endif else if ptr_valid(!dustem_data.polsed) then begin | |
242 | 258 | |
243 | 259 | ;device, filename = 'plot008.eps', /color, /encapsulated |
244 | 260 | if not keyword_set(ps) then tit='Polarization intensity in emission' | ... | ... |
src/idl/dustem_plot_sdist.pro
... | ... | @@ -52,12 +52,13 @@ xtit=textoidl('a (\mu m)') |
52 | 52 | norm_size = 1.d7 |
53 | 53 | norm_size = 1.d4 |
54 | 54 | xr /=1d3 |
55 | + | |
55 | 56 | ;ytit='Mass log( 10!u29!n n!dH!u-1!n a dm/da ) ' |
56 | 57 | ytit=textoidl('4\pi/3 a^3dn/d ln a (cm^3/H)') |
57 | 58 | if multi eq 0 then plot_oo, xr, /nodata,xr=xr,/xs,xtit=xtit,/ys,yr=yr,ytit=ytit,tit='' |
58 | 59 | if multi eq 1 then plot_oo, xr, /nodata,xr=xr,/xs,xtit='',/ys,yr=yr,ytit=ytit,tit='',position=[0.17,0.45,0.95,0.95],xtickformat='(A1)' |
59 | 60 | colors=dustem_grains_colors(ntype,ls,ps=ps) |
60 | - | |
61 | +;stop | |
61 | 62 | FOR i=0,ntype-1 DO begin |
62 | 63 | ;if i le 1 and keyword_set(mergePAH) then begin |
63 | 64 | ; if i eq 0 then oplot, ax(0,0:nsize(0)-1)*1.e7, alog10(ava(0,0:nsize(0)-1)*yscl)+alog10(ava(1,0:nsize(1)-1)*yscl), line=ls(1),color = colors(1) | ... | ... |
src/idl/dustem_read_align.pro
... | ... | @@ -42,20 +42,22 @@ one_st={aligned:0.,law:'',athresh:0.,plev:0.,pstiff:0.,TdsTg:0.,a0:0.,rvcut:0.} |
42 | 42 | st=replicate(one_st,st_grains.Ngrains) |
43 | 43 | |
44 | 44 | st.aligned = stregex(st_grains.grains.type_keywords, 'pol', /bool) |
45 | - | |
45 | +;count=0 | |
46 | 46 | FOR i=0L,st_grains.Ngrains-1 DO BEGIN |
47 | - | |
48 | - IF st(i).aligned then begin | |
49 | - | |
50 | - readf,unit,str,format='(A100)' | |
47 | + IF st(i).aligned then begin | |
48 | + ; if count EQ 0. then begin | |
49 | + readf,unit,str,format='(A100)' | |
50 | + ;endif | |
51 | + | |
51 | 52 | strv=str_sep(strcompress(strtrim(str,2)),' ') |
52 | 53 | Nstrv=n_elements(strv) |
53 | - | |
54 | + | |
54 | 55 | ii=0L |
55 | - st(i).law=strv(ii) & ii=ii+1 | |
56 | + st(i).law=strv(ii) & ii=ii+1 | |
56 | 57 | |
57 | 58 | ; IDG |
58 | - IF stregex(st(i).law, 'idg', /bool) THEN begin | |
59 | + IF stregex(st(i).law, 'idg', /bool) THEN begin | |
60 | + ii=ii+1 | |
59 | 61 | st(i).TdsTg = strv(ii) & ii=ii+1 |
60 | 62 | st(i).a0 = strv(ii) & ii=ii+1 |
61 | 63 | st(i).rvcut = strv(ii) & ii=ii+1 |
... | ... | @@ -66,19 +68,25 @@ FOR i=0L,st_grains.Ngrains-1 DO BEGIN |
66 | 68 | endif |
67 | 69 | |
68 | 70 | ; PARAMETRIC |
69 | - IF stregex(st(i).law, 'par', /bool) THEN begin | |
70 | - ; Grain radius Threshold for alignment, given in microns and converted in cm | |
71 | + IF stregex(st(i).law, 'par', /bool) THEN begin | |
72 | + ; Grain radius Threshold for | |
73 | + ; alignment, given in microns and | |
74 | + ; converted in cm | |
71 | 75 | st(i).athresh = strv(ii) & ii=ii+1 |
72 | 76 | st(i).pstiff = strv(ii) & ii=ii+1 |
73 | - st(i).plev = strv(ii) & ii=ii+1 | |
77 | + st(i).plev = strv(ii) & ii=ii+1 | |
78 | + ; count=1 | |
74 | 79 | endif |
75 | 80 | |
76 | 81 | IF !run_univ eq 1 then begin |
77 | 82 | st = replicate(st(i),st_grains.Ngrains) |
78 | - st.aligned = stregex(st_grains.grains.type_keywords, 'pol', /bool) | |
83 | + st.aligned = stregex(st_grains.grains.type_keywords, 'pol', /bool) | |
84 | + ;stop | |
79 | 85 | break |
80 | 86 | endif |
81 | - | |
87 | + | |
88 | + | |
89 | + | |
82 | 90 | ENDIF |
83 | 91 | |
84 | 92 | ENDFOR |
... | ... | @@ -87,6 +95,7 @@ close,unit |
87 | 95 | free_lun,unit |
88 | 96 | |
89 | 97 | full_st={keywords:key_str,anisG0:anisG0,gamma:0,grains:st} |
98 | + | |
90 | 99 | RETURN,full_st |
91 | 100 | |
92 | 101 | END | ... | ... |
src/idl/dustem_read_all_res.pro
... | ... | @@ -73,6 +73,7 @@ CASE !dustem_which OF |
73 | 73 | file=dir_out+'out/'+'EXT.RES' |
74 | 74 | st_ext=dustem_read_ext_lv(file,silent=silent) |
75 | 75 | ;VGb : add polarization |
76 | + | |
76 | 77 | if !run_pol then begin |
77 | 78 | file=dir_out+'out/'+'SED_POL.RES' |
78 | 79 | st_polsed=dustem_read_dustem_lv(file,silent=silent) | ... | ... |
src/idl/dustem_set_data.pro
... | ... | @@ -52,6 +52,7 @@ ENDIF |
52 | 52 | ;=== clean the data structure |
53 | 53 | !dustem_data.sed = ptr_new() |
54 | 54 | !dustem_data.ext = ptr_new() |
55 | + | |
55 | 56 | if keyword_set(polext) then !dustem_data.polext = ptr_new() |
56 | 57 | if keyword_set(polsed) then !dustem_data.polsed = ptr_new() |
57 | 58 | if keyword_set(polfrac) then !dustem_data.polfrac = ptr_new() |
... | ... | @@ -108,7 +109,8 @@ IF keyword_set(polfrac) THEN BEGIN |
108 | 109 | ENDIF |
109 | 110 | |
110 | 111 | IF keyword_set(polext) THEN BEGIN |
111 | - wavs=polext.wave | |
112 | + wavs=polext.wave | |
113 | + | |
112 | 114 | ;=== Impose central wavelengths for photometric channels |
113 | 115 | ind=where(polext.filter NE 'SPECTRUM',count) |
114 | 116 | IF count NE 0 THEN BEGIN |
... | ... | @@ -116,7 +118,7 @@ IF keyword_set(polext) THEN BEGIN |
116 | 118 | ENDIF |
117 | 119 | ;=== define observations structure |
118 | 120 | obs_st={instru_names:polext.instru,filt_names:polext.filter,wav:wavs, values:polext.spec,sigma:polext.error} |
119 | - ;=== fill !dustem_data | |
121 | + ;=== fill !dustem_data | |
120 | 122 | !dustem_data.polext = ptr_new(obs_st) |
121 | 123 | ENDIF |
122 | 124 | ... | ... |
src/idl/mpfit.pro
... | ... | @@ -118,7 +118,7 @@ |
118 | 118 | ; caller gracefully. However, during the debugging process, it is |
119 | 119 | ; often useful to halt execution where the error occurred. When you |
120 | 120 | ; set the NOCATCH keyword, MPFIT will not do any special error |
121 | -; trapping, and execution will stop where ever the error occurred. | |
121 | +; trapping, and execution will stop whereever the error occurred. | |
122 | 122 | ; |
123 | 123 | ; MPFIT does not explicitly change the !ERROR_STATE variable |
124 | 124 | ; (although it may be changed implicitly if MPFIT calls MESSAGE). It |
... | ... | @@ -164,9 +164,9 @@ |
164 | 164 | ; individual values of PARINFO.MPSIDE. Setting AUTODERIVATIVE=0 is |
165 | 165 | ; equivalent to resetting PARINFO.MPSIDE=3 for all parameters. |
166 | 166 | ; |
167 | -; However, be aware that even if the user requests explicit | |
168 | -; derivatives for some or all parameters, MPFIT will not always | |
169 | -; request explicit derivatives on ever user function call. | |
167 | +; Even if the user requests explicit derivatives for some or all | |
168 | +; parameters, MPFIT will not always request explicit derivatives on | |
169 | +; every user function call. | |
170 | 170 | ; |
171 | 171 | ; EXPLICIT DERIVATIVES - CALLING INTERFACE |
172 | 172 | ; |
... | ... | @@ -303,6 +303,14 @@ |
303 | 303 | ; that the derivatives computed in two different ways have the same |
304 | 304 | ; numerical sign and the same order of magnitude, since these are the |
305 | 305 | ; most common programming mistakes. |
306 | +; | |
307 | +; A line of this form may also appear | |
308 | +; | |
309 | +; # FJAC_MASK = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 | |
310 | +; | |
311 | +; This line indicates for which parameters explicit derivatives are | |
312 | +; expected. A list of all-1s indicates all explicit derivatives for | |
313 | +; all parameters are requested from the user function. | |
306 | 314 | ; |
307 | 315 | ; |
308 | 316 | ; CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD |
... | ... | @@ -448,6 +456,25 @@ |
448 | 456 | ; constrained to be above 50. |
449 | 457 | ; |
450 | 458 | ; |
459 | +; RECURSION | |
460 | +; | |
461 | +; Generally, recursion is not allowed. As of version 1.77, MPFIT has | |
462 | +; recursion protection which does not allow a model function to | |
463 | +; itself call MPFIT. Users who wish to perform multi-level | |
464 | +; optimization should investigate the 'EXTERNAL' function evaluation | |
465 | +; methods described below for hard-to-evaluate functions. That | |
466 | +; method places more control in the user's hands. The user can | |
467 | +; design a "recursive" application by taking care. | |
468 | +; | |
469 | +; In most cases the recursion protection should be well-behaved. | |
470 | +; However, if the user is doing debugging, it is possible for the | |
471 | +; protection system to get "stuck." In order to reset it, run the | |
472 | +; procedure: | |
473 | +; MPFIT_RESET_RECURSION | |
474 | +; and the protection system should get "unstuck." It is save to call | |
475 | +; this procedure at any time. | |
476 | +; | |
477 | +; | |
451 | 478 | ; COMPATIBILITY |
452 | 479 | ; |
453 | 480 | ; This function is designed to work with IDL 5.0 or greater. |
... | ... | @@ -457,6 +484,53 @@ |
457 | 484 | ; of the IDL Virtual Machine. |
458 | 485 | ; |
459 | 486 | ; |
487 | +; DETERMINING THE VERSION OF MPFIT | |
488 | +; | |
489 | +; MPFIT is a changing library. Users of MPFIT may also depend on a | |
490 | +; specific version of the library being present. As of version 1.70 | |
491 | +; of MPFIT, a VERSION keyword has been added which allows the user to | |
492 | +; query which version is present. The keyword works like this: | |
493 | +; | |
494 | +; RESULT = MPFIT(/query, VERSION=version) | |
495 | +; | |
496 | +; This call uses the /QUERY keyword to query the version number | |
497 | +; without performing any computations. Users of MPFIT can call this | |
498 | +; method to determine which version is in the IDL path before | |
499 | +; actually using MPFIT to do any numerical work. Upon return, the | |
500 | +; VERSION keyword contains the version number of MPFIT, expressed as | |
501 | +; a string of the form 'X.Y' where X and Y are integers. | |
502 | +; | |
503 | +; Users can perform their own version checking, or use the built-in | |
504 | +; error checking of MPFIT. The MIN_VERSION keyword enforces the | |
505 | +; requested minimum version number. For example, | |
506 | +; | |
507 | +; RESULT = MPFIT(/query, VERSION=version, MIN_VERSION='1.70') | |
508 | +; | |
509 | +; will check whether the accessed version is 1.70 or greater, without | |
510 | +; performing any numerical processing. | |
511 | +; | |
512 | +; The VERSION and MIN_VERSION keywords were added in MPFIT | |
513 | +; version 1.70 and later. If the caller attempts to use the VERSION | |
514 | +; or MIN_VERSION keywords, and an *older* version of the code is | |
515 | +; present in the caller's path, then IDL will throw an 'unknown | |
516 | +; keyword' error. Therefore, in order to be robust, the caller, must | |
517 | +; use exception handling. Here is an example demanding at least | |
518 | +; version 1.70. | |
519 | +; | |
520 | +; MPFIT_OK = 0 & VERSION = '<unknown>' | |
521 | +; CATCH, CATCHERR | |
522 | +; IF CATCHERR EQ 0 THEN MPFIT_OK = MPFIT(/query, VERSION=version, $ | |
523 | +; MIN_VERSION='1.70') | |
524 | +; CATCH, /CANCEL | |
525 | +; | |
526 | +; IF NOT MPFIT_OK THEN $ | |
527 | +; MESSAGE, 'ERROR: you must have MPFIT version 1.70 or higher in '+$ | |
528 | +; 'your path (found version '+version+')' | |
529 | +; | |
530 | +; Of course, the caller can also do its own version number | |
531 | +; requirements checking. | |
532 | +; | |
533 | +; | |
460 | 534 | ; HARD-TO-COMPUTE FUNCTIONS: "EXTERNAL" EVALUATION |
461 | 535 | ; |
462 | 536 | ; The normal mode of operation for MPFIT is for the user to pass a |
... | ... | @@ -525,6 +599,8 @@ |
525 | 599 | ; RETURNS: |
526 | 600 | ; |
527 | 601 | ; Returns the array of best-fit parameters. |
602 | +; Exceptions: | |
603 | +; * if /QUERY is set (see QUERY). | |
528 | 604 | ; |
529 | 605 | ; |
530 | 606 | ; KEYWORD PARAMETERS: |
... | ... | @@ -537,8 +613,31 @@ |
537 | 613 | ; NOTE: to supply your own explicit derivatives, |
538 | 614 | ; explicitly pass AUTODERIVATIVE=0 |
539 | 615 | ; |
540 | -; BESTNORM - the value of the summed squared weighted residuals for | |
541 | -; the returned parameter values, i.e. TOTAL(DEVIATES^2). | |
616 | +; BESTNORM - upon return, the value of the summed squared weighted | |
617 | +; residuals for the returned parameter values, | |
618 | +; i.e. TOTAL(DEVIATES^2). | |
619 | +; | |
620 | +; BEST_FJAC - upon return, BEST_FJAC contains the Jacobian, or | |
621 | +; partial derivative, matrix for the best-fit model. | |
622 | +; The values are an array, | |
623 | +; ARRAY(N_ELEMENTS(DEVIATES),NFREE) where NFREE is the | |
624 | +; number of free parameters. This array is only | |
625 | +; computed if /CALC_FJAC is set, otherwise BEST_FJAC is | |
626 | +; undefined. | |
627 | +; | |
628 | +; The returned array is such that BEST_FJAC[I,J] is the | |
629 | +; partial derivative of DEVIATES[I] with respect to | |
630 | +; parameter PARMS[PFREE_INDEX[J]]. Note that since | |
631 | +; deviates are (data-model)*weight, the Jacobian of the | |
632 | +; *deviates* will have the opposite sign from the | |
633 | +; Jacobian of the *model*, and may be scaled by a | |
634 | +; factor. | |
635 | +; | |
636 | +; BEST_RESID - upon return, an array of best-fit deviates. | |
637 | +; | |
638 | +; CALC_FJAC - if set, then calculate the Jacobian and return it in | |
639 | +; BEST_FJAC. If not set, then the return value of | |
640 | +; BEST_FJAC is undefined. | |
542 | 641 | ; |
543 | 642 | ; COVAR - the covariance matrix for the set of parameters returned |
544 | 643 | ; by MPFIT. The matrix is NxN where N is the number of |
... | ... | @@ -548,9 +647,11 @@ |
548 | 647 | ; Parameter errors are also returned in PERROR. |
549 | 648 | ; |
550 | 649 | ; To compute the correlation matrix, PCOR, use this example: |
551 | -; IDL> PCOR = COV * 0 | |
552 | -; IDL> FOR i = 0, n-1 DO FOR j = 0, n-1 DO $ | |
553 | -; PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j]) | |
650 | +; PCOR = COV * 0 | |
651 | +; FOR i = 0, n-1 DO FOR j = 0, n-1 DO $ | |
652 | +; PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j]) | |
653 | +; or equivalently, in vector notation, | |
654 | +; PCOR = COV / (PERROR # PERROR) | |
554 | 655 | ; |
555 | 656 | ; If NOCOVAR is set or MPFIT terminated abnormally, then |
556 | 657 | ; COVAR is set to a scalar with value !VALUES.D_NAN. |
... | ... | @@ -558,7 +659,8 @@ |
558 | 659 | ; DOF - number of degrees of freedom, computed as |
559 | 660 | ; DOF = N_ELEMENTS(DEVIATES) - NFREE |
560 | 661 | ; Note that this doesn't account for pegged parameters (see |
561 | -; NPEGGED). | |
662 | +; NPEGGED). It also does not account for data points which | |
663 | +; are assigned zero weight by the user function. | |
562 | 664 | ; |
563 | 665 | ; ERRMSG - a string error or warning message is returned. |
564 | 666 | ; |
... | ... | @@ -699,10 +801,24 @@ |
699 | 801 | ; change to a printable character like 'q'. |
700 | 802 | ; |
701 | 803 | ; MAXITER - The maximum number of iterations to perform. If the |
702 | -; number is exceeded, then the STATUS value is set to 5 | |
703 | -; and MPFIT returns. | |
804 | +; number of calculation iterations exceeds MAXITER, then | |
805 | +; the STATUS value is set to 5 and MPFIT returns. | |
806 | +; | |
807 | +; If MAXITER EQ 0, then MPFIT does not iterate to adjust | |
808 | +; parameter values; however, the user function is evaluated | |
809 | +; and parameter errors/covariance/Jacobian are estimated | |
810 | +; before returning. | |
704 | 811 | ; Default: 200 iterations |
705 | 812 | ; |
813 | +; MIN_VERSION - The minimum requested version number. This must be | |
814 | +; a scalar string of the form returned by the VERSION | |
815 | +; keyword. If the current version of MPFIT does not | |
816 | +; satisfy the minimum requested version number, then, | |
817 | +; MPFIT(/query, min_version='...') returns 0 | |
818 | +; MPFIT(...) returns NAN | |
819 | +; Default: no version number check | |
820 | +; NOTE: MIN_VERSION was added in MPFIT version 1.70 | |
821 | +; | |
706 | 822 | ; NFEV - the number of MYFUNCT function evaluations performed. |
707 | 823 | ; |
708 | 824 | ; NFREE - the number of free parameters in the fit. This includes |
... | ... | @@ -761,6 +877,19 @@ |
761 | 877 | ; DOF = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom |
762 | 878 | ; PCERROR = PERROR * SQRT(BESTNORM / DOF) ; scaled uncertainties |
763 | 879 | ; |
880 | +; PFREE_INDEX - upon return, PFREE_INDEX contains an index array | |
881 | +; which indicates which parameter were allowed to | |
882 | +; vary. I.e. of all the parameters PARMS, only | |
883 | +; PARMS[PFREE_INDEX] were varied. | |
884 | +; | |
885 | +; QUERY - if set, then MPFIT() will return immediately with one of | |
886 | +; the following values: | |
887 | +; 1 - if MIN_VERSION is not set | |
888 | +; 1 - if MIN_VERSION is set and MPFIT satisfies the minimum | |
889 | +; 0 - if MIN_VERSION is set and MPFIT does not satisfy it | |
890 | +; The VERSION output keyword is always set upon return. | |
891 | +; Default: not set. | |
892 | +; | |
764 | 893 | ; QUIET - set this keyword when no textual output should be printed |
765 | 894 | ; by MPFIT |
766 | 895 | ; |
... | ... | @@ -827,6 +956,14 @@ |
827 | 956 | ; the function and its derivatives. This status indicator |
828 | 957 | ; is neither an error nor a convergence indicator. |
829 | 958 | ; |
959 | +; VERSION - upon return, VERSION will be set to the MPFIT internal | |
960 | +; version number. The version number will be a string of | |
961 | +; the form "X.Y" where X is a major revision number and Y | |
962 | +; is a minor revision number. | |
963 | +; NOTE: the VERSION keyword was not present before | |
964 | +; MPFIT version number 1.70, therefore, callers must | |
965 | +; use exception handling when using this keyword. | |
966 | +; | |
830 | 967 | ; XTOL - a nonnegative input variable. Termination occurs when the |
831 | 968 | ; relative error between two consecutive iterates is at most |
832 | 969 | ; XTOL (and STATUS is accordingly set to 2 or 3). Therefore, |
... | ... | @@ -965,18 +1102,24 @@ |
965 | 1102 | ; with MPFIT," in proc. Astronomical Data Analysis Software and |
966 | 1103 | ; Systems XVIII, Quebec, Canada, ASP Conference Series, Vol. XXX, eds. |
967 | 1104 | ; D. Bohlender, P. Dowler & D. Durand (Astronomical Society of the |
968 | -; Pacific: San Francisco), p. XXX | |
969 | -; http://arxiv.org/XXXXX | |
1105 | +; Pacific: San Francisco), p. 251-254 (ISBN: 978-1-58381-702-5) | |
1106 | +; http://arxiv.org/abs/0902.2850 | |
1107 | +; Link to NASA ADS: http://adsabs.harvard.edu/abs/2009ASPC..411..251M | |
1108 | +; Link to ASP: http://aspbooks.org/a/volumes/table_of_contents/411 | |
1109 | +; | |
1110 | +; Refer to the MPFIT website as: | |
1111 | +; http://purl.com/net/mpfit | |
970 | 1112 | ; |
971 | -; MINPACK-1, Jorge More', available from netlib. | |
1113 | +; MINPACK-1 software, by Jorge More' et al, available from netlib. | |
972 | 1114 | ; http://www.netlib.org/ |
973 | 1115 | ; |
974 | 1116 | ; "Optimization Software Guide," Jorge More' and Stephen Wright, |
975 | 1117 | ; SIAM, *Frontiers in Applied Mathematics*, Number 14. |
1118 | +; (ISBN: 978-0-898713-22-0) | |
976 | 1119 | ; |
977 | -; More', J. 1977, ``The Levenberg-Marquardt Algorithm: | |
978 | -; Implementation and Theory,'' in *Numerical Analysis*, | |
979 | -; vol. 630, ed. G. A. Watson (Springer-Verlag: Berlin), 105 | |
1120 | +; More', J. 1978, "The Levenberg-Marquardt Algorithm: Implementation | |
1121 | +; and Theory," in Numerical Analysis, vol. 630, ed. G. A. Watson | |
1122 | +; (Springer-Verlag: Berlin), p. 105 (DOI: 10.1007/BFb0067690 ) | |
980 | 1123 | ; |
981 | 1124 | ; MODIFICATION HISTORY: |
982 | 1125 | ; Translated from MINPACK-1 in FORTRAN, Apr-Jul 1998, CM |
... | ... | @@ -1141,12 +1284,33 @@ |
1141 | 1284 | ; the covariance matrix to be computed, CM, 14 Apr 2009 |
1142 | 1285 | ; Avoid numerical underflow while solving for the LM parameter, |
1143 | 1286 | ; (thanks to Sergey Koposov) CM, 14 Apr 2009 |
1144 | -; | |
1145 | -; $Id: mpfit.pro,v 1.64 2009/05/05 05:37:49 craigm Exp $ | |
1287 | +; Use individual functions for all possible MPFIT_CALL permutations, | |
1288 | +; (and make sure the syntax is right) CM, 01 Sep 2009 | |
1289 | +; Correct behavior of MPMAXSTEP when some parameters are frozen, | |
1290 | +; thanks to Josh Destree, CM, 22 Nov 2009 | |
1291 | +; Update the references section, CM, 22 Nov 2009 | |
1292 | +; 1.70 - Add the VERSION and MIN_VERSION keywords, CM, 22 Nov 2009 | |
1293 | +; 1.71 - Store pre-calculated revision in common, CM, 23 Nov 2009 | |
1294 | +; 1.72-1.74 - Documented alternate method to compute correlation matrix, | |
1295 | +; CM, 05 Feb 2010 | |
1296 | +; 1.75 - Enforce TIED constraints when preparing to terminate the | |
1297 | +; routine, CM, 2010-06-22 | |
1298 | +; 1.76 - Documented input keywords now are not modified upon output, | |
1299 | +; CM, 2010-07-13 | |
1300 | +; 1.77 - Upon user request (/CALC_FJAC), compute Jacobian matrix and | |
1301 | +; return in BEST_FJAC; also return best residuals in | |
1302 | +; BEST_RESID; also return an index list of free parameters as | |
1303 | +; PFREE_INDEX; add a fencepost to prevent recursion | |
1304 | +; CM, 2010-10-27 | |
1305 | +; 1.79 - Documentation corrections. CM, 2011-08-26 | |
1306 | +; 1.81 - Fix bug in interaction of AUTODERIVATIVE=0 and .MPSIDE=3; | |
1307 | +; Document FJAC_MASK. CM, 2012-05-08 | |
1308 | +; | |
1309 | +; $Id: mpfit.pro,v 1.82 2012/09/27 23:59:44 cmarkwar Exp $ | |
1146 | 1310 | ;- |
1147 | 1311 | ; Original MINPACK by More' Garbow and Hillstrom, translated with permission |
1148 | 1312 | ; Modifications and enhancements are: |
1149 | -; Copyright (C) 1997-2003, 2004, 2005, 2006, 2007, 2008, 2009, Craig Markwardt | |
1313 | +; Copyright (C) 1997-2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012 Craig Markwardt | |
1150 | 1314 | ; This software is provided as is without any warranty whatsoever. |
1151 | 1315 | ; Permission to use, copy, modify, and distribute modified or |
1152 | 1316 | ; unmodified copies is granted, provided this copyright and disclaimer |
... | ... | @@ -1215,6 +1379,44 @@ pro mpfit_setmachar, double=isdouble |
1215 | 1379 | end |
1216 | 1380 | |
1217 | 1381 | |
1382 | +; Call user function with no _EXTRA parameters | |
1383 | +function mpfit_call_func_noextra, fcn, x, fjac, _EXTRA=extra | |
1384 | + if n_params() EQ 2 then begin | |
1385 | + return, call_function(fcn, x) | |
1386 | + endif else begin | |
1387 | + return, call_function(fcn, x, fjac) | |
1388 | + endelse | |
1389 | +end | |
1390 | + | |
1391 | +; Call user function with _EXTRA parameters | |
1392 | +function mpfit_call_func_extra, fcn, x, fjac, _EXTRA=extra | |
1393 | + if n_params() EQ 2 then begin | |
1394 | + return, call_function(fcn, x, _EXTRA=extra) | |
1395 | + endif else begin | |
1396 | + return, call_function(fcn, x, fjac, _EXTRA=extra) | |
1397 | + endelse | |
1398 | +end | |
1399 | + | |
1400 | +; Call user procedure with no _EXTRA parameters | |
1401 | +function mpfit_call_pro_noextra, fcn, x, fjac, _EXTRA=extra | |
1402 | + if n_params() EQ 2 then begin | |
1403 | + call_procedure, fcn, x, f | |
1404 | + endif else begin | |
1405 | + call_procedure, fcn, x, f, fjac | |
1406 | + endelse | |
1407 | + return, f | |
1408 | +end | |
1409 | + | |
1410 | +; Call user procedure with _EXTRA parameters | |
1411 | +function mpfit_call_pro_extra, fcn, x, fjac, _EXTRA=extra | |
1412 | + if n_params() EQ 2 then begin | |
1413 | + call_procedure, fcn, x, f, _EXTRA=extra | |
1414 | + endif else begin | |
1415 | + call_procedure, fcn, x, f, fjac, _EXTRA=extra | |
1416 | + endelse | |
1417 | + return, f | |
1418 | +end | |
1419 | + | |
1218 | 1420 | |
1219 | 1421 | ;; Call user function or procedure, with _EXTRA or not, with |
1220 | 1422 | ;; derivatives or not. |
... | ... | @@ -1224,36 +1426,19 @@ function mpfit_call, fcn, x, fjac, _EXTRA=extra |
1224 | 1426 | common mpfit_config, mpconfig |
1225 | 1427 | |
1226 | 1428 | if keyword_set(mpconfig.qanytied) then mpfit_tie, x, mpconfig.ptied |
1227 | - | |
1228 | - ;; Decide whether we are calling a procedure or function | |
1229 | - if mpconfig.proc then proc = 1 else proc = 0 | |
1230 | - mpconfig.nfev = mpconfig.nfev + 1 | |
1231 | 1429 | |
1232 | - if proc then begin | |
1233 | - if n_params() EQ 3 then begin | |
1234 | - if n_elements(extra) GT 0 then $ | |
1235 | - call_procedure, fcn, x, f, fjac, _EXTRA=extra $ | |
1236 | - else $ | |
1237 | - call_procedure, fcn, x, f, fjac | |
1238 | - endif else begin | |
1239 | - if n_elements(extra) GT 0 then $ | |
1240 | - call_procedure, fcn, x, f, _EXTRA=extra $ | |
1241 | - else $ | |
1242 | - call_procedure, fcn, x, f | |
1243 | - endelse | |
1430 | + ;; Decide whether we are calling a procedure or function, and | |
1431 | + ;; with/without FUNCTARGS | |
1432 | + proname = 'MPFIT_CALL' | |
1433 | + proname = proname + ((mpconfig.proc) ? '_PRO' : '_FUNC') | |
1434 | + proname = proname + ((n_elements(extra) GT 0) ? '_EXTRA' : '_NOEXTRA') | |
1435 | + | |
1436 | + if n_params() EQ 2 then begin | |
1437 | + f = call_function(proname, fcn, x, _EXTRA=extra) | |
1244 | 1438 | endif else begin |
1245 | - if n_params() EQ 3 then begin | |
1246 | - if n_elements(extra) GT 0 then $ | |
1247 | - f = call_function(fcn, x, fjac, _EXTRA=extra) $ | |
1248 | - else $ | |
1249 | - f = call_function(fcn, x, fjac) | |
1250 | - endif else begin | |
1251 | - if n_elements(extra) GT 0 then $ | |
1252 | - f = call_function(fcn, x, _EXTRA=extra) $ | |
1253 | - else $ | |
1254 | - f = call_function(fcn, x) | |
1255 | - endelse | |
1256 | - endelse | |
1439 | + f = call_function(proname, fcn, x, fjac, _EXTRA=extra) | |
1440 | + endelse | |
1441 | + mpconfig.nfev = mpconfig.nfev + 1 | |
1257 | 1442 | |
1258 | 1443 | if n_params() EQ 2 AND mpconfig.damp GT 0 then begin |
1259 | 1444 | damp = mpconfig.damp[0] |
... | ... | @@ -1309,12 +1494,14 @@ function mpfit_fdjac2, fcn, x, fvec, step, ulimited, ulimit, dside, $ |
1309 | 1494 | ;; 2. AUTODERIVATIVE=1, but P[i].MPSIDE EQ 3 |
1310 | 1495 | |
1311 | 1496 | if keyword_set(autoderiv) EQ 0 OR max(dside[ifree] EQ 3) EQ 1 then begin |
1312 | - fjac = intarr(nall) | |
1497 | + fjac_mask = intarr(nall) | |
1313 | 1498 | ;; Specify which parameters need derivatives |
1314 | - ;; ---- Case 2 ------ ----- Case 1 ----- | |
1315 | - fjac[ifree] = (dside[ifree] EQ 3) OR (keyword_set(autoderiv) EQ 0) | |
1316 | - if has_debug_deriv then print, fjac, format='("# FJAC_MASK = ",100000(I0," ",:))' | |
1499 | + ;; ---- Case 2 ------ ----- Case 1 ----- | |
1500 | + fjac_mask[ifree] = (dside[ifree] EQ 3) OR (keyword_set(autoderiv) EQ 0) | |
1501 | + if has_debug_deriv then $ | |
1502 | + print, fjac_mask, format='("# FJAC_MASK = ",100000(I0," ",:))' | |
1317 | 1503 | |
1504 | + fjac = fjac_mask ;; Pass the mask to the calling function as FJAC | |
1318 | 1505 | mperr = 0 |
1319 | 1506 | fp = mpfit_call(fcn, xall, fjac, _EXTRA=fcnargs) |
1320 | 1507 | iflag = mperr |
... | ... | @@ -1340,12 +1527,13 @@ function mpfit_fdjac2, fcn, x, fvec, step, ulimited, ulimit, dside, $ |
1340 | 1527 | ;; Select only the free parameters |
1341 | 1528 | if n_elements(ifree) LT nall then $ |
1342 | 1529 | fjac = reform(fjac[*,ifree], m, n, /overwrite) |
1343 | - | |
1344 | - ;; If there are no more free parameters to analyze, then | |
1345 | - ;; return now, (but not if we are debugging the derivatives) | |
1346 | - if ((keyword_set(autoderiv) EQ 0) OR $ | |
1347 | - (min(dside[ifree]) EQ 1) OR $ | |
1348 | - (has_debug_deriv EQ 0)) then return, fjac | |
1530 | + | |
1531 | + ;; Are we done computing derivatives? The answer is, YES, if we | |
1532 | + ;; computed explicit derivatives for all free parameters, EXCEPT | |
1533 | + ;; when we are going on to compute debugging derivatives. | |
1534 | + if min(fjac_mask[ifree]) EQ 1 AND NOT has_debug_deriv then begin | |
1535 | + return, fjac | |
1536 | + endif | |
1349 | 1537 | endif |
1350 | 1538 | |
1351 | 1539 | ;; Final output array, if it was not already created above |
... | ... | @@ -2174,7 +2362,7 @@ pro mpfit_defiter, fcn, x, iter, fnorm, FUNCTARGS=fcnargs, $ |
2174 | 2362 | if n_elements(fmt) GT 0 then begin |
2175 | 2363 | call_procedure, iterprint, x, format=fmt, _EXTRA=iterargs |
2176 | 2364 | endif else begin |
2177 | - if n_elements(pformat) EQ 0 then pformat = '(G20.6)' | |
2365 | + if n_elements(pformat) EQ 0 then pformat = '(G40.6)' | |
2178 | 2366 | parname = 'P('+strtrim(iprint,2)+')' |
2179 | 2367 | pformats = strarr(nprint) + pformat |
2180 | 2368 | |
... | ... | @@ -2398,6 +2586,45 @@ function mpfit_covar, rr, ipvt, tol=tol |
2398 | 2586 | return, r |
2399 | 2587 | end |
2400 | 2588 | |
2589 | +;; Parse the RCSID revision number | |
2590 | +function mpfit_revision | |
2591 | + ;; NOTE: this string is changed every time an RCS check-in occurs | |
2592 | + revision = '$Revision: 1.82 $' | |
2593 | + | |
2594 | + ;; Parse just the version number portion | |
2595 | + revision = stregex(revision,'\$'+'Revision: *([0-9.]+) *'+'\$',/extract,/sub) | |
2596 | + revision = revision[1] | |
2597 | + return, revision | |
2598 | +end | |
2599 | + | |
2600 | +;; Parse version numbers of the form 'X.Y' | |
2601 | +function mpfit_parse_version, version | |
2602 | + sz = size(version) | |
2603 | + if sz[sz[0]+1] NE 7 then return, 0 | |
2604 | + | |
2605 | + s = stregex(version[0], '^([0-9]+)\.([0-9]+)$', /extract,/sub) | |
2606 | + if s[0] NE version[0] then return, 0 | |
2607 | + return, long(s[1:2]) | |
2608 | +end | |
2609 | + | |
2610 | +;; Enforce a minimum version number | |
2611 | +function mpfit_min_version, version, min_version | |
2612 | + mv = mpfit_parse_version(min_version) | |
2613 | + if mv[0] EQ 0 then return, 0 | |
2614 | + v = mpfit_parse_version(version) | |
2615 | + | |
2616 | + ;; Compare version components | |
2617 | + if v[0] LT mv[0] then return, 0 | |
2618 | + if v[1] LT mv[1] then return, 0 | |
2619 | + return, 1 | |
2620 | +end | |
2621 | + | |
2622 | +; Manually reset recursion fencepost if the user gets in trouble | |
2623 | +pro mpfit_reset_recursion | |
2624 | + common mpfit_fencepost, mpfit_fencepost_active | |
2625 | + mpfit_fencepost_active = 0 | |
2626 | +end | |
2627 | + | |
2401 | 2628 | ; ********** |
2402 | 2629 | ; |
2403 | 2630 | ; subroutine lmdif |
... | ... | @@ -2579,24 +2806,48 @@ end |
2579 | 2806 | ; |
2580 | 2807 | ; ********** |
2581 | 2808 | function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2582 | - ftol=ftol, xtol=xtol, gtol=gtol, epsfcn=epsfcn, resdamp=damp, $ | |
2809 | + ftol=ftol0, xtol=xtol0, gtol=gtol0, epsfcn=epsfcn, $ | |
2810 | + resdamp=damp0, $ | |
2583 | 2811 | nfev=nfev, maxiter=maxiter, errmsg=errmsg, $ |
2584 | - factor=factor, nprint=nprint, STATUS=info, $ | |
2585 | - iterproc=iterproc, iterargs=iterargs, iterstop=ss,$ | |
2812 | + factor=factor0, nprint=nprint0, STATUS=info, $ | |
2813 | + iterproc=iterproc0, iterargs=iterargs, iterstop=ss,$ | |
2586 | 2814 | iterkeystop=iterkeystop, $ |
2587 | 2815 | niter=iter, nfree=nfree, npegged=npegged, dof=dof, $ |
2588 | - diag=diag, rescale=rescale, autoderivative=autoderiv, $ | |
2589 | - perror=perror, covar=covar, nocovar=nocovar, bestnorm=fnorm, $ | |
2816 | + diag=diag, rescale=rescale, autoderivative=autoderiv0, $ | |
2817 | + pfree_index=ifree, $ | |
2818 | + perror=perror, covar=covar, nocovar=nocovar, $ | |
2819 | + bestnorm=fnorm, best_resid=fvec, $ | |
2820 | + best_fjac=output_fjac, calc_fjac=calc_fjac, $ | |
2590 | 2821 | parinfo=parinfo, quiet=quiet, nocatch=nocatch, $ |
2591 | - fastnorm=fastnorm, proc=proc, query=query, $ | |
2822 | + fastnorm=fastnorm0, proc=proc, query=query, $ | |
2592 | 2823 | external_state=state, external_init=extinit, $ |
2593 | - external_fvec=efvec, external_fjac=efjac | |
2594 | - | |
2824 | + external_fvec=efvec, external_fjac=efjac, $ | |
2825 | + version=version, min_version=min_version0 | |
2826 | + | |
2827 | + | |
2595 | 2828 | COMPILE_OPT strictarr |
2596 | 2829 | info = 0L |
2597 | 2830 | errmsg = '' |
2598 | 2831 | |
2599 | - if keyword_set(query) then return, 1 | |
2832 | + ;; Compute the revision number, to be returned in the VERSION and | |
2833 | + ;; QUERY keywords. | |
2834 | + common mpfit_revision_common, mpfit_revision_str | |
2835 | + if n_elements(mpfit_revision_str) EQ 0 then $ | |
2836 | + mpfit_revision_str = mpfit_revision() | |
2837 | + version = mpfit_revision_str | |
2838 | + | |
2839 | + if keyword_set(query) then begin | |
2840 | + if n_elements(min_version0) GT 0 then $ | |
2841 | + if mpfit_min_version(version, min_version0[0]) EQ 0 then $ | |
2842 | + return, 0 | |
2843 | + return, 1 | |
2844 | + endif | |
2845 | + | |
2846 | + if n_elements(min_version0) GT 0 then $ | |
2847 | + if mpfit_min_version(version, min_version0[0]) EQ 0 then begin | |
2848 | + message, 'ERROR: minimum required version '+min_version0[0]+' not satisfied', /info | |
2849 | + return, !values.d_nan | |
2850 | + endif | |
2600 | 2851 | |
2601 | 2852 | if n_params() EQ 0 then begin |
2602 | 2853 | message, "USAGE: PARMS = MPFIT('MYFUNCT', START_PARAMS, ... )", /info |
... | ... | @@ -2605,15 +2856,15 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2605 | 2856 | |
2606 | 2857 | ;; Use of double here not a problem since f/x/gtol are all only used |
2607 | 2858 | ;; in comparisons |
2608 | - if n_elements(ftol) EQ 0 then ftol = 1.D-10 | |
2609 | - if n_elements(xtol) EQ 0 then xtol = 1.D-10 | |
2610 | - if n_elements(gtol) EQ 0 then gtol = 1.D-10 | |
2611 | - if n_elements(factor) EQ 0 then factor = 100. | |
2612 | - if n_elements(nprint) EQ 0 then nprint = 1 | |
2613 | - if n_elements(iterproc) EQ 0 then iterproc = 'MPFIT_DEFITER' | |
2614 | - if n_elements(autoderiv) EQ 0 then autoderiv = 1 | |
2615 | - if n_elements(fastnorm) EQ 0 then fastnorm = 0 | |
2616 | - if n_elements(damp) EQ 0 then damp = 0 else damp = damp[0] | |
2859 | + if n_elements(ftol0) EQ 0 then ftol = 1.D-10 else ftol = ftol0[0] | |
2860 | + if n_elements(xtol0) EQ 0 then xtol = 1.D-10 else xtol = xtol0[0] | |
2861 | + if n_elements(gtol0) EQ 0 then gtol = 1.D-10 else gtol = gtol0[0] | |
2862 | + if n_elements(factor0) EQ 0 then factor = 100. else factor = factor0[0] | |
2863 | + if n_elements(nprint0) EQ 0 then nprint = 1 else nprint = nprint0[0] | |
2864 | + if n_elements(iterproc0) EQ 0 then iterproc = 'MPFIT_DEFITER' else iterproc = iterproc0[0] | |
2865 | + if n_elements(autoderiv0) EQ 0 then autoderiv = 1 else autoderiv = autoderiv0[0] | |
2866 | + if n_elements(fastnorm0) EQ 0 then fastnorm = 0 else fastnorm = fastnorm0[0] | |
2867 | + if n_elements(damp0) EQ 0 then damp = 0 else damp = damp0[0] | |
2617 | 2868 | |
2618 | 2869 | ;; These are special configuration parameters that can't be easily |
2619 | 2870 | ;; passed by MPFIT directly. |
... | ... | @@ -2631,6 +2882,18 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2631 | 2882 | nfree = 0L |
2632 | 2883 | npegged = 0L |
2633 | 2884 | dof = 0L |
2885 | + output_fjac = 0L | |
2886 | + | |
2887 | + ;; Set up a persistent fencepost that prevents recursive calls | |
2888 | + common mpfit_fencepost, mpfit_fencepost_active | |
2889 | + if n_elements(mpfit_fencepost_active) EQ 0 then mpfit_fencepost_active = 0 | |
2890 | + if mpfit_fencepost_active then begin | |
2891 | + errmsg = 'ERROR: recursion detected; you cannot run MPFIT recursively' | |
2892 | + goto, TERMINATE | |
2893 | + endif | |
2894 | + ;; Only activate the fencepost if we are not in debugging mode | |
2895 | + if NOT keyword_set(nocatch) then mpfit_fencepost_active = 1 | |
2896 | + | |
2634 | 2897 | |
2635 | 2898 | ;; Parameter damping doesn't work when user is providing their own |
2636 | 2899 | ;; gradients. |
... | ... | @@ -2669,8 +2932,9 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2669 | 2932 | ;; Handle error conditions gracefully |
2670 | 2933 | if NOT keyword_set(nocatch) then begin |
2671 | 2934 | catch, catcherror |
2672 | - if catcherror NE 0 then begin | |
2935 | + if catcherror NE 0 then begin ;; An error occurred!!! | |
2673 | 2936 | catch, /cancel |
2937 | + mpfit_fencepost_active = 0 | |
2674 | 2938 | err_string = ''+!error_state.msg |
2675 | 2939 | message, /cont, 'Error detected while '+catch_msg+':' |
2676 | 2940 | message, /cont, err_string |
... | ... | @@ -2795,8 +3059,6 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2795 | 3059 | errmsg = 'ERROR: MPMINSTEP is greater than MPMAXSTEP' |
2796 | 3060 | goto, TERMINATE |
2797 | 3061 | endif |
2798 | - wh = where(qmin OR qmax, ct) | |
2799 | - qminmax = ct GT 0 | |
2800 | 3062 | |
2801 | 3063 | ;; Finish up the free parameters |
2802 | 3064 | ifree = where(pfixed NE 1, nfree) |
... | ... | @@ -2819,6 +3081,12 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
2819 | 3081 | ;; Compose only VARYING parameters |
2820 | 3082 | xnew = xall ;; xnew is the set of parameters to be returned |
2821 | 3083 | x = xnew[ifree] ;; x is the set of free parameters |
3084 | + ; Same for min/max step diagnostics | |
3085 | + qmin = qmin[ifree] & minstep = minstep[ifree] | |
3086 | + qmax = qmax[ifree] & maxstep = maxstep[ifree] | |
3087 | + wh = where(qmin OR qmax, ct) | |
3088 | + qminmax = ct GT 0 | |
3089 | + | |
2822 | 3090 | |
2823 | 3091 | ;; LIMITED parameters ? |
2824 | 3092 | mpfit_parinfo, parinfo, tagnames, 'LIMITED', limited, status=st1 |
... | ... | @@ -3012,6 +3280,8 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
3012 | 3280 | iflag = 2 |
3013 | 3281 | if NOT isext then begin |
3014 | 3282 | catch_msg = 'calling MPFIT_FDJAC2' |
3283 | + ;; NOTE! If you change this call then change the one during | |
3284 | + ;; clean-up as well! | |
3015 | 3285 | fjac = mpfit_fdjac2(fcn, x, fvec, step, qulim, ulim, dside, $ |
3016 | 3286 | iflag=iflag, epsfcn=epsfcn, $ |
3017 | 3287 | autoderiv=autoderiv, dstep=dstep, $ |
... | ... | @@ -3043,6 +3313,7 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
3043 | 3313 | ;; See if any "pegged" values should keep their derivatives |
3044 | 3314 | if (nlpeg GT 0) then begin |
3045 | 3315 | ;; Total derivative of sum wrt lower pegged parameters |
3316 | + ;; Note: total(fvec*fjac[*,i]) is d(CHI^2)/dX[i] | |
3046 | 3317 | for i = 0L, nlpeg-1 do begin |
3047 | 3318 | sum = total(fvec * fjac[*,whlpeg[i]]) |
3048 | 3319 | if sum GT 0 then fjac[*,whlpeg[i]] = 0 |
... | ... | @@ -3057,24 +3328,42 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
3057 | 3328 | endif |
3058 | 3329 | endif |
3059 | 3330 | |
3331 | + ;; Save a copy of the Jacobian if the user requests it... | |
3332 | + if keyword_set(calc_fjac) then output_fjac = fjac | |
3333 | + | |
3334 | + ;; ===================== | |
3060 | 3335 | ;; Compute the QR factorization of the jacobian |
3061 | 3336 | catch_msg = 'calling MPFIT_QRFAC' |
3062 | - mpfit_qrfac, fjac, ipvt, wa1, wa2, /pivot | |
3063 | - | |
3337 | + ;; IN: Jacobian | |
3338 | + ;; OUT: Hh Vects Permutation RDIAG ACNORM | |
3339 | + mpfit_qrfac, fjac, ipvt, wa1, wa2, /pivot | |
3340 | + ;; Jacobian - jacobian matrix computed by mpfit_fdjac2 | |
3341 | + ;; Hh vects - house holder vectors from QR factorization & R matrix | |
3342 | + ;; Permutation - permutation vector for pivoting | |
3343 | + ;; RDIAG - diagonal elements of R matrix | |
3344 | + ;; ACNORM - norms of input Jacobian matrix before factoring | |
3345 | + | |
3346 | + ;; ===================== | |
3064 | 3347 | ;; On the first iteration if "diag" is unspecified, scale |
3065 | 3348 | ;; according to the norms of the columns of the initial jacobian |
3066 | 3349 | catch_msg = 'rescaling diagonal elements' |
3067 | 3350 | if (iter EQ 1) then begin |
3351 | + ;; Input: WA2 = root sum of squares of original Jacobian matrix | |
3352 | + ;; DIAG = user-requested diagonal (not documented!) | |
3353 | + ;; FACTOR = user-requested norm factor (not documented!) | |
3354 | + ;; Output: DIAG = Diagonal scaling values | |
3355 | + ;; XNORM = sum of squared scaled residuals | |
3356 | + ;; DELTA = rescaled XNORM | |
3068 | 3357 | |
3069 | 3358 | if NOT keyword_set(rescale) OR (n_elements(diag) LT n) then begin |
3070 | - diag = wa2 | |
3071 | - wh = where (diag EQ 0, ct) | |
3359 | + diag = wa2 ;; Calculated from original Jacobian | |
3360 | + wh = where (diag EQ 0, ct) ;; Handle zero values | |
3072 | 3361 | if ct GT 0 then diag[wh] = one |
3073 | 3362 | endif |
3074 | 3363 | |
3075 | 3364 | ;; On the first iteration, calculate the norm of the scaled x |
3076 | 3365 | ;; and initialize the step bound delta |
3077 | - wa3 = diag * x | |
3366 | + wa3 = diag * x ;; WA3 is temp variable | |
3078 | 3367 | xnorm = mpfit_enorm(wa3) |
3079 | 3368 | delta = factor*xnorm |
3080 | 3369 | if delta EQ zero then delta = zero + factor |
... | ... | @@ -3176,7 +3465,7 @@ function mpfit, fcn, xall, FUNCTARGS=fcnargs, SCALE_FCN=scalfcn, $ |
3176 | 3465 | nwa1 = wa1 * alpha |
3177 | 3466 | whmax = where(qmax AND maxstep GT 0, ct) |
3178 | 3467 | if ct GT 0 then begin |
3179 | - mrat = max(abs(nwa1[whmax])/abs(maxstep[ifree[whmax]])) | |
3468 | + mrat = max(abs(nwa1[whmax])/abs(maxstep[whmax])) | |
3180 | 3469 | if mrat GT 1 then alpha = alpha / mrat |
3181 | 3470 | endif |
3182 | 3471 | endif |
... | ... | @@ -3316,6 +3605,7 @@ TERMINATE: |
3316 | 3605 | iflag = 0 |
3317 | 3606 | if n_elements(xnew) EQ 0 then goto, FINAL_RETURN |
3318 | 3607 | if nfree EQ 0 then xnew = xall else xnew[ifree] = x |
3608 | + if n_elements(qanytied) GT 0 then if qanytied then mpfit_tie, xnew, ptied | |
3319 | 3609 | dof = n_elements(fvec) - nfree |
3320 | 3610 | |
3321 | 3611 | |
... | ... | @@ -3350,7 +3640,8 @@ TERMINATE: |
3350 | 3640 | (qllim AND (x EQ llim)), npegged) |
3351 | 3641 | endif |
3352 | 3642 | |
3353 | - if fcn NE '(EXTERNAL)' AND nprint GT 0 AND info GT 0 then begin | |
3643 | + ;; Calculate final function value (FNORM) and residuals (FVEC) | |
3644 | + if isext EQ 0 AND nprint GT 0 AND info GT 0 then begin | |
3354 | 3645 | catch_msg = 'calling '+fcn |
3355 | 3646 | fvec = mpfit_call(fcn, xnew, _EXTRA=fcnargs) |
3356 | 3647 | catch_msg = 'in the termination phase' |
... | ... | @@ -3394,10 +3685,12 @@ TERMINATE: |
3394 | 3685 | perror[wh] = sqrt(covar[wh, wh]) |
3395 | 3686 | endif |
3396 | 3687 | endif |
3688 | + | |
3397 | 3689 | ; catch_msg = 'returning the result' |
3398 | 3690 | ; profvals.mpfit = profvals.mpfit + (systime(1) - prof_start) |
3399 | 3691 | |
3400 | 3692 | FINAL_RETURN: |
3693 | + mpfit_fencepost_active = 0 | |
3401 | 3694 | nfev = mpconfig.nfev |
3402 | 3695 | if n_elements(xnew) EQ 0 then return, !values.d_nan |
3403 | 3696 | return, xnew | ... | ... |
src/idl/mpfitfun.pro
... | ... | @@ -73,12 +73,61 @@ |
73 | 73 | ; using the ERROR_CODE common block variable, as described |
74 | 74 | ; below under the MPFIT_ERROR common block definition. |
75 | 75 | ; |
76 | -; See the discussion under "EXPLICIT DERIVATIVES" and AUTODERIVATIVE | |
77 | -; in MPFIT.PRO if you wish to compute the derivatives for yourself. | |
78 | -; AUTODERIVATIVE is accepted by MPFITFUN and passed directly to | |
79 | -; MPFIT. The user function must accept one additional parameter, DP, | |
80 | -; which contains the derivative of the user function with respect to | |
81 | -; each parameter at each data point, as described in MPFIT.PRO. | |
76 | +; MPFIT by default calculates derivatives numerically via a finite | |
77 | +; difference approximation. However, the user function *may* | |
78 | +; calculate the derivatives if desired, but only if the model | |
79 | +; function is declared with an additional position parameter, DP, as | |
80 | +; described below. | |
81 | +; | |
82 | +; To enable explicit derivatives for all parameters, set | |
83 | +; AUTODERIVATIVE=0. | |
84 | +; | |
85 | +; When AUTODERIVATIVE=0, the user function is responsible for | |
86 | +; calculating the derivatives of the user function with respect to | |
87 | +; each parameter. The user function should be declared as follows: | |
88 | +; | |
89 | +; ; | |
90 | +; ; MYFUNCT - example user function | |
91 | +; ; P - input parameter values (N-element array) | |
92 | +; ; DP - upon input, an N-vector indicating which parameters | |
93 | +; ; to compute derivatives for; | |
94 | +; ; upon output, the user function must return | |
95 | +; ; an ARRAY(M,N) of derivatives in this keyword | |
96 | +; ; (keywords) - any other keywords specified by FUNCTARGS | |
97 | +; ; RETURNS - function values | |
98 | +; ; | |
99 | +; FUNCTION MYFUNCT, x, p, dp [, (additional keywords if desired)] | |
100 | +; model = F(x, p) ;; Model function | |
101 | +; | |
102 | +; if n_params() GT 2 then begin | |
103 | +; ; Create derivative and compute derivative array | |
104 | +; requested = dp ; Save original value of DP | |
105 | +; dp = make_array(n_elements(x), n_elements(p), value=x[0]*0) | |
106 | +; | |
107 | +; ; Compute derivative if requested by caller | |
108 | +; for i = 0, n_elements(p)-1 do if requested(i) NE 0 then $ | |
109 | +; dp(*,i) = FGRAD(x, p, i) | |
110 | +; endif | |
111 | +; | |
112 | +; return, resid | |
113 | +; END | |
114 | +; | |
115 | +; where FGRAD(x, p, i) is a model function which computes the | |
116 | +; derivative of the model F(x,p) with respect to parameter P(i) at X. | |
117 | +; | |
118 | +; Derivatives should be returned in the DP array. DP should be an | |
119 | +; ARRAY(m,n) array, where m is the number of data points and n is the | |
120 | +; number of parameters. DP[i,j] is the derivative of the ith | |
121 | +; function value with respect to the jth parameter. | |
122 | +; | |
123 | +; MPFIT may not always request derivatives from the user function. | |
124 | +; In those cases, the parameter DP is not passed. Therefore | |
125 | +; functions can use N_PARAMS() to indicate whether they must compute | |
126 | +; the derivatives or not. | |
127 | +; | |
128 | +; For additional information about explicit derivatives, including | |
129 | +; additional settings and debugging options, see the discussion under | |
130 | +; "EXPLICIT DERIVATIVES" and AUTODERIVATIVE in MPFIT.PRO. | |
82 | 131 | ; |
83 | 132 | ; CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD |
84 | 133 | ; |
... | ... | @@ -253,6 +302,21 @@ |
253 | 302 | ; BESTNORM - the value of the summed squared residuals for the |
254 | 303 | ; returned parameter values. |
255 | 304 | ; |
305 | +; BEST_FJAC - upon return, BEST_FJAC contains the Jacobian, or | |
306 | +; partial derivative, matrix for the best-fit model. | |
307 | +; The values are an array, | |
308 | +; ARRAY(N_ELEMENTS(DEVIATES),NFREE) where NFREE is the | |
309 | +; number of free parameters. This array is only | |
310 | +; computed if /CALC_FJAC is set, otherwise BEST_FJAC is | |
311 | +; undefined. | |
312 | +; | |
313 | +; The returned array is such that BEST_FJAC[I,J] is the | |
314 | +; partial derivative of the model with respect to | |
315 | +; parameter PARMS[PFREE_INDEX[J]]. | |
316 | +; | |
317 | +; BEST_RESID - upon return, an array of best-fit deviates, | |
318 | +; normalized by the weights or errors. | |
319 | +; | |
256 | 320 | ; COVAR - the covariance matrix for the set of parameters returned |
257 | 321 | ; by MPFIT. The matrix is NxN where N is the number of |
258 | 322 | ; parameters. The square root of the diagonal elements |
... | ... | @@ -260,10 +324,12 @@ |
260 | 324 | ; parameters IF errors were treated "properly" in MYFUNC. |
261 | 325 | ; Parameter errors are also returned in PERROR. |
262 | 326 | ; |
263 | -; To compute the correlation matrix, PCOR, use this: | |
264 | -; IDL> PCOR = COV * 0 | |
265 | -; IDL> FOR i = 0, n-1 DO FOR j = 0, n-1 DO $ | |
266 | -; PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j]) | |
327 | +; To compute the correlation matrix, PCOR, use this example: | |
328 | +; PCOR = COV * 0 | |
329 | +; FOR i = 0, n-1 DO FOR j = 0, n-1 DO $ | |
330 | +; PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j]) | |
331 | +; or equivalently, in vector notation, | |
332 | +; PCOR = COV / (PERROR # PERROR) | |
267 | 333 | ; |
268 | 334 | ; If NOCOVAR is set or MPFIT terminated abnormally, then |
269 | 335 | ; COVAR is set to a scalar with value !VALUES.D_NAN. |
... | ... | @@ -275,7 +341,11 @@ |
275 | 341 | ; DOF - number of degrees of freedom, computed as |
276 | 342 | ; DOF = N_ELEMENTS(DEVIATES) - NFREE |
277 | 343 | ; Note that this doesn't account for pegged parameters (see |
278 | -; NPEGGED). | |
344 | +; NPEGGED). It also does not account for data points which | |
345 | +; are assigned zero weight, for example if : | |
346 | +; * WEIGHTS[i] EQ 0, or | |
347 | +; * ERR[i] EQ infinity, or | |
348 | +; * any of the values is "undefined" and /NAN is set. | |
279 | 349 | ; |
280 | 350 | ; ERRMSG - a string error or warning message is returned. |
281 | 351 | ; |
... | ... | @@ -341,8 +411,13 @@ |
341 | 411 | ; parameter values. |
342 | 412 | ; |
343 | 413 | ; MAXITER - The maximum number of iterations to perform. If the |
344 | -; number is exceeded, then the STATUS value is set to 5 | |
345 | -; and MPFIT returns. | |
414 | +; number of calculation iterations exceeds MAXITER, then | |
415 | +; the STATUS value is set to 5 and MPFIT returns. | |
416 | +; | |
417 | +; If MAXITER EQ 0, then MPFIT does not iterate to adjust | |
418 | +; parameter values; however, the user function is evaluated | |
419 | +; and parameter errors/covariance/Jacobian are estimated | |
420 | +; before returning. | |
346 | 421 | ; Default: 200 iterations |
347 | 422 | ; |
348 | 423 | ; NAN - ignore infinite or NaN values in the Y, ERR or WEIGHTS |
... | ... | @@ -366,12 +441,15 @@ |
366 | 441 | ; |
367 | 442 | ; NPRINT - The frequency with which ITERPROC is called. A value of |
368 | 443 | ; 1 indicates that ITERPROC is called with every iteration, |
369 | -; while 2 indicates every other iteration, etc. Note that | |
370 | -; several Levenberg-Marquardt attempts can be made in a | |
371 | -; single iteration. | |
444 | +; while 2 indicates every other iteration, etc. Be aware | |
445 | +; that several Levenberg-Marquardt attempts can be made in | |
446 | +; a single iteration. Also, the ITERPROC is *always* | |
447 | +; called for the final iteration, regardless of the | |
448 | +; iteration number. | |
372 | 449 | ; Default value: 1 |
373 | 450 | ; |
374 | -; PARINFO - Provides a mechanism for more sophisticated constraints | |
451 | +; PARINFO - A one-dimensional array of structures. | |
452 | +; Provides a mechanism for more sophisticated constraints | |
375 | 453 | ; to be placed on parameter values. When PARINFO is not |
376 | 454 | ; passed, then it is assumed that all parameters are free |
377 | 455 | ; and unconstrained. Values in PARINFO are never |
... | ... | @@ -400,13 +478,43 @@ |
400 | 478 | ; DOF = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom |
401 | 479 | ; PCERROR = PERROR * SQRT(BESTNORM / DOF) ; scaled uncertainties |
402 | 480 | ; |
481 | +; PFREE_INDEX - upon return, PFREE_INDEX contains an index array | |
482 | +; which indicates which parameter were allowed to | |
483 | +; vary. I.e. of all the parameters PARMS, only | |
484 | +; PARMS[PFREE_INDEX] were varied. | |
485 | +; | |
486 | +; QUERY - if set, then MPFIT() will return immediately with one of | |
487 | +; the following values: | |
488 | +; 1 - if MIN_VERSION is not set | |
489 | +; 1 - if MIN_VERSION is set and MPFIT satisfies the minimum | |
490 | +; 0 - if MIN_VERSION is set and MPFIT does not satisfy it | |
491 | +; Default: not set. | |
492 | +; | |
403 | 493 | ; QUIET - set this keyword when no textual output should be printed |
404 | 494 | ; by MPFIT |
405 | 495 | ; |
406 | -; STATUS - an integer status code is returned. All values other | |
407 | -; than zero can represent success. It can have one of the | |
496 | +; STATUS - an integer status code is returned. All values greater | |
497 | +; than zero can represent success (however STATUS EQ 5 may | |
498 | +; indicate failure to converge). It can have one of the | |
408 | 499 | ; following values: |
409 | 500 | ; |
501 | +; -18 a fatal execution error has occurred. More information | |
502 | +; may be available in the ERRMSG string. | |
503 | +; | |
504 | +; -16 a parameter or function value has become infinite or an | |
505 | +; undefined number. This is usually a consequence of | |
506 | +; numerical overflow in the user's model function, which | |
507 | +; must be avoided. | |
508 | +; | |
509 | +; -15 to -1 | |
510 | +; these are error codes that either MYFUNCT or ITERPROC | |
511 | +; may return to terminate the fitting process (see | |
512 | +; description of MPFIT_ERROR common below). If either | |
513 | +; MYFUNCT or ITERPROC set ERROR_CODE to a negative number, | |
514 | +; then that number is returned in STATUS. Values from -15 | |
515 | +; to -1 are reserved for the user functions and will not | |
516 | +; clash with MPFIT. | |
517 | +; | |
410 | 518 | ; 0 improper input parameters. |
411 | 519 | ; |
412 | 520 | ; 1 both actual and predicted relative reductions |
... | ... | @@ -542,10 +650,14 @@ |
542 | 650 | ; (the weights were not being applied), CM, 03 Sep 2007 |
543 | 651 | ; Add COMPATIBILITY section, CM, 13 Dec 2007 |
544 | 652 | ; Add documentation about NAN behavior, CM, 30 Mar 2009 |
653 | +; Add keywords BEST_RESIDS, CALC_FJAC, BEST_FJAC, PFREE_INDEX; | |
654 | +; update some documentation that had become stale, CM, 2010-10-28 | |
655 | +; Documentation corrections, CM, 2011-08-26 | |
656 | +; Additional documentation about explicit derivatives, CM, 2012-07-23 | |
545 | 657 | ; |
546 | -; $Id: mpfitfun.pro,v 1.1 2009/08/28 14:29:35 bernard Exp $ | |
658 | +; $Id: mpfitfun.pro,v 1.19 2012/09/27 23:59:31 cmarkwar Exp $ | |
547 | 659 | ;- |
548 | -; Copyright (C) 1997-2002, 2003, 2006, 2007, 2009, Craig Markwardt | |
660 | +; Copyright (C) 1997-2002, 2003, 2006, 2007, 2009, 2010, 2011, 2012, Craig Markwardt | |
549 | 661 | ; This software is provided as is without any warranty whatsoever. |
550 | 662 | ; Permission to use, copy, modify, and distribute modified or |
551 | 663 | ; unmodified copies is granted, provided this copyright and disclaimer |
... | ... | @@ -629,6 +741,8 @@ end |
629 | 741 | |
630 | 742 | function mpfitfun, fcn, x, y, err, p, WEIGHTS=wts, FUNCTARGS=fa, $ |
631 | 743 | BESTNORM=bestnorm, nfev=nfev, STATUS=status, $ |
744 | + best_resid=best_resid, pfree_index=ifree, $ | |
745 | + calc_fjac=calc_fjac, best_fjac=best_fjac, $ | |
632 | 746 | parinfo=parinfo, query=query, CASH=cash, $ |
633 | 747 | covar=covar, perror=perror, yfit=yfit, $ |
634 | 748 | niter=niter, nfree=nfree, npegged=npegged, dof=dof, $ |
... | ... | @@ -733,11 +847,20 @@ function mpfitfun, fcn, x, y, err, p, WEIGHTS=wts, FUNCTARGS=fa, $ |
733 | 847 | result = mpfit('mpfitfun_eval', p, SCALE_FCN=scalfcn, $ |
734 | 848 | parinfo=parinfo, STATUS=status, nfev=nfev, BESTNORM=bestnorm,$ |
735 | 849 | covar=covar, perror=perror, $ |
850 | + best_resid=best_resid, pfree_index=ifree, $ | |
851 | + calc_fjac=calc_fjac, best_fjac=best_fjac, $ | |
736 | 852 | niter=niter, nfree=nfree, npegged=npegged, dof=dof, $ |
737 | 853 | ERRMSG=errmsg, quiet=quiet, _EXTRA=extra) |
738 | 854 | |
739 | 855 | ;; Retrieve the fit value |
740 | 856 | yfit = temporary(mc) |
857 | + | |
858 | + ;; Rescale the Jacobian according to parameter uncertainties | |
859 | + if keyword_set(calc_fjac) AND nfree GT 0 AND status GT 0 then begin | |
860 | + ec = 1/wc ;; Per-data-point errors (could be INF or NAN!) | |
861 | + for i = 0, nfree-1 do best_fjac[*,i] = - best_fjac[*,i] * ec | |
862 | + endif | |
863 | + | |
741 | 864 | ;; Some cleanup |
742 | 865 | xc = 0 & yc = 0 & wc = 0 & ec = 0 & mc = 0 & ac = 0 |
743 | 866 | ... | ... |
src/idl_misc/init_healpix.pro
... | ... | @@ -38,10 +38,10 @@ pro init_healpix, verbose=verbose |
38 | 38 | healpix_sysvar = '!HEALPIX' |
39 | 39 | |
40 | 40 | ; Healpix version |
41 | -version = '2.11c' | |
41 | +version = '2.12a' | |
42 | 42 | |
43 | 43 | ; release data |
44 | -date = '2009-02-19' | |
44 | +date = '2009-08-06' | |
45 | 45 | |
46 | 46 | ; Healpix directory |
47 | 47 | sv = 'HEALPIX' | ... | ... |
1 | -pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols | |
2 | -;+ | |
1 | +pro plotsym, psym, psize, FILL=fill,thick=thick,Color = color | |
2 | + ;+ | |
3 | 3 | ; NAME: |
4 | 4 | ; PLOTSYM |
5 | 5 | ; PURPOSE: |
... | ... | @@ -8,8 +8,10 @@ pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols |
8 | 8 | ; After a symbol has been defined with PLOTSYM, a plotting command should |
9 | 9 | ; follow with either PSYM = 8 or !P.PSYM = 8 (see USERSYM) |
10 | 10 | ; |
11 | +; For additional rotationally symmetric plotting symbols, see VSYM.PRO | |
12 | +; or http://www.dfanning.com/documents/programs.html#SYMCAT | |
11 | 13 | ; CALLING SEQUENCE: |
12 | -; PLOTSYM, PSYM,[ PSIZE, /FILL, THICK=] | |
14 | +; PLOTSYM, PSYM,[ PSIZE, /FILL, THICK=, COLOR=] | |
13 | 15 | ; |
14 | 16 | ; INPUTS: |
15 | 17 | ; PSYM - The following integer values of PSYM will create the |
... | ... | @@ -35,7 +37,7 @@ pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols |
35 | 37 | ; The default is 0, unfilled symbol. Does not affect arrows |
36 | 38 | ; or character symbols. |
37 | 39 | ; THICK - Thickness of unfilled symbols. Default is 1. |
38 | -; | |
40 | +; COLOR - Color of the symbols, Default is !P.color | |
39 | 41 | ; OUTPUTS: |
40 | 42 | ; None |
41 | 43 | ; |
... | ... | @@ -58,12 +60,13 @@ pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols |
58 | 60 | ; Written W. Landsman June 1992 |
59 | 61 | ; 18-JAN-1996 Added a square symbol, HCW. |
60 | 62 | ; 98Aug20 Added keyword thick parameter - RCB. |
63 | +; April 2001 Added COLOR keyword WBL | |
61 | 64 | ;- |
62 | 65 | On_error,2 |
63 | 66 | |
64 | 67 | if N_elements(psym) LT 1 then begin |
65 | 68 | print,'Syntax - PLOTSYM, psym, [ size, /FILL, THICK= ]' |
66 | - print,' PSYM values 0 - circle, 1 - down arrow, 2 - up arrow, 3 - star | |
69 | + print,' PSYM values 0 - circle, 1 - down arrow, 2 - up arrow, 3 - star' | |
67 | 70 | print,' 4 - triangle, 5 - upside down triangle, 6 - left arrow' |
68 | 71 | print,' 7 - right arrow, 8 - square' |
69 | 72 | return |
... | ... | @@ -90,10 +93,15 @@ pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols |
90 | 93 | fill = 0 |
91 | 94 | end |
92 | 95 | 3: begin ;Star |
93 | - r = psize | |
94 | - ang = (720. / 5*findgen(6) + 45) / !RADEG ;Define star angles every 144 deg | |
95 | - xarr = r*cos(ang) & yarr = r*sin(ang) | |
96 | - end | |
96 | + ang = (360. / 10 * findgen(11) + 90) / !RADEG ;star angles every 36 deg | |
97 | + r = ang*0 | |
98 | + r[2*indgen(6)] = 1. | |
99 | + cp5 = cos(!pi/5.) | |
100 | + r1 = 2. * cp5 - 1. / cp5 | |
101 | + r[2*indgen(5)+1] = r1 | |
102 | + r = r * psize / sqrt(!pi/4.) * 2. / (1.+r1) | |
103 | + xarr = r * cos(ang) & yarr = r * sin(ang) | |
104 | + end | |
97 | 105 | 4: begin ;Triangle |
98 | 106 | xarr = [-1,0,1,-1]*psize |
99 | 107 | yarr = [-1,1,-1,-1]*psize |
... | ... | @@ -119,8 +127,9 @@ pro plotsym, psym, psize, FILL=fill,thick=thick ;Define some plotting symbols |
119 | 127 | else: message,'Unknown plotting symbol value of '+strtrim(psym,2) |
120 | 128 | endcase |
121 | 129 | |
130 | + if N_elements(color) GT 0 then $ | |
131 | + usersym, xarr, yarr, FILL = fill,thick=thick, color = color else $ | |
122 | 132 | usersym, xarr, yarr, FILL = fill,thick=thick |
123 | - | |
124 | 133 | return |
125 | 134 | end |
126 | 135 | ... | ... |
src/idl_misc/strtrans.pro
1 | -; ;+ ; NAME: ; STRTRANS ; PURPOSE: ; Translate all occurences of one substring to another. ; CATEGORY: ; text/strings ; CALLING SEQUENCE: ; new = strtrans(oldstr,from,to,ned) ; INPUTS: ; oldstr -- string on which to operate. in ; May be an array. ; from -- substrings to be translated. May be in ; an array. ; to -- what strings in from should be in ; translated to. May be an array. ; KEYWORD PARAMETERS: ; /HELP -- Set this to print useful message and ; exit. ; OUTPUTS: ; new -- Translated string. Array if oldstr is out ; an array. ; ned -- number of substitutions performed in out ; oldstr. Array if oldstr is an array. ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; - Any of old, from, and to can be arrays. ; - from and to must have the same number of elements. ; EXAMPLE: ; inp='Many*bad!chars+in_here' ; from=['*','!','+','_'] ; to =[' ',' ',' ',' '] ; out = strtrans(inp,from,to,ned) ; Will produce out='Many bad chars in here', and set ned to 4. ; MODIFICATION HISTORY: ; $Id: strtrans.pro,v 1.4 2001/11/21 19:13:23 mcraig Exp $ ; $Log: strtrans.pro,v $ ; Revision 1.4 2001/11/21 19:13:23 mcraig ; Changed str_sep to strsplit. The former is now considered obsolete by RSI. ; ; Revision 1.3 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.2 1996/05/09 00:22:17 mcraig ; Sped up significantly by using str_sep to handle the translation. No longer ; relies on routines fromother user libraries. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- ; FUNCTION strtrans, InputString, from, to, ned, $ HELP=Help ; Bomb out to caller if error. On_error, 2 ; Offer help if we don't have at least InputString, from, and to, or ; if the user asks for it. IF (n_params() LT 3) OR keyword_set(help) THEN BEGIN offset = ' ' print, offset+'Translate all occurences of one substring to another.' print, offset+'new = strtrans(oldstr,from,to,ned)' print, offset+'Inputs:' print, offset+offset+'oldstr -- string on which to operate. in' print, offset+offset+' May be an array.' print, offset+offset+'from -- substrings to be translated. May be in' print, offset+offset+' an array.' print, offset+offset+'to -- what strings in from should be in' print, offset+offset+' translated to. May be an array.' print, offset+'Outputs:' print, offset+offset+'new -- Translated string. Array if oldstr is out' print, offset+offset+' an array.' print, offset+offset+'ned -- number of substitutions performed in out' print, offset+offset+' oldstr. Array if oldstr is an array.' print, offset+'Notes:' print, offset+offset+'- Any of old, from, and to can be arrays. ' print, offset+offset+'- from and to must have the same number of elements.' return, -1 ENDIF strn = InputString ; Check that From/To have same number of elements. RETURN if they don't. NFrom = n_elements(from) NTo = n_elements(to) IF (NFrom EQ 0) OR (NTo EQ 0) THEN return, strn IF NFrom NE NTo THEN BEGIN print,'Error: Number of elements in from/to unequal' return,-1 ENDIF ; Make sure there are no null strings in From. RETURN if there are. FromLen = strlen(From) IF (total(FromLen EQ 0) GT 0) THEN BEGIN print, 'Error: elements of From must have nonzero length.' return, -1 ENDIF NStrings = n_elements(strn) ned = lonarr(NStrings) tmpned = 0L ; Say strn='a#b#c', from='#' and to='@'. Then the approach here is to ; first split strn at all occurances of '#', then recombine the pieces ; with '@' inserted instead. Do this for all elements of strn, and ; all elements of from. FOR i = 0L, NStrings-1 DO BEGIN ned(i) = 0L st=strn(i) FOR j=0L, NFrom-1 DO BEGIN strn[i]=textoidl_str_replace(strn[i],from(j),to(j)) ;jpb patch using JD's routine ; SepStr = strsplit(strn(i), from(j)) ;jpb patch ; pos=strposmulti(strn(i),from(j),count) ; SepStr = strsplit(strn(i), from(j),/extract) ;jpb patch ; NSubs = n_elements(SepStr) - 1 ; IF count NE 0 THEN BEGIN ; stop ; SepStr = strsplit(strn(i), from(j),/extract) ; NSubs = n_elements(SepStr) - 1 ; strn(i) = SepStr(0) ; FOR k=1L, NSubs DO strn(i) = strn(i) + To(j) + SepStr(k) ; ned(i) = ned(i) + NSubs ; ENDIF ENDFOR ENDFOR return, strn END | |
2 | 1 | \ No newline at end of file |
2 | +; ;+ ; NAME: ; STRTRANS ; PURPOSE: ; Translate all occurences of one substring to another. ; CATEGORY: ; text/strings ; CALLING SEQUENCE: ; new = strtrans(oldstr,from,to,ned) ; INPUTS: ; oldstr -- string on which to operate. in ; May be an array. ; from -- substrings to be translated. May be in ; an array. ; to -- what strings in from should be in ; translated to. May be an array. ; KEYWORD PARAMETERS: ; /HELP -- Set this to print useful message and ; exit. ; OUTPUTS: ; new -- Translated string. Array if oldstr is out ; an array. ; ned -- number of substitutions performed in out ; oldstr. Array if oldstr is an array. ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; - Any of old, from, and to can be arrays. ; - from and to must have the same number of elements. ; EXAMPLE: ; inp='Many*bad!chars+in_here' ; from=['*','!','+','_'] ; to =[' ',' ',' ',' '] ; out = strtrans(inp,from,to,ned) ; Will produce out='Many bad chars in here', and set ned to 4. ; MODIFICATION HISTORY: ; $Id: strtrans.pro,v 1.4 2001/11/21 19:13:23 mcraig Exp $ ; $Log: strtrans.pro,v $ ; Revision 1.4 2001/11/21 19:13:23 mcraig ; Changed str_sep to strsplit. The former is now considered obsolete by RSI. ; ; Revision 1.3 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.2 1996/05/09 00:22:17 mcraig ; Sped up significantly by using str_sep to handle the translation. No longer ; relies on routines fromother user libraries. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- ; FUNCTION strtrans, InputString, from, to, ned, $ HELP=Help ; Bomb out to caller if error. On_error, 2 ; Offer help if we don't have at least InputString, from, and to, or ; if the user asks for it. IF (n_params() LT 3) OR keyword_set(help) THEN BEGIN offset = ' ' print, offset+'Translate all occurences of one substring to another.' print, offset+'new = strtrans(oldstr,from,to,ned)' print, offset+'Inputs:' print, offset+offset+'oldstr -- string on which to operate. in' print, offset+offset+' May be an array.' print, offset+offset+'from -- substrings to be translated. May be in' print, offset+offset+' an array.' print, offset+offset+'to -- what strings in from should be in' print, offset+offset+' translated to. May be an array.' print, offset+'Outputs:' print, offset+offset+'new -- Translated string. Array if oldstr is out' print, offset+offset+' an array.' print, offset+offset+'ned -- number of substitutions performed in out' print, offset+offset+' oldstr. Array if oldstr is an array.' print, offset+'Notes:' print, offset+offset+'- Any of old, from, and to can be arrays. ' print, offset+offset+'- from and to must have the same number of elements.' return, -1 ENDIF strn = InputString ; Check that From/To have same number of elements. RETURN if they don't. NFrom = n_elements(from) NTo = n_elements(to) IF (NFrom EQ 0) OR (NTo EQ 0) THEN return, strn IF NFrom NE NTo THEN BEGIN print,'Error: Number of elements in from/to unequal' return,-1 ENDIF ; Make sure there are no null strings in From. RETURN if there are. FromLen = strlen(From) IF (total(FromLen EQ 0) GT 0) THEN BEGIN print, 'Error: elements of From must have nonzero length.' return, -1 ENDIF NStrings = n_elements(strn) ned = lonarr(NStrings) tmpned = 0L ; Say strn='a#b#c', from='#' and to='@'. Then the approach here is to ; first split strn at all occurances of '#', then recombine the pieces ; with '@' inserted instead. Do this for all elements of strn, and ; all elements of from. FOR i = 0L, NStrings-1 DO BEGIN ned(i) = 0L st=strn(i) FOR j=0L, NFrom-1 DO BEGIN strn(i)=textoidl_str_replace(strn(i),from(j),to(j)) ;jpb patch using JD's routine ; SepStr = strsplit(strn(i), from(j)) ;jpb patch ; pos=strposmulti(strn(i),from(j),count) ; SepStr = strsplit(strn(i), from(j),/extract) ;jpb patch ; NSubs = n_elements(SepStr) - 1 ; IF count NE 0 THEN BEGIN ; stop ; SepStr = strsplit(strn(i), from(j),/extract) ; NSubs = n_elements(SepStr) - 1 ; strn(i) = SepStr(0) ; FOR k=1L, NSubs DO strn(i) = strn(i) + To(j) + SepStr(k) ; ned(i) = ned(i) + NSubs ; ENDIF ENDFOR ENDFOR return, strn END | |
3 | 3 | \ No newline at end of file | ... | ... |
src/idl_misc/textoidl.pro
1 | -; ;+ ; NAME: ; TEXTOIDL ; PURPOSE: ; Convert a valid TeX string to a valid IDL string for plot labels. ; CATEGORY: ; text/strings ; CALLING SEQUENCE: ; new = textoidl(old) ; INPUTS: ; old -- TeX string to be converted. Will not be in ; modified. old may be a string array. ; KEYWORD PARAMETERS: ; FONT -- Set to 0 to use hardware font, -1 to use ; vector. Note that the only hardware font ; supported is PostScript. ; /TEX_SEQUENCES -- return the available TeX sequences ; /HELP -- print out info on use of the function ; and exit. ; OUTPUTS: ; new -- IDL string corresponding to old. out ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; - Use the procedure SHOWTEX to get a list of the available TeX ; control sequences. ; - The only hardware font for which translation is available is ; PostScript. ; - The only device for which hardware font' ; translation is available is PostScript.' ; - The FONT keyword overrides the font selected' ; by !p.font' ; EXAMPLE: ; out = TeXtoIDL('\Gamma^2 + 5N_{ed}') ; The string out may be used in XYOUTS or other IDL text ; display routines. It will be an uppercase Gamma, with an ; exponent of 2, then a plus sign, then an N with the subscript ; ed. ; MODIFICATION HISTORY: ; $Id: textoidl.pro,v 1.4 1996/06/14 20:00:27 mcraig Exp $ ; $Log: textoidl.pro,v $ ; Revision 1.4 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.3 1996/05/09 00:22:17 mcraig ; Added error handling, cleaned up documentation. ; ; Revision 1.2 1996/02/08 18:52:50 mcraig ; Added ability to use hardware fonts for PostScript device. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- ; FUNCTION Textoidl, InputString, $ FONT=fnt, $ HELP=hlp, $ TEX_SEQUENCES=tex_seq ; Return to caller if there is an error. On_error, 2 ; We begin by deciding on the font. PostScript = 0 means use vector. PostScript = 0 IF n_elements(fnt) EQ 0 THEN BEGIN ; get font from !p.font IF !p.font NE -1 THEN BEGIN ; User wants hardware font. PostScript=1 ENDIF ENDIF ELSE BEGIN ; get font from FONT keyword IF fnt NE -1 THEN PostScript = 1 ENDELSE ; Bomb out if user wants non-PostScript hardware font. IF (PostScript EQ 1) AND (!d.name NE 'PS') THEN BEGIN ; Device isn't postscript ; and user wants hardware ; font. Not good. print,'Warning: No translation for device: ',!d.name return,InputString ENDIF IF keyword_set (tex_seq) THEN BEGIN table=textable() return,table(0,*) ENDIF IF keyword_set(hlp) OR (n_params() EQ 0) THEN BEGIN print, ' Convert a TeX string to an IDL string' print, ' new = TeXtoIDL(old)' print, ' old = TeX string to translate. in' print, ' new = resulting IDL string. out' print, ' Keywords:' print, ' FONT set to -1 to translate for vector fonts ' print, ' (DEFAULT) . Set to 0 to translate for' print, ' hardware font.' print, ' /TEX_SEQUENCES -- return the available TeX sequences' print, ' /HELP print this message and exit.' print, ' NOTES: ' print, ' - Use SHOWTEX to obtain a list of the available' print, ' TeX control sequences.' print, ' - old may be a string array. If so, new is too.' print, ' - The only device for which hardware font' print, ' translation is available is PostScript.' print, ' - The FONT keyword overrides the font selected' print, ' by !p.font' return, -1 ENDIF ; PostScript has been set to 1 if PostScript fonts are desired. strn = InputString table = textable(POSTSCRIPT=PostScript) ; Greek sub/superscripts need to be protected by putting braces ; around them if they are unbraced. This will have the result the ; it will be difficult to use \ as a sub/superscript. Get over it. strn = strtrans(strn, '^'+table(0, *), '^{'+table(0, *)+'}') strn = strtrans(strn, '_'+table(0, *), '_{'+table(0, *)+'}') ; First we translate Greek letters and the like. This makes guessing ; alignment of sub/superscripts easier, as all special characters will then ; be one character long. strn = strtrans(strn, table(0, *), table(1, *)) FOR i = 0L, n_elements(strn)-1 DO $ strn[i] = translate_sub_super(strn[i]) ; Take care of sub/superscripts return,strn END | |
2 | 1 | \ No newline at end of file |
2 | +; ;+ ; NAME: ; TEXTOIDL ; PURPOSE: ; Convert a valid TeX string to a valid IDL string for plot labels. ; CATEGORY: ; text/strings ; CALLING SEQUENCE: ; new = textoidl(old) ; INPUTS: ; old -- TeX string to be converted. Will not be in ; modified. old may be a string array. ; KEYWORD PARAMETERS: ; FONT -- Set to 0 to use hardware font, -1 to use ; vector. Note that the only hardware font ; supported is PostScript. ; /TEX_SEQUENCES -- return the available TeX sequences ; /HELP -- print out info on use of the function ; and exit. ; OUTPUTS: ; new -- IDL string corresponding to old. out ; COMMON BLOCKS: ; SIDE EFFECTS: ; NOTES: ; - Use the procedure SHOWTEX to get a list of the available TeX ; control sequences. ; - The only hardware font for which translation is available is ; PostScript. ; - The only device for which hardware font' ; translation is available is PostScript.' ; - The FONT keyword overrides the font selected' ; by !p.font' ; EXAMPLE: ; out = TeXtoIDL('\Gamma^2 + 5N_{ed}') ; The string out may be used in XYOUTS or other IDL text ; display routines. It will be an uppercase Gamma, with an ; exponent of 2, then a plus sign, then an N with the subscript ; ed. ; MODIFICATION HISTORY: ; $Id: textoidl.pro,v 1.4 1996/06/14 20:00:27 mcraig Exp $ ; $Log: textoidl.pro,v $ ; Revision 1.4 1996/06/14 20:00:27 mcraig ; Updated Copyright info. ; ; Revision 1.3 1996/05/09 00:22:17 mcraig ; Added error handling, cleaned up documentation. ; ; Revision 1.2 1996/02/08 18:52:50 mcraig ; Added ability to use hardware fonts for PostScript device. ; ; Revision 1.1 1996/01/31 18:47:37 mcraig ; Initial revision ; ; RELEASE: ; $Name: Rel_2_1 $ ; ; COPYRIGHT: ; Copyright (C) 1996 The Regents of the University of California, All ; Rights Reserved. Written by Matthew W. Craig. ; See the file COPYRIGHT for restrictions on distrubting this code. ; This code comes with absolutely NO warranty; see DISCLAIMER for details. ;- ; FUNCTION Textoidl, InputString, $ FONT=fnt, $ HELP=hlp, $ TEX_SEQUENCES=tex_seq ; Return to caller if there is an error. On_error, 2 ; We begin by deciding on the font. PostScript = 0 means use vector. PostScript = 0 IF n_elements(fnt) EQ 0 THEN BEGIN ; get font from !p.font IF !p.font NE -1 THEN BEGIN ; User wants hardware font. PostScript=1 ENDIF ENDIF ELSE BEGIN ; get font from FONT keyword IF fnt NE -1 THEN PostScript = 1 ENDELSE ; Bomb out if user wants non-PostScript hardware font. IF (PostScript EQ 1) AND (!d.name NE 'PS') THEN BEGIN ; Device isn't postscript ; and user wants hardware ; font. Not good. print,'Warning: No translation for device: ',!d.name return,InputString ENDIF IF keyword_set (tex_seq) THEN BEGIN table=textable() return,table(0,*) ENDIF IF keyword_set(hlp) OR (n_params() EQ 0) THEN BEGIN print, ' Convert a TeX string to an IDL string' print, ' new = TeXtoIDL(old)' print, ' old = TeX string to translate. in' print, ' new = resulting IDL string. out' print, ' Keywords:' print, ' FONT set to -1 to translate for vector fonts ' print, ' (DEFAULT) . Set to 0 to translate for' print, ' hardware font.' print, ' /TEX_SEQUENCES -- return the available TeX sequences' print, ' /HELP print this message and exit.' print, ' NOTES: ' print, ' - Use SHOWTEX to obtain a list of the available' print, ' TeX control sequences.' print, ' - old may be a string array. If so, new is too.' print, ' - The only device for which hardware font' print, ' translation is available is PostScript.' print, ' - The FONT keyword overrides the font selected' print, ' by !p.font' return, -1 ENDIF ; PostScript has been set to 1 if PostScript fonts are desired. strn = InputString table = textable(POSTSCRIPT=PostScript) ; Greek sub/superscripts need to be protected by putting braces ; around them if they are unbraced. This will have the result the ; it will be difficult to use \ as a sub/superscript. Get over it. strn = strtrans(strn, '^'+table(0, *), '^{'+table(0, *)+'}') strn = strtrans(strn, '_'+table(0, *), '_{'+table(0, *)+'}') ; First we translate Greek letters and the like. This makes guessing ; alignment of sub/superscripts easier, as all special characters will then ; be one character long. strn = strtrans(strn, table(0, *), table(1, *)) FOR i = 0L, n_elements(strn)-1 DO $ strn(i) = translate_sub_super(strn(i)) ; Take care of sub/superscripts return,strn END | |
3 | 3 | \ No newline at end of file | ... | ... |