| 1 | function t_bb,radiance,lambda,response,emissivity=eps,range=range, $ |
|---|
| 2 | t_bb_data=t_bb_data,autorange=autorange,truncate=truncate,spline=spline, $ |
|---|
| 3 | verbose=verbose |
|---|
| 4 | |
|---|
| 5 | ; calculates temperature (K) corresponding to given radiance (W/m2/sr/um) from |
|---|
| 6 | ; instrument with response curve response(lambda) (lambda in nm, response |
|---|
| 7 | ; relative) and optional emissivity eps (default 1) - lookup table calculated |
|---|
| 8 | ; and returned in structure t_bb_data for future use if multiple calls are |
|---|
| 9 | ; required. If a temperature range for the lookup table different from the |
|---|
| 10 | ; default is required, it can be specified using range=[t_min,t_max[,t_step]] |
|---|
| 11 | ; though the program will attempt to autorange if required. |
|---|
| 12 | |
|---|
| 13 | default_t_min=270. ; minimum lookup table temperature |
|---|
| 14 | default_t_max=370. ; maximum lookup table temperature |
|---|
| 15 | default_t_step=.1 ; lookup table temperature step |
|---|
| 16 | max_n_t=5000 ; maximum number of lookup table entries (for autoranging) |
|---|
| 17 | n_non_spline_tags=10 ; number of tags in t_bb_data excluding spline |
|---|
| 18 | auto=keyword_set(autorange) |
|---|
| 19 | chop=keyword_set(truncate) |
|---|
| 20 | spline_set=keyword_set(spline) |
|---|
| 21 | verb=keyword_set(verbose) |
|---|
| 22 | n_lambda=n_elements(lambda) |
|---|
| 23 | n_eps=n_elements(eps) |
|---|
| 24 | if n_eps gt 1 && n_eps ne n_elements(radiance) then $ |
|---|
| 25 | message,'T_BB: Emissivity must match radiance' |
|---|
| 26 | if n_elements(response) ne n_lambda then $ |
|---|
| 27 | message,'T_BB: Response must have same number of elements as lambda' |
|---|
| 28 | n_range=n_elements(range) |
|---|
| 29 | range_set=n_range gt 0 |
|---|
| 30 | t_bb_data_present=n_elements(t_bb_data) gt 0 |
|---|
| 31 | if range_set then begin |
|---|
| 32 | if n_range lt 2 then message,'T_BB: Range must have at least 2 elements' |
|---|
| 33 | t_min=range[0] |
|---|
| 34 | t_max=range[1] |
|---|
| 35 | if n_range gt 2 then t_step=range[2] else t_step=default_t_step |
|---|
| 36 | endif else if t_bb_data_present then begin |
|---|
| 37 | t_min=t_bb_data.t_min |
|---|
| 38 | t_max=t_bb_data.t_max |
|---|
| 39 | t_step=t_bb_data.t_step |
|---|
| 40 | endif else begin |
|---|
| 41 | t_min=default_t_min |
|---|
| 42 | t_max=default_t_max |
|---|
| 43 | t_step=default_t_step |
|---|
| 44 | endelse |
|---|
| 45 | min_radiance=min(radiance,max=max_radiance) |
|---|
| 46 | if t_bb_data_present then begin |
|---|
| 47 | too_low=min_radiance lt t_bb_data.rad_min |
|---|
| 48 | too_high=max_radiance gt t_bb_data.rad_max |
|---|
| 49 | if too_low || too_high then begin |
|---|
| 50 | if auto then begin |
|---|
| 51 | if too_low then begin ; expand downwards |
|---|
| 52 | t_min=t_min-.5*(t_max-t_min)>(.5*t_min) |
|---|
| 53 | t_bb_data_present=0 |
|---|
| 54 | endif |
|---|
| 55 | if too_high then begin ; expand upwards |
|---|
| 56 | t_max=t_max+.5*(t_max-t_min) |
|---|
| 57 | t_bb_data_present=0 |
|---|
| 58 | endif |
|---|
| 59 | if verb then print,'Expanding T range to ',t_min,t_max |
|---|
| 60 | endif else if chop then begin ; truncate radiance to table limits |
|---|
| 61 | radiance=radiance>t_bb_data.rad_min<t_bb_data.rad_max |
|---|
| 62 | endif else message,'Lookup table radiance range: '+ $ |
|---|
| 63 | string(t_bb_data.rad_min)+string(t_bb_data.rad_max)+', data: '+ $ |
|---|
| 64 | string(min_radiance)+string(max_radiance) |
|---|
| 65 | endif |
|---|
| 66 | endif |
|---|
| 67 | if t_bb_data_present then begin |
|---|
| 68 | if range_set then if t_bb_data.t_min ne t_min || t_bb_data.t_max ne t_max $ |
|---|
| 69 | || t_bb_data.t_step ne t_step then t_bb_data_present=0 |
|---|
| 70 | if spline_set && n_tags(t_bb_data) le n_non_spline_tags then $ |
|---|
| 71 | t_bb_data_present=0 ; splines requested but not found in table |
|---|
| 72 | if t_bb_data.n_lambda ne n_lambda then t_bb_data_present=0 else $ |
|---|
| 73 | if max(t_bb_data.lambda ne lambda) || max(t_bb_data.response ne response)$ |
|---|
| 74 | then t_bb_data_present=0 |
|---|
| 75 | if ~t_bb_data_present then print,'T_BB WARNING: overwriting t_bb_data' |
|---|
| 76 | endif |
|---|
| 77 | if ~t_bb_data_present then begin ; set up t_bb_data |
|---|
| 78 | repeat begin |
|---|
| 79 | n_temps=floor((t_max-t_min)/t_step)+1 |
|---|
| 80 | if auto && n_temps gt max_n_t then begin |
|---|
| 81 | n_temps=max_n_t |
|---|
| 82 | t_step=(t_max-t_min)/(n_temps-1) |
|---|
| 83 | if verb then print,'T_BB WARNING: changing t_step to ',t_step |
|---|
| 84 | endif |
|---|
| 85 | temps=t_min+findgen(n_temps)*t_step |
|---|
| 86 | radiances=l_band(lambda,response,temps) |
|---|
| 87 | rad_min=min(radiances,max=rad_max) |
|---|
| 88 | too_low=min_radiance lt rad_min |
|---|
| 89 | too_high=max_radiance gt rad_max |
|---|
| 90 | if too_low || too_high then begin |
|---|
| 91 | if auto then begin |
|---|
| 92 | if too_low then t_min=t_min-.5*(t_max-t_min)>(.5*t_min) ;expand downward |
|---|
| 93 | if too_high then t_max=t_max+.5*(t_max-t_min) ; expand upward |
|---|
| 94 | if verb then print,'Expanding T range to ',t_min,t_max, $ |
|---|
| 95 | ', lookup table radiance range: ',rad_min,rad_max |
|---|
| 96 | endif else if chop then begin ; truncate radiance to table limits |
|---|
| 97 | radiance=radiance>rad_min<rad_max |
|---|
| 98 | too_low=0 |
|---|
| 99 | too_high=0 |
|---|
| 100 | endif else message,'Lookup table radiance range: '+string(rad_min)+ $ |
|---|
| 101 | string(rad_max)+', data: '+string(min_radiance)+string(max_radiance) |
|---|
| 102 | endif |
|---|
| 103 | endrep until ~(too_low || too_high) |
|---|
| 104 | if spline_set then begin |
|---|
| 105 | spline=spl_init(radiances,temps) |
|---|
| 106 | t_bb_data={t_bb_str_spline,n_lambda:n_lambda,lambda:lambda, $ |
|---|
| 107 | response:response,t_min:t_min,t_max:t_max,t_step:t_step,temps:temps, $ |
|---|
| 108 | radiances:radiances,rad_min:rad_min,rad_max:rad_max,spline:spline} |
|---|
| 109 | endif else begin |
|---|
| 110 | t_bb_data={t_bb_str,n_lambda:n_lambda,lambda:lambda,response:response, $ |
|---|
| 111 | t_min:t_min,t_max:t_max,t_step:t_step,temps:temps,radiances:radiances, $ |
|---|
| 112 | rad_min:rad_min,rad_max:rad_max} |
|---|
| 113 | endelse |
|---|
| 114 | endif |
|---|
| 115 | if n_eps gt 0 then begin |
|---|
| 116 | if spline_set then return,spl_interp(t_bb_data.radiances,t_bb_data.temps, $ |
|---|
| 117 | t_bb_data.spline,radiance/eps) else $ |
|---|
| 118 | return,interpol(t_bb_data.temps,t_bb_data.radiances,radiance/eps) |
|---|
| 119 | endif else begin |
|---|
| 120 | if spline_set then return,spl_interp(t_bb_data.radiances,t_bb_data.temps, $ |
|---|
| 121 | t_bb_data.spline,radiance) else $ |
|---|
| 122 | return,interpol(t_bb_data.temps,t_bb_data.radiances,radiance) |
|---|
| 123 | endelse |
|---|
| 124 | |
|---|
| 125 | end |
|---|