Commit 860668891bf3e02ff0f6501fe8f5cee99ac75197

Authored by Annie Hughes
1 parent 56f461b1
Exists in master

first commit

Showing 1 changed file with 177 additions and 0 deletions   Show diff stats
src/idl/dustem_str_tools.pro 0 → 100755
... ... @@ -0,0 +1,177 @@
  1 +FUNCTION ADD_MOD, sf, tag, nsz, unit=unit
  2 +; adds a model tag to a existing SMDAT structure
  3 +; SF (I): input SMDAT structure
  4 +; TAG (I): tag of model to be added
  5 +; NSZ (I): int array(2) of sizes [nr of data pts, nr of grain types]
  6 +
  7 + tag = STRLOWCASE(STRTRIM(tag,2))
  8 + if n_elements(nsz) GT 1 then begin
  9 + n1 = nsz(0) & n2 = nsz(1)
  10 + if n_elements(nsz) EQ 3 then n3 = nsz(2) else n3 = 0
  11 + endif else begin
  12 + print,'(F) ADD_MOD: array of sizes must > 1D'
  13 + endelse
  14 + if TAG EQ 'emis' then begin
  15 + if n_elements(unit) EQ 0 then unit='x(microns) SED(erg/s/cm2/sr)'
  16 + s1 = { UNIT : unit, $
  17 + X : dblarr(n1), $ ; wave
  18 + Y : dblarr(n1,n2), $ ; SED(wave, grain type) (index ntype is total)
  19 + YP : dblarr(n1,n2) } ; polarized SED(wave, grain type) (index ntype is total)
  20 + ENDIF else if TAG EQ 'ext' then begin
  21 + if n_elements(unit) EQ 0 then unit='x(microns) sigma(cm2/H)'
  22 + s1 = {UNIT : unit, $
  23 + X : dblarr(n1), $ ; wave
  24 + Y : dblarr(n1,n2), $ ; sigma_ext(wave, grain type) (index ntype is total)
  25 + ABS : dblarr(n1,n2), $ ; sigma_abs(wave, grain type)
  26 + SCA : dblarr(n1,n2), $ ; sigma_sca(wave, grain type)
  27 + ABS_P : dblarr(n1,n2), $ ; absorption sigma_pol(wave, grain type)
  28 + SCA_P : dblarr(n1,n2), $ ; scattering sigma_pol(wave, grain type)
  29 + ALB : dblarr(n1,n2), $ ; alb(wave, grain type)
  30 + XR : 0d, $ ; ref wave
  31 + YR_ABS : dblarr(n2), $ ; tau_abs/NH @ XR
  32 + YR_SCA : dblarr(n2), $ ; tau_sca/NH @ XR
  33 + RV : 0d }
  34 +; ENDIF else if TAG EQ 'pol' then begin
  35 +; if n_elements(unit) EQ 0 then unit='x(microns) SED(erg/s/cm2/sr)'
  36 +; s1 = {UNIT : unit, $
  37 +; X: dblarr(n1), $ ; wave
  38 +; Y: dblarr(n1,n2), $ ; polarized SED(wave, grain type) (index ntype is total)
  39 +; POL: dblarr(n1,n2) } ; sigma_pol(wave, grain type) (ABS + SCAT)
  40 + ENDIF else if tag EQ 'sdist' then begin
  41 + if n3 EQ 0 then begin
  42 + print,'(F) ADD_MOD: 3d dimension missing '
  43 + return,0
  44 + endif
  45 + if n_elements(unit) EQ 0 then unit='x(cm) a^4*dn/da(cm3/H)'
  46 + s1 = {UNIT : unit, $
  47 + XTOT : dblarr(n1), $ ; grain size
  48 + YTOT : dblarr(n1,n2), $ ; size distribution
  49 + XI : dblarr(n3,n2), $ ; grain size per type
  50 + YI : dblarr(n3,n2) } ; grain size dist per type
  51 + ENDIF
  52 + sm = CREATE_STRUCT( CREATE_STRUCT('M_'+tag,s1), sf )
  53 + return, sm
  54 +END
  55 +
  56 +FUNCTION STR_INST, n1, n2=n2, n3=n3
  57 +; returns structure containing flux and CC in band
  58 +; N1 (I): number of data points
  59 +; N2 (I): nr of grain types or different models
  60 +; N3 (I): nr of points in transmission (band flux data)
  61 +
  62 + if n_elements(n2) EQ 0 then n2 = 1
  63 +
  64 + if n_elements(n3) NE 0 then begin
  65 + strct = { NAME : strarr(n1), $
  66 + X : dblarr(n1), $
  67 + YD : dblarr(n1), $
  68 + ERR : dblarr(n1), $
  69 + YM : dblarr(n1,n2), $
  70 + FLX : dblarr(n1,n2), $
  71 + CC : dblarr(n1,n2), $
  72 + RR : dblarr(n1), $
  73 + ISEL : intarr(n1)+1, $
  74 + UNIT : '', $
  75 + NPAR : 0, $
  76 + CHI2 : 0d }
  77 + s1 = CREATE_STRUCT('TRANS', {X : dblarr(n1,n3), Y : dblarr(n1,n3) })
  78 + strct = CREATE_STRUCT( strct, s1 )
  79 + endif else if n_elements(BAND) EQ 0 then begin
  80 + strct = { X : dblarr(n1), $
  81 + YD : dblarr(n1), $
  82 + ERR : dblarr(n1) , $
  83 + YM : dblarr(n1,n2), $
  84 + ISEL : intarr(n1)+1, $
  85 + UNIT : '', $
  86 + NPAR : 0, $
  87 + CHI2 : 0d }
  88 + endif
  89 +
  90 + RETURN, strct
  91 +END
  92 +
  93 +FUNCTION CHI2, y, model, npar, err=err
  94 +; returns the chi-square value of fit MODEL to data Y
  95 +;
  96 +; NPAR (I): nr of parameters in the fit
  97 +; ERR (I): error of each data point. Default is ERR=0.1*Y
  98 +
  99 + ny = n_elements(y)
  100 + if n_elements(err) EQ 0 OR TOTAL(err) EQ 0 then begin
  101 + err = 0.1*y
  102 + print,'(W) CHI2: error missing, set to 10 %'
  103 + endif
  104 + ndof = ny - npar ; nr of degrees of freedom
  105 + chi = TOTAL( ((y-model)/err)^2 )
  106 + if ndof GT 0 then chi = chi / ndof
  107 +
  108 + return, chi
  109 +END
  110 +
  111 +FUNCTION FIL_CHI2, sf, ntype=ntype
  112 +; fills in the Chi-square fields of an input SMDAT structure
  113 +; (see format in GET_BAND_FLUX)
  114 +;
  115 +; SF (I): input SMDAT structure
  116 +; NTYPE (I): index of SED to be used
  117 +
  118 + if ntype EQ 0 then begin
  119 + tt = SIZE(sf.sed.y)
  120 + ntype = tt(2)
  121 + endif
  122 + ntag = N_TAGS(sf)
  123 + stag = TAG_NAMES(sf)
  124 + itg = WHERE( STRPOS(stag,'I_') GE 0, ctg )
  125 + if ctg EQ 0 then begin
  126 + print,'(F) FIL_CHI2: no instrument to fill in'
  127 + return,0
  128 + endif
  129 + yy=0d & mm=0d & ee=0d & ift=0
  130 + for k = 0, ctg-1 do begin
  131 + i1 = WHERE( sf.(itg(k)).isel EQ 1 AND sf.(itg(k)).err GT 0, c1)
  132 + if c1 GT 0 then begin
  133 + sf.(itg(k)).chi2 = $
  134 + CHI2(sf.(itg(k)).yd(i1), sf.(itg(k)).ym(i1,ntype-1), sf.(itg(k)).npar, err=sf.(itg(k)).err(i1))
  135 + endif
  136 + yy = [ yy, sf.(itg(k)).yd ]
  137 + ee = [ ee, sf.(itg(k)).err]
  138 + mm = [ mm, sf.(itg(k)).ym(*,ntype-1) ]
  139 + ift = [ ift, sf.(itg(k)).isel ]
  140 + endfor
  141 + yy=yy(1:*) & ee=ee(1:*) & mm=mm(1:*) & ift=ift(1:*)
  142 + it = WHERE( ift EQ 1 AND ee GT 0, ct)
  143 + if ct GT 0 then sf.chi2 = CHI2( yy(it), mm(it), sf.npar, err=ee(it))
  144 +
  145 + return, sf
  146 +END
  147 +
  148 +FUNCTION ADD_INST, sf, tag, nsz, ntrans=ntrans
  149 +; fills in data for existing instruments in SMDAT structure
  150 +; or add a new instrument to SMDAT structure
  151 +;
  152 +; SF (I): SMDAT input structure
  153 +; TAG (I): name of instrument to add in
  154 +; NSZ (I): array(2) of sizes [nr of data pts, nr of grain types]
  155 +; NTRANS (I): nr of points for transmission (bad flux data)
  156 +
  157 + stag = TAG_NAMES(sf)
  158 + ntag = N_TAGS(sf)
  159 + tag = STRUPCASE('I_'+STRTRIM(tag,2))
  160 + itg = WHERE( stag EQ tag, ctg )
  161 + if n_elements(nsz) EQ 2 then begin
  162 + nx = nsz(0) & ntype = nsz(1)
  163 + endif else begin
  164 + print,'(F) ADD_MOD: array of sizes must be 2D'
  165 + endelse
  166 + if ctg EQ 0 then begin
  167 + if n_elements(ntrans) EQ 0 then st = CREATE_STRUCT( tag, STR_INST(nx,n2=ntype) ) $
  168 + else st = CREATE_STRUCT( tag, STR_INST(nx,n2=ntype,n3=ntrans) )
  169 + sf = CREATE_STRUCT( sf, st )
  170 + stag = TAG_NAMES(sf)
  171 + itg = WHERE( stag EQ tag )
  172 + sf.(itg).isel = intarr(nx) + 1
  173 + endif else begin
  174 + print,'(F) ADD_INST: INST already exists in structure'
  175 + endelse
  176 + return,sf
  177 +END
... ...