;+ ; NAME: ; cdf_fhc ; ; PURPOSE: ; Perform the fuzzy logic hydrometeor classification (FHC) ; using input polarimetric variables and temperature. Return the FHC ; types in an array of the same size as the input polarimetric variables. ; ; This method is based on the method of Liu and Chandrasekar (2000), ; J. Atmos. Oceanic Tech., _17_, 140-164. This assumes summer convective ; storms. ; However, my method uses a weighted sum of each truth value instead ; of the straight multiplication method of L&C (2000). ; ; Truth value of each hydrotype for each input variable is a beta ; function. The total truth value for each hydro type is thus a ; weighted sum of the truth value of each input variable, with two ; exceptions: The horizontal reflectivity and temperature (if used) truth ; values are multiplied by the weighted sum of the others, thus effectively ; weighting the final output more strongly on the horizontal reflectivity ; and temperature (if present). ; ; Uses parameters defined in 'cdf_beta_functions.pro' to define the ; m,a,b parameters for each hydro type's beta function. The independent ; variable 'x' is one of the radar measurements. ; ; Basic form of a Membership Beta Function is: ; ; 1 ; --------------------- ; beta(x) = | |^b ; 1+ | ((x-m)/a)^2 | ; | | ; ; Where x = input data (Zh, Zdr, etc) ; m = center ; a = width ; b = slope ; ; Anticipate having up to 6 input data fields and 11 fuzzy sets (HID types) for ; summer storms. ; ; Input data fields: HID types: Fuzzy set: ;------------------- ---------- ---------- ; Z_h Drizzle 1 ; Z_dr Rain 2 ; K_dp Dry snow 3 ; LDR Wet snow 4 ; rho_hv[0] Vertical Ice 5 ; Temperature Dry graupel 6 ; Wet graupel 7 ; Small hail 8 ; Large hail 9 ; Sm. Hail & Rain 10 ; Lg. Hail & Rain 11 ; ; So there should be 6 X 11 = 66 beta functions...one for each pair ; of inputs and fuzzy sets ; ; The final output for each grid point is the fuzzy set which has the ; highest cumulative truth value (i.e., the most likely hydrometeor type). ; ; If there is an error, the function will return the integer zero instead ; of a gridded array. ; ; USAGE: ; output = cdf_fhc(radar_data,mbf_sets,fhc_vars[,T,weights=weights, ; use_temp=use_temp,compare=compare]) ; ; Terms in brackets [] are optional. ; ; INPUT PARAMETERS: ; REQUIRED INPUTS ; radar_data -- A structure containing the radar data (Should not matter if in radial ; or gridded format). The structure must ; have one of the following tag names: DZ,DR,KD,LD,RH. ; These correspond to horiz. reflect, diff. reflect., ; spec. diff. phase, linear depol. ratio, and corr. coeff., ; respectively. For example, to use all these variables in ; the classification, define this structure as: ; ; radar_data = {DZ:dz_data,$ ; DR:DR_data,$ ; KD:KD_data,$ ; LD:LD_data,$ ; RH:RH_data} ; ; Then call the program: ; result = cdf_fhc(radar_data,...) ; ; Or if you have only horiz. reflect. and ; diff. reflect. define the structure like this: ; ; radar_data = {DZ:dz_data,$ ; DR:DR_data} ; ; Only the tag names are important, e.g., the two-character ; string before each colon must be DZ, DR, etc. The ; actual data (e.g., dz_data) should be 1,2,or3-d floating ; point array of the appropriate data. Each data field is ; expected to have the same dimensions. ; mbf_sets -- Beta function parameters for each fuzzy set and input ; variable (defined in 'cdf_beta_functions.pro') ; fhc_vars -- A Boolean structure of which input variables to use in the ; FHC. Should be a 6-element structure of either 0 (Don't ; Include) or 1 (Do Include) ; fhc_vars = {Zh: 0 or 1, ; Zdr:0 or 1, ; Kdp:0 or 1, ; LDR:0 or 1, ; rho_hv: 0 or 1, ; T: 0 or 1} ; The use for this array is to do sensitivity tests where you'd ; explicity state which radar fields to use in the ; classification. If the corresponding data is not present ; in the radar_data input structure, then this program will ; override what you passed it as 'fhc_vars' and set ; its boolean value to 0. For example, if there is no LD field ; in the radar_data structure, then this program will do the ; following: ; ; fhc_vars.LDR = 0 ; ; And hence will not try to use LDR in the classification. ; ; OPTIONAL INPUTS ; T -- Temperature, either single value or a 1-D vertical profile with the ; temperature defined at each vertical grid point of the radar data. ; --BD 2-2012: Changed to require this be the same size as the input data. ; weights -- Weights for the different variables. Added this as a keyword such that you don't ; need a speciifc cdf_fhc for different radars. If weights is not passed, then ; default values are used. This is a structure like fhc_vars: ; Weights= { W_Zh: 1.5 , ; W_Zdr: 0.8, ; W_Kdp: 1.0, ; W_rho: 0.8, ; W_ldr: 0.5, ; W_T: 0.4} ; ; ; KEYWORDS: ; use_temp -- If set, use temperature in the FHC. If you set this keyword, ; make sure you also supply a temperature (T) input. ; compare -- If set, a structure will be returned intstead of just the FHT variable. It will contain the first ; and second best scoring categories, as well as their scores. ; fdat = { FHT, FHT2, mu_best, mu_sec} ; ;BD 2-2012: CHANGED SO NONE OF THESE ARE AVAILABLE ANYMORE. By making temperature ; The same size as the other variables, no longer need /rhi or /ppi. ; Sum_it never quite worked right for me anyway, so stick with the Hybrid method for now. ; rhi -- IF set, assume temperature is an array of temperatures at ; each z level of the radar field arrays. Program assumes that the ; second dimension of the input radar data corresponds to height. ; ppi -- If set, assume temperature is a single number for a given ; height level. ; sum_it -- If set, use a weighted sum method for all variables. If not ; set, use a weighted sum for Zdr, Kdp, LDR, and rho_hv; then ; multiply this sum by the scores for Zh and Temperature. ; ; You need to set either the 'rhi' or 'ppi' keyword only if you are passing ; a 2-D cross-section of data to this program and you are including ; temperature. Otherwise, if you are passing a 3-D array and including ; temperature, the program will assume the 3rd dimension of the input radar ; data corresponds to height. ; ;IF radar_data is just single values, then the scores for each category given those inputs will be ; printed out. ; ;IF the compare keyword is set, then the output will be a structure that contains the first and second best scoring ; HID types, as well as the socres associated with those two categories. ; ; AUTHOR: ; Kyle C. Wiens ; kwiens@atmos.colostate.edu ; ; DATE: ; 26 April 2002. ; ; MODIFICATIONS: ; ; 28 April 2002: Changed the aggregation operations. Instead of ; taking a sum of all the MBFs, I take a sum of the polarimetric MBFs ; and then multiply this sum by the MBFs for temperature and ; horizontal reflectivity. ; ; 4 May 2002: Added weighting factors. ; Also added ability to use any combination of the input ; variables in the FHC by multiplying each MBF by its ; associated fhc_vars value. This is for doing sensitivity ; tests or if you don't have all 5 of the radar measurements. ; ; 5 May 2002: Made weighting factors for Zdr, Kdp, LDR, and rho_hv ; dependent on the hydro type. ; ; 15 May 2002: Added division by the sum of the weighting factors so ; that the scores are normalized with respect to these factors. I ; should have done this a long time ago!!! ; ; 24 May 2002: Changed the weighting factors back to being the same for each ; hydrometeor type. ; ; 23 July 2002: Greatly improved the efficiency of this program by ; performing all the beta function calculations on the entire 2 or 3 ; dimensional data sets, all at once. I used to have 4 embedded FOR ; loops to do this. It took some brain power to figure out how to ; keep the maximum scores from each iteration, but apparently, my ; brain was up to the task. This runs MUCH faster now, with identical ; results. ; ; 24 July 2002: Decomposed rain/hail mix into large and small hail ; components. ; ; 7 April 2003: Added a few lines to allow the user to do the ; classification using any combination of input variables. ; ; 23 April 2003: Changed the calling sequence so that the input radar data ; is a structure instead of each individual field. This should make the ; program more modular by allowing it to work with any combination of radar ; variables. I also added more comments. ; ; 21 January 2004: Added option to use a weighted sum for all variables by ; passing the /Sum_It keyword. ; 22 February 2012: Modified to be more modular, and no longer require so many keywords. ; Also set up to pass in a single set of radar observations to calculate the scores. ; B.D. 2-2012 ;- ; 17 September 2014: Program was returning -1 with 'good' data when none of the mu scores were > 0.001. ; Changed so if the scores were < 0.001 it would result in a score of 0 (unknown). Then ; at the end of the program, set all the FHT scores to -1 where data is bad (use Zh if fhc_vars.Zh eq 1, ; Otherwise look for bad KD, DR or RH. ; B.D. ;-------- ; This is a sub-function of the main program. ; ; FUNCTION hid_beta ; Compute the value of the beta function from inputs x,a,b,m ; Where, ; x = independent variable (DZ,KDP,etc.) ; a = width. ; b = slope. ; m = midpoint ;-------- FUNCTION hid_beta,x,a,b,m beta = 0.0d beta = 1.0/(1.0 + ( ((x - m)/a)^2 )^b) RETURN,beta END ; ----------- ; FUNCTION cdf_fhc ; Do the fuzzy logic classification and return array of hydrometeor ; types. ;------------ FUNCTION cdf_fhc_all,radar_data,mbf_sets,fhc_vars,T,$ use_temp=use_temp,weights=weights, compare=compare me = '-->cdf_fhc_all: ' ; Check which data sets are present in the radar data. radar_names = TAG_NAMES(radar_data) ; Check for the horizontal reflectivity field. If it's present, then grab ; the size of the data and use it to size dummy arrays for the other ; variables. If it's not present, then RETURN, because hydro ID is useless ; without it. wh_dz = where(radar_names EQ 'DZ') IF(wh_dz[0] GE 0) THEN BEGIN DZ = radar_data.DZ ; Get the size of the input data. size_radar = size(DZ) ; Not very efficient to make all these ; dummy arrays, but oh well. DR =-32767.0*DZ KD =-32767.0*DZ LD =-32767.0*DZ RH =-32767.0*DZ ;stop ENDIF ELSE BEGIN ; There's no DZ array, return. print,me+'No DZ field present...Returning.' RETURN,0 ENDELSE ;;;;Check for the weights: IF keyword_set(weights) THEN BEGIN print,'Using Weights passed in!' W_Zh=weights.W_zh W_Zdr=weights.W_Zdr W_Kdp=weights.W_Kdp W_rho=weights.W_rho W_Ldr=weights.W_Ldr W_T=weights.W_T ENDIF ELSE BEGIN print,'Using default Weight values!' ; Define weighting factors (After Zrnic et. al, 2000) W_Zh = 1.5 ; Same for all hydrotypes. W_Zdr = 0.8 W_Kdp = 1.0 W_rho = 0.8 W_Ldr = 0.5 W_T = 0.5 ENDELSE ; Now check for the other radar fields. If they're not present, then set ; their use to zero. ; Check for differential reflectivity field wh_dr = where(radar_names EQ 'DR') IF(wh_dr[0] GE 0) THEN DR = radar_data.DR ELSE fhc_vars.Zdr = 0 ; Check for specific differential phase. wh_kd = where(radar_names EQ 'KD') IF(wh_kd[0] GE 0) THEN KD = radar_data.KD ELSE fhc_vars.Kdp = 0 ; Check for linear depolarization ratio. wh_ld = where(radar_names EQ 'LD') IF(wh_ld[0] GE 0) THEN LD = radar_data.LD ELSE fhc_vars.LDR = 0 ; Check for correlation coefficient wh_rh = where(radar_names EQ 'RH') IF(wh_rh[0] GE 0) THEN RH = radar_data.RH ELSE fhc_vars.rho_hv = 0 ; Tell user which variables are being used. print,me+'Using variables:' print,tag_names(fhc_vars) print,fhc_vars ; Get all the beta function parameters. Zh_set=mbf_sets.Zh_set Zdr_set=mbf_sets.Zdr_set Kdp_set=mbf_sets.Kdp_set LDR_set=mbf_sets.LDR_set rho_set=mbf_sets.rho_set T_set=mbf_sets.T_set ;STOP ; Make an HID array of the same size as the radar data set. bad=-32767.0 ;STOP CASE size_radar[0] OF 0: BEGIN print,me+' Printing scores for given input data!' FHT=0.0 END 1:BEGIN FHT= INTARR(size_radar[1])*0-1. FHT2 = INTARR(size_radar[1])*0-1. END 2: BEGIN FHT= INTARR(size_radar[1],size_radar[2])*0-1. FHT2 = INTARR(size_radar[1],size_radar[2])*0-1. END 3: BEGIN FHT= INTARR(size_radar[1],size_radar[2],size_radar[3])*0-1. FHT2 = INTARR(size_radar[1],size_radar[2],size_radar[3])*0-1. END ELSE: BEGIN print,me+'Cowardly refusing to make a 4-D FHC array...returning.' RETURN,0 END ENDCASE ;STOP ; Define a flag indicating the presence of polarimetric variables. IF( (fhc_vars.Zdr) OR $ (fhc_vars.Kdp) OR $ (fhc_vars.LDR) OR $ (fhc_vars.rho_hv)) THEN pol_flag = 1 ELSE pol_flag =0 unclass_count = 0L ; to keep track of when more than one ; fuzzy set receives the same score. T_truth = 0 ; Whether to use temperature. IF( (Keyword_Set(use_temp))AND(fhc_vars.T)) THEN BEGIN T_truth = 1 print,me+'Using temperature in FHC' ENDIF ELSE print,me+'Not using temperature in FHC' ; Define the sum of the weighting ; factors, so we can normalize later. weight_sum = $ fhc_vars.Zdr*W_Zdr + $ fhc_vars.Kdp*W_Kdp + $ fhc_vars.LDR*W_ldr + $ fhc_vars.rho_hv*W_rho print,me+'Using hybrid method: Pol vars weighted, Zh and T (if used) will be multiplied.' ; For this case, do a weight sum of only ; the polarimetric variables and then ; multiply by the MBFs of Zh and temperature. CASE size_radar[0] OF 3: BEGIN ; 3-d input arrays. ; Initialize truth array. mu = DBLARR(size_radar[1],size_radar[2],size_radar[3]) FOR c=0,N_Elements(ZH_set.m)-1 DO BEGIN ; Loop over fuzzy sets. IF(pol_flag) THEN BEGIN mu=(fhc_vars.Zdr*W_Zdr*hid_beta(DR,$ Zdr_set.a[c],$ Zdr_set.b[c],$ Zdr_set.m[c])+$ fhc_vars.Kdp*W_Kdp*hid_beta(KD,$ Kdp_set.a[c],$ Kdp_set.b[c],$ Kdp_set.m[c])+$ fhc_vars.LDR*W_ldr*hid_beta(LD,$ LDR_set.a[c],$ LDR_set.b[c],$ LDR_set.m[c])+$ fhc_vars.rho_hv*W_rho*hid_beta(RH,$ rho_set.a[c],$ rho_set.b[c],$ rho_set.m[c]))/weight_sum ENDIF IF(T_truth) THEN BEGIN ; Multiply by temperature score. ; Have to calculate the MBF for ; temperature, level by level. ; If the pol_flag is set, then multiply by ; the weighted sum result. If not set, ; then don't multiply...just redefine. IF(pol_flag) THEN BEGIN ; print,"attempting to use T!" mu = mu*hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDIF ELSE BEGIN ; ENDS IF(pol_flag) mu = hid_beta(fhc_vars.T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDELSE ENDIF ; Multiply by DZ score. IF(fhc_vars.Zh) THEN BEGIN IF((pol_flag)OR(T_truth)) THEN $ mu = mu*hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c])$ ELSE $ ; Just define as truth value of DZ score. mu = hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c]) ENDIF ; ENDS IF(fhc_vars.Zh) ; Now determine if this fuzzy set held ; greater scores than the last fuzzy ; set. IF(c GT 0) THEN BEGIN ; Difference the current fuzzy set ; from the prior fuzzy set. mu_diff = mu - mu_best ; Find where the current fuzzy set ; returned a better score. wh_better = where(mu_diff GT 0.0) IF(wh_better[0] GE 0) THEN BEGIN ; Save the better scores to mu_last ; for comparison with the next iteration. mu_best[wh_better] = mu[wh_better] ; Save the fuzzy set of these better scores. FHT[wh_better] = c + 1 ENDIF mu_diffs=mu-mu_sec wh_betters=where(mu_diffs GE 0.0 AND mu_diff LE 0.0 AND mu ne 0.0) IF (wh_betters[0] GE 0) THEN BEGIN mu_sec[wh_betters]=mu[wh_betters] FHT2[wh_betters]=c+1 ; print,'Found points with second best score!' ENDIF ENDIF ELSE BEGIN mu_best = mu ; Save only those points that are ; significantly above zero for this ; first iteration. mu_sec=mu wh_large = where(mu GT 0.001) IF(wh_large[0] GE 0) THEN FHT[wh_large] = c +1 IF(wh_large[0] GE 0) THEN FHT2[wh_large]=c wh_small = where(mu LE 0.001) IF(wh_small[0] GE 0) THEN FHT[wh_small]= 0.0 IF(wh_small[0] GE 0) THEN FHT2[wh_small]=0.0 ENDELSE ENDFOR ; end c END ; ENDS 3-dimensional array case. ; 2-dimensional array. 2: BEGIN ; Initialize total truth array. mu = DBLARR(size_radar[1],size_radar[2]) FOR c=0,N_Elements(ZH_set.m)-1 DO BEGIN ; Loop over fuzzy sets. IF(pol_flag) THEN BEGIN mu = (fhc_vars.Zdr*W_Zdr*hid_beta(DR,$ Zdr_set.a[c],$ Zdr_set.b[c],$ Zdr_set.m[c])+$ fhc_vars.Kdp*W_Kdp*hid_beta(KD,$ Kdp_set.a[c],$ Kdp_set.b[c],$ Kdp_set.m[c])+$ fhc_vars.LDR*W_ldr*hid_beta(LD,$ LDR_set.a[c],$ LDR_set.b[c],$ LDR_set.m[c])+$ fhc_vars.rho_hv*W_rho*hid_beta(RH,$ rho_set.a[c],$ rho_set.b[c],$ rho_set.m[c]))/weight_sum ENDIF IF(T_truth) THEN BEGIN ; Determine what temperature to use. IF(pol_flag) THEN BEGIN mu = mu*hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDIF ELSE BEGIN ; ENDS IF(pol_flag) mu = hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDELSE ENDIF ; ENDS IF(T_truth) ; Multiply by DZ score. IF(fhc_vars.Zh) THEN BEGIN IF((pol_flag)OR(T_truth)) THEN $ mu = mu*hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c])$ ELSE $ mu = hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c]) ENDIF ; Now determine if this fuzzy set held ; greater scores than the last fuzzy ; set. IF(c GT 0) THEN BEGIN ; Difference the current fuzzy set ; from the prior fuzzy set. mu_diff = mu - mu_best ; Find where the current fuzzy set ; returned a better score. wh_better = where(mu_diff GT 0.0) IF(wh_better[0] GE 0) THEN BEGIN ; Save the better scores to mu_last ; for comparison with the next iteration. mu_best[wh_better] = mu[wh_better] ; Save the fuzzy set of these better scores. FHT[wh_better] = c + 1 ENDIF mu_diffs=mu-mu_sec wh_betters=where(mu_diffs GE 0.0 AND mu_diff LE 0.0 AND mu ne 0.0) IF (wh_betters[0] GE 0) THEN BEGIN mu_sec[wh_betters]=mu[wh_betters] FHT2[wh_betters]=c+1 ; print,'Found points with second best score!' ENDIF ENDIF ELSE BEGIN mu_best = mu ; Save only those points that are ; significantly above zero for this ; first iteration. mu_sec=mu wh_large = where(mu GT 0.001) IF(wh_large[0] GE 0) THEN FHT[wh_large] = c +1 IF(wh_large[0] GE 0) THEN FHT2[wh_large]=c wh_small = where(mu LE 0.001) IF(wh_small[0] GE 0) THEN FHT[wh_small]= 0.0 IF(wh_small[0] GE 0) THEN FHT2[wh_small]=0.0 ENDELSE ENDFOR ;end c END ; ENDS case of 2-dimensional data. 1: BEGIN ; Initialize total truth array. mu = DBLARR(size_radar[1]) FOR c=0,N_Elements(ZH_set.m)-1 DO BEGIN ; Loop over fuzzy sets. IF(pol_flag) THEN BEGIN mu = (fhc_vars.Zdr*W_Zdr*hid_beta(DR,$ Zdr_set.a[c],$ Zdr_set.b[c],$ Zdr_set.m[c])+$ fhc_vars.Kdp*W_Kdp*hid_beta(KD,$ Kdp_set.a[c],$ Kdp_set.b[c],$ Kdp_set.m[c])+$ fhc_vars.LDR*W_ldr*hid_beta(LD,$ LDR_set.a[c],$ LDR_set.b[c],$ LDR_set.m[c])+$ fhc_vars.rho_hv*W_rho*hid_beta(RH,$ rho_set.a[c],$ rho_set.b[c],$ rho_set.m[c]))/weight_sum ENDIF IF(T_truth) THEN BEGIN ; Determine what temperature to use. IF(pol_flag) THEN BEGIN mu = mu*hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDIF ELSE BEGIN ; ENDS IF(pol_flag) mu = hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDELSE ENDIF ; ENDS IF(T_truth) ; Multiply by DZ score. IF(fhc_vars.Zh) THEN BEGIN IF((pol_flag)OR(T_truth)) THEN $ mu = mu*hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c])$ ELSE $ mu = hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c]) ENDIF ; Now determine if this fuzzy set held ; greater scores than the last fuzzy ; set. IF(c GT 0) THEN BEGIN ; Difference the current fuzzy set ; from the prior fuzzy set. mu_diff = mu - mu_best ; Find where the current fuzzy set ; returned a better score. wh_better = where(mu_diff GT 0.0) IF(wh_better[0] GE 0) THEN BEGIN ; Save the better scores to mu_last ; for comparison with the next iteration. mu_best[wh_better] = mu[wh_better] ; Save the fuzzy set of these better scores. FHT[wh_better] = c + 1 ENDIF mu_diffs=mu-mu_sec wh_betters=where(mu_diffs GE 0.0 AND mu_diff LE 0.0 AND mu ne 0.0) IF (wh_betters[0] GE 0) THEN BEGIN mu_sec[wh_betters]=mu[wh_betters] FHT2[wh_betters]=c+1 ; print,'Found points with second best score!' ENDIF ENDIF ELSE BEGIN mu_best = mu ; Save only those points that are ; significantly above zero for this ; first iteration. mu_sec=mu wh_large = where(mu GT 0.001) IF(wh_large[0] GE 0) THEN FHT[wh_large] = c +1 IF(wh_large[0] GE 0) THEN FHT2[wh_large]=c wh_small = where(mu LE 0.001) IF(wh_small[0] GE 0) THEN FHT[wh_small]= 0.0 IF(wh_small[0] GE 0) THEN FHT2[wh_small]=0.0 ENDELSE ; STOP ENDFOR ;end c END ; ENDS case of 1-dimensional data. 0: BEGIN print, 'Just calculating scores for given input values' mu = DBLARR(N_Elements(ZH_set.m)) FOR c=0,N_Elements(ZH_set.m)-1 DO BEGIN ; Loop over fuzzy sets. IF(pol_flag) THEN BEGIN mu[c] = (fhc_vars.Zdr*W_Zdr*hid_beta(DR,$ Zdr_set.a[c],$ Zdr_set.b[c],$ Zdr_set.m[c])+$ fhc_vars.Kdp*W_Kdp*hid_beta(KD,$ Kdp_set.a[c],$ Kdp_set.b[c],$ Kdp_set.m[c])+$ fhc_vars.LDR*W_ldr*hid_beta(LD,$ LDR_set.a[c],$ LDR_set.b[c],$ LDR_set.m[c])+$ fhc_vars.rho_hv*W_rho*hid_beta(RH,$ rho_set.a[c],$ rho_set.b[c],$ rho_set.m[c]));/weight_sum ENDIF IF(T_truth) THEN BEGIN ; Determine what temperature to use. ; If it's an RHI, then use different ; temperature for each y. If it's ; a PPI, use the same temperature for all. IF(pol_flag) THEN BEGIN mu[c] = mu[c]+W_T*hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDIF ELSE BEGIN ; ENDS IF(pol_flag) mu[c] = W_T*hid_beta(T,$ T_set.a[c],$ T_set.b[c],$ T_set.m[c]) ENDELSE ENDIF ; ENDS IF(T_truth) ; Multiply by DZ score. IF(fhc_vars.Zh) THEN BEGIN IF((pol_flag)OR(T_truth)) THEN $ mu[c] = mu[c]+W_Zh*hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c])$ ELSE $ mu[c] = W_Zh*hid_beta(DZ,$ ZH_set.a[c],$ ZH_set.b[c],$ ZH_set.m[c]) ENDIF ; Now divide by the weight_sum for this type. mu[c]= mu[c]/weight_sum ENDFOR ;end c print,'Scores: ',mu RETURN,0 END ELSE: RETURN,0 ENDCASE ;;;Now set all the areas associated with 'bad' flags as -1. IF fhc_vars.Zh eq 1 THEN BEGIN wh_bad=where(DZ eq bad) IF wh_bad[0] gt -1 THEN BEGIN fht[wh_bad]=-1 fht2[wh_bad]=-1 mu[wh_bad]=0.0 mu_sec[wh_bad]=0.0 ENDIF ENDIF ELSE BEGIN IF pol_flag eq 1 THEN BEGIN wh_bad=where(DR eq bad or KD eq bad or RH eq bad) IF wh_bad[0] gt -1 THEN BEGIN fht[wh_bad]=-1 fht2[wh_bad]=-1 mu[wh_bad]=0.0 mu_sec[wh_bad]=0.0 ENDIF ENDIF ENDELSE print,me+'weight sum' print,weight_sum IF keyword_set(compare) THEN BEGIN fdat={FHT:FHT,FHT2:FHT2,mu_best:mu_best,mu_sec:mu_sec} RETURN,fdat ENDIF ELSE BEGIN RETURN,FHT ENDELSE END