|         |      1 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl" | 
|         |      2 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl" | 
|         |      3  | 
|         |      4 procedure pminmax(data:numeric,name:string) | 
|         |      5 begin | 
|         |      6   print ("min/max " + name + " = " + min(data) + "/" + max(data)) | 
|         |      7   if(isatt(data,"units")) then | 
|         |      8     print (name + " units = " + data@units) | 
|         |      9   end if | 
|         |     10 end | 
|         |     11  | 
|         |     12 ; | 
|         |     13 ; Main code. | 
|         |     14 ; | 
|         |     15 begin | 
|         |     16   data_types    = (/ "Obs",        "Model"       /) | 
|         |     17   data_names    = (/ "data.81.nc", "i01.03cn_1545-1569_ANN_climo.nc" /) | 
|         |     18 ; data_names    = (/ "data.81.nc", "i01.04casa_1605-1629_ANN_climo.nc" /) | 
|         |     19   filevar_names = (/ (/"PREC_ANN","TNPP_C"/), (/"RAIN","NPP"/) /) | 
|         |     20   ndata_types   = dimsizes(data_types) | 
|         |     21  | 
|         |     22   data_file_obs = addfile(data_names(0),"r")    ; Open obs file | 
|         |     23   data_file_mod = addfile(data_names(1),"r")    ; Open model file | 
|         |     24  | 
|         |     25 ; | 
|         |     26 ; Read four variables from files. | 
|         |     27 ; | 
|         |     28   PREC_ANN = tofloat(data_file_obs->PREC_ANN) | 
|         |     29   TNPP_C   = data_file_obs->TNPP_C | 
|         |     30   RAIN     = data_file_mod->RAIN | 
|         |     31   NPP    = data_file_mod->NPP | 
|         |     32 ; | 
|         |     33 ; Units for these four variables are: | 
|         |     34 ; | 
|         |     35 ; PREC_ANN : mm/year | 
|         |     36 ; TNPP_C   : g C/m^2/year | 
|         |     37 ; RAIN     : mm/s | 
|         |     38 ; NPP    : g C/m^2/s | 
|         |     39 ; | 
|         |     40 ; We want to convert these to "m/year" and "g C/m^2/year". | 
|         |     41 ; | 
|         |     42   nsec_per_year = 60*60*24*365                  ; # seconds per year | 
|         |     43  | 
|         |     44 ; Do the necessary conversions. | 
|         |     45   PREC_ANN = PREC_ANN / 1000. | 
|         |     46   RAIN     = (RAIN / 1000.) * nsec_per_year | 
|         |     47   NPP    = NPP * nsec_per_year | 
|         |     48  | 
|         |     49 ; Redo the units. | 
|         |     50   PREC_ANN@units = "m/yr" | 
|         |     51   RAIN@units     = "m/yr" | 
|         |     52   NPP@units    = "gC/m^2/yr" | 
|         |     53   TNPP_C@units   = "gC/m^2/yr" | 
|         |     54  | 
|         |     55   pminmax(PREC_ANN,"PREC_ANN") | 
|         |     56   pminmax(TNPP_C,"TNPP_C") | 
|         |     57   pminmax(RAIN,"RAIN") | 
|         |     58   pminmax(NPP,"NPP") | 
|         |     59  | 
|         |     60   RAIN_1D     = ndtooned(RAIN) | 
|         |     61   NPP_1D    = ndtooned(NPP) | 
|         |     62   PREC_ANN_1D = ndtooned(PREC_ANN) | 
|         |     63   TNPP_C_1D   = ndtooned(TNPP_C) | 
|         |     64  | 
|         |     65 ; | 
|         |     66 ; Calculate some "nice" bins for binning the data in equally spaced | 
|         |     67 ; ranges. | 
|         |     68 ; | 
|         |     69   nbins       = 15     ; Number of bins to use. | 
|         |     70  | 
|         |     71   nicevals    = nice_mnmxintvl(min(RAIN_1D),max(RAIN_1D),nbins,True) | 
|         |     72   nvals       = floattoint((nicevals(1) - nicevals(0))/nicevals(2) + 1) | 
|         |     73   range       = fspan(nicevals(0),nicevals(1),nvals) | 
|         |     74 ; | 
|         |     75 ; Use this range information to grab all the values in a | 
|         |     76 ; particular range, and then take an average. | 
|         |     77 ; | 
|         |     78   nr      = dimsizes(range) | 
|         |     79   nx      = nr-1 | 
|         |     80   xvalues     = new((/2,nx/),typeof(RAIN_1D)) | 
|         |     81   xvalues(0,:) = range(0:nr-2) + (range(1:)-range(0:nr-2))/2. | 
|         |     82   dx           = xvalues(0,1) - xvalues(0,0)       ; range width | 
|         |     83   dx4          = dx/4                              ; 1/4 of the range | 
|         |     84   xvalues(1,:) = xvalues(0,:) - dx/5. | 
|         |     85   yvalues      = new((/2,nx/),typeof(RAIN_1D)) | 
|         |     86   mn_yvalues   = new((/2,nx/),typeof(RAIN_1D)) | 
|         |     87   mx_yvalues   = new((/2,nx/),typeof(RAIN_1D)) | 
|         |     88  | 
|         |     89   do nd=0,1 | 
|         |     90 ; | 
|         |     91 ; See if we are doing model or observational data. | 
|         |     92 ; | 
|         |     93     if(nd.eq.0) then | 
|         |     94       data     = PREC_ANN_1D | 
|         |     95       npp_data = TNPP_C_1D | 
|         |     96     else | 
|         |     97       data     = RAIN_1D | 
|         |     98       npp_data = NPP_1D | 
|         |     99     end if | 
|         |    100 ; | 
|         |    101 ; Loop through each range and check for values. | 
|         |    102 ; | 
|         |    103     do i=0,nr-2 | 
|         |    104       if (i.ne.(nr-2)) then | 
|         |    105         print("") | 
|         |    106         print("In range ["+range(i)+","+range(i+1)+")") | 
|         |    107         idx = ind((range(i).le.data).and.(data.lt.range(i+1))) | 
|         |    108       else | 
|         |    109         print("") | 
|         |    110         print("In range ["+range(i)+",)") | 
|         |    111         idx = ind(range(i).le.data) | 
|         |    112       end if | 
|         |    113 ; | 
|         |    114 ; Calculate average, and get min and max. | 
|         |    115 ; | 
|         |    116       if(.not.any(ismissing(idx))) then | 
|         |    117         yvalues(nd,i)    = avg(npp_data(idx)) | 
|         |    118         mn_yvalues(nd,i) = min(npp_data(idx)) | 
|         |    119         mx_yvalues(nd,i) = max(npp_data(idx)) | 
|         |    120         count = dimsizes(idx) | 
|         |    121       else | 
|         |    122         count            = 0 | 
|         |    123         yvalues(nd,i)    = yvalues@_FillValue | 
|         |    124         mn_yvalues(nd,i) = yvalues@_FillValue | 
|         |    125         mx_yvalues(nd,i) = yvalues@_FillValue | 
|         |    126       end if | 
|         |    127 ; | 
|         |    128 ; Print out information. | 
|         |    129 ; | 
|         |    130       print(data_types(nd) + ": " + count + " points, avg = " + yvalues(nd,i)) | 
|         |    131       print("Min/Max:  " + mn_yvalues(nd,i) + "/" + mx_yvalues(nd,i)) | 
|         |    132  | 
|         |    133 ; | 
|         |    134 ; Clean up for next time in loop. | 
|         |    135 ; | 
|         |    136       delete(idx) | 
|         |    137     end do | 
|         |    138     delete(data) | 
|         |    139     delete(npp_data) | 
|         |    140   end do | 
|         |    141  | 
|         |    142   xvalues@long_name = "Mean Annual precipitation (m/year)" | 
|         |    143   yvalues@long_name = "NPP (g C/m2/year)"                  | 
|         |    144   | 
|         |    145 ; | 
|         |    146 ; Start the graphics. | 
|         |    147 ; | 
|         |    148 ; wks = gsn_open_wks("x11","npp") | 
|         |    149   wks = gsn_open_wks("png","npp") | 
|         |    150  | 
|         |    151   res             = True | 
|         |    152   res@tiMainString = "Observed vs i01.03cn" | 
|         |    153 ; res@tiMainString = "Observed vs i01.04casa" | 
|         |    154   res@gsnMaximize = False | 
|         |    155   res@gsnDraw     = False | 
|         |    156   res@gsnFrame    = False | 
|         |    157   res@xyMarkLineMode = "Markers" | 
|         |    158   res@xyMarkerSizeF   = 0.014 | 
|         |    159   res@xyMarker       = 16 | 
|         |    160 ; res@xyMarkerColors = (/"Gray25","Gray50"/) | 
|         |    161   res@xyMarkerColors = (/"brown","blue"/) | 
|         |    162   res@trYMinF        = min(mn_yvalues) - 10. | 
|         |    163   res@trYMaxF        = max(mx_yvalues) + 10. | 
|         |    164  | 
|         |    165   xy = gsn_csm_xy(wks,xvalues,yvalues,res) | 
|         |    166  | 
|         |    167   max_bar = new((/2,nx/),graphic) | 
|         |    168   min_bar = new((/2,nx/),graphic) | 
|         |    169   max_cap = new((/2,nx/),graphic) | 
|         |    170   min_cap = new((/2,nx/),graphic) | 
|         |    171  | 
|         |    172   lnres = True | 
|         |    173  | 
|         |    174   line_colors = (/"brown","blue"/) | 
|         |    175   do nd=0,1 | 
|         |    176     lnres@gsLineColor = line_colors(nd) | 
|         |    177     do i=0,nx-1 | 
|         |    178       | 
|         |    179       if(.not.ismissing(mn_yvalues(nd,i)).and. \ | 
|         |    180          .not.ismissing(mx_yvalues(nd,i))) then | 
|         |    181 ; | 
|         |    182 ; Attach the vertical bar, both above and below the marker. | 
|         |    183 ; | 
|         |    184         x1 = xvalues(nd,i) | 
|         |    185         y1 = yvalues(nd,i) | 
|         |    186         y2 = mn_yvalues(nd,i) | 
|         |    187         min_bar(nd,i) = gsn_add_polyline(wks,xy,(/x1,x1/),(/y1,y2/),lnres) | 
|         |    188  | 
|         |    189         y2 = mx_yvalues(nd,i) | 
|         |    190         max_bar(nd,i) = gsn_add_polyline(wks,xy,(/x1,x1/),(/y1,y2/),lnres) | 
|         |    191 ; | 
|         |    192 ; Attach the horizontal cap line, both above and below the marker. | 
|         |    193 ; | 
|         |    194         x1 = xvalues(nd,i) - dx4 | 
|         |    195         x2 = xvalues(nd,i) + dx4 | 
|         |    196         y1 = mn_yvalues(nd,i) | 
|         |    197         min_cap(nd,i) = gsn_add_polyline(wks,xy,(/x1,x2/),(/y1,y1/),lnres) | 
|         |    198  | 
|         |    199         y1 = mx_yvalues(nd,i) | 
|         |    200         max_cap(nd,i) = gsn_add_polyline(wks,xy,(/x1,x2/),(/y1,y1/),lnres) | 
|         |    201       end if | 
|         |    202     end do | 
|         |    203   end do | 
|         |    204  | 
|         |    205   draw(xy) | 
|         |    206   frame(wks) | 
|         |    207  | 
|         |    208 end | 
|         |    209  |