1 ;********************************************************
2 ; using observed biome class
3 ; landfrac applied to area only.
5 ; required command line input parameters:
6 ; ncl 'model_name="10cn" model_grid="T42" dirm="/.../ film="..."' 01.npp.ncl
8 ; histogram normalized by rain and compute correleration
9 ;**************************************************************
10 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"
11 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_csm.ncl"
12 load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/contributed.ncl"
13 ;**************************************************************
14 procedure set_line(lines:string,nline:integer,newlines:string)
16 ; add line to ascci/html file
18 nnewlines = dimsizes(newlines)
19 if(nline+nnewlines-1.ge.dimsizes(lines))
20 print("set_line: bad index, not setting anything.")
23 lines(nline:nline+nnewlines-1) = newlines
24 ; print ("lines = " + lines(nline:nline+nnewlines-1))
25 nline = nline + nnewlines
28 ;**************************************************************
35 ;---------------------------------------------------
41 model_name1 = "i01.06cn"
42 model_name2 = "i01.10cn"
44 ;------------------------------------------------
45 ; read biome data: observed
47 biome_name_ob = "MODIS LandCover"
49 diro = "/fis/cgd/cseg/people/jeff/clamp_data/lai/ob/"
50 filo = "land_class_"+model_grid+".nc"
52 fo = addfile(diro+filo,"r")
54 classob = tofloat(fo->LAND_CLASS)
58 ; observed data has 20 land-type classes
62 ;---------------------------------------------------
63 ; get biome data: model
65 biome_name_mod = "Model PFT Class"
67 dirm = "/fis/cgd/cseg/people/jeff/clamp_data/model/"
68 film = "class_pft_"+model_grid+".nc"
69 fm = addfile(dirm+film,"r")
71 classmod = fm->CLASS_PFT
75 ; model data has 17 land-type classes
79 ;--------------------------------------------------
80 ; get model data: landmask, landfrac and area
82 dirm = "/fis/cgd/cseg/people/jeff/surface_data/"
84 fm = addfile (dirm+film,"r")
86 landmask = fm->landmask
87 landfrac = fm->landfrac
92 ; change area from km**2 to m**2
95 ;---------------------------------------------------
96 ; take into account landfrac
98 area = area * landfrac
100 ;----------------------------------------------------
101 ; read data: time series, model
103 dirm = "/fis/cgd/cseg/people/jeff/clamp_data/model/"
104 film = model_name2 + "_Fire_C_1979-2004_monthly.nc"
105 fm = addfile (dirm+film,"r")
107 data_mod = fm->COL_FIRE_CLOSS(18:25,:,:,:)
111 ; Units for these variables are:
114 ; change unit to g C/m^2/month
116 nsec_per_month = 60*60*24*30
118 data_mod = data_mod * nsec_per_month
120 data_mod@unit = "gC/m2/month"
121 ;----------------------------------------------------
122 ; read data: time series, observed
124 dirm = "/fis/cgd/cseg/people/jeff/fire_data/ob/GFEDv2_C/"
125 film = "Fire_C_1997-2006_monthly_"+ model_grid+".nc"
126 fm = addfile (dirm+film,"r")
128 data_ob = fm->FIRE_C(0:7,:,:,:)
134 ; Units for these variables are:
137 ;-------------------------------------------------------------
140 ; column (not including header column)
142 col_head = (/"Observed Fire_Flux (PgC/yr)" \
143 ,"Model Fire_Flux (PgC/yr)" \
144 ,"Correlation Coefficient" \
145 ,"Ratio model/observed" \
150 ncol = dimsizes(col_head)
152 ; row (not including header row)
154 ;----------------------------------------------------
155 ; using observed biome class:
156 row_head = (/"Evergreen Needleleaf Forests" \
157 ,"Evergreen Broadleaf Forests" \
158 ,"Deciduous Needleleaf Forest" \
159 ,"Deciduous Broadleaf Forests" \
161 ,"Closed Bushlands" \
163 ,"Woody Savannas (S. Hem.)" \
164 ,"Savannas (S. Hem.)" \
166 ,"Permanent Wetlands" \
168 ,"Cropland/Natural Vegetation Mosaic" \
169 ,"Barren or Sparsely Vegetated" \
170 ,"Woody Savannas (N. Hem.)" \
171 ,"Savannas (N. Hem.)" \
176 ; using model biome class:
177 ; row_head = (/"Not Vegetated" \
178 ; ,"Needleleaf Evergreen Temperate Tree" \
179 ; ,"Needleleaf Evergreen Boreal Tree" \
180 ;; ,"Needleleaf Deciduous Boreal Tree" \
181 ; ,"Broadleaf Evergreen Tropical Tree" \
182 ; ,"Broadleaf Evergreen Temperate Tree" \
183 ; ,"Broadleaf Deciduous Tropical Tree" \
184 ; ,"Broadleaf Deciduous Temperate Tree" \
185 ;; ,"Broadleaf Deciduous Boreal Tree" \
186 ;; ,"Broadleaf Evergreen Shrub" \
187 ; ,"Broadleaf Deciduous Temperate Shrub" \
188 ; ,"Broadleaf Deciduous Boreal Shrub" \
189 ; ,"C3 Arctic Grass" \
190 ; ,"C3 Non-Arctic Grass" \
196 nrow = dimsizes(row_head)
198 ; arrays to be passed to table.
199 text = new ((/nrow, ncol/),string )
201 ;*****************************************************************
203 ;*****************************************************************
205 x = dim_avg_Wrap(data_mod(lat|:,lon|:,month|:,year|:))
206 data_mod_m = dim_avg_Wrap( x(lat|:,lon|:,month|:))
209 x = dim_avg_Wrap( data_ob(lat|:,lon|:,month|:,year|:))
210 data_ob_m = dim_avg_Wrap( x(lat|:,lon|:,month|:))
213 ;----------------------------------------------------
214 ; compute correlation coef: space
216 landmask_1d = ndtooned(landmask)
217 data_mod_1d = ndtooned(data_mod_m)
218 data_ob_1d = ndtooned(data_ob_m )
219 area_1d = ndtooned(area)
220 landfrac_1d = ndtooned(landfrac)
222 good = ind(landmask_1d .gt. 0.)
224 global_mod = sum(data_mod_1d(good)*area_1d(good)) * 1.e-15 * 12.
225 global_ob = sum(data_ob_1d(good) *area_1d(good)) * 1.e-15 * 12.
230 global_area= sum(area_1d)
231 global_land= sum(area_1d(good))
235 cc_space = esccr(data_mod_1d(good)*landfrac_1d(good),data_ob_1d(good)*landfrac_1d(good),0)
244 ;----------------------------------------------------
249 Mscore1 = cc_space * cc_space * score_max
251 M_global = sprintf("%.2f", Mscore1)
253 ;----------------------------------------------------
256 resg = True ; Use plot options
257 resg@cnFillOn = True ; Turn on color fill
258 resg@gsnSpreadColors = True ; use full colormap
259 resg@cnLinesOn = False ; Turn off contourn lines
260 resg@mpFillOn = False ; Turn off map fill
261 resg@cnLevelSelectionMode = "ManualLevels" ; Manual contour invtervals
263 ;----------------------------------------------------
264 ; global contour: model vs ob
266 plot_name = "global_model_vs_ob"
268 wks = gsn_open_wks (plot_type,plot_name)
269 gsn_define_colormap(wks,"gui_default")
271 plot=new(3,graphic) ; create graphic array
273 resg@gsnFrame = False ; Do not draw plot
274 resg@gsnDraw = False ; Do not advance frame
276 ;----------------------
277 ; plot correlation coef
280 gRes@txFontHeightF = 0.02
283 correlation_text = "(correlation coef = "+sprintf("%.2f", cc_space)+")"
285 gsn_text_ndc(wks,correlation_text,0.20,0.50,gRes)
287 ;-----------------------
290 data_ob_m = where(landmask .gt. 0., data_ob_m, data_ob_m@_FillValue)
293 resg@tiMainString = title
295 resg@cnMinLevelValF = 1.
296 resg@cnMaxLevelValF = 10.
297 resg@cnLevelSpacingF = 1.
299 plot(0) = gsn_csm_contour_map_ce(wks,data_ob_m,resg)
301 ;-----------------------
304 data_mod_m = where(landmask .gt. 0., data_mod_m, data_mod_m@_FillValue)
306 title = "Model "+ model_name
307 resg@tiMainString = title
309 resg@cnMinLevelValF = 1.
310 resg@cnMaxLevelValF = 10.
311 resg@cnLevelSpacingF = 1.
313 plot(1) = gsn_csm_contour_map_ce(wks,data_mod_m,resg)
315 ;-----------------------
318 resg@cnMinLevelValF = -8.
319 resg@cnMaxLevelValF = 2.
320 resg@cnLevelSpacingF = 1.
323 zz = data_mod_m - data_ob_m
324 title = "Model_"+model_name+" - Observed"
325 resg@tiMainString = title
327 plot(2) = gsn_csm_contour_map_ce(wks,zz,resg)
331 pres = True ; panel plot mods desired
332 pres@gsnMaximize = True ; fill the page
334 gsn_panel(wks,plot,(/3,1/),pres) ; create panel plot
336 system("convert "+plot_name+"."+plot_type+" "+plot_name+"."+plot_type_new+";"+ \
337 "rm "+plot_name+"."+plot_type)
346 resg@gsnFrame = True ; Do advance frame
347 resg@gsnDraw = True ; Do draw plot
349 ;*******************************************************************
350 ; (B) Time series : per biome
351 ;*******************************************************************
355 dsizes = dimsizes(data_mod)
358 ntime = nyear * nmonth
363 ;-------------------------------------------
364 ; Calculate "nice" bins for binning the data
366 ; using ob biome class
368 ; using model biome class
369 ; nclass = nclass_mod
371 range = fspan(0,nclass,nclass+1)
373 ; Use this range information to grab all the values in a
374 ; particular range, and then take an average.
376 nx = dimsizes(range) - 1
378 ;-------------------------------------------
381 ; using observed biome class
382 base = ndtooned(classob)
383 ; using model biome class
384 ; base = ndtooned(classmod)
388 area_bin = new((/nx/),float)
389 yvalues = new((/ntime,data_n,nx/),float)
391 ; Loop through each range, using base.
395 if (i.ne.(nx-1)) then
396 idx = ind((base.ge.range(i)).and.(base.lt.range(i+1)))
398 idx = ind(base.ge.range(i))
400 ;---------------------
403 if (.not.any(ismissing(idx))) then
404 area_bin(i) = sum(area_1d(idx))
406 area_bin(i) = area_bin@_FillValue
409 ;#############################################################
410 ;using observed biome class:
411 ; set the following 4 classes to _FillValue:
412 ; Water Bodies(0), Urban and Build-Up(13),
413 ; Permenant Snow and Ice(15), Unclassified(17)
415 if (i.eq.0 .or. i.eq.13 .or. i.eq.15 .or. i.eq.17) then
416 area_bin(i) = yvalues@_FillValue
418 ;#############################################################
421 ;#############################################################
422 ; using model biome class:
423 ; set the following 4 classes to _FillValue:
424 ; (3)Needleleaf Deciduous Boreal Tree,
425 ; (8)Broadleaf Deciduous Boreal Tree,
426 ; (9)Broadleaf Evergreen Shrub,
429 ; if (i.eq.3 .or. i.eq.8 .or. i.eq.9 .or. i.eq.16) then
430 ; area_bin(i) = area_bin@_FillValue
432 ;#############################################################
434 ;---------------------
435 ; for data_mod and data_ob
446 data = ndtooned(data_ob(m,k,:,:))
450 data = ndtooned(data_mod(m,k,:,:))
455 if (.not.any(ismissing(idx))) then
456 yvalues(t,n,i) = sum(data(idx)*area_1d(idx))
458 yvalues(t,n,i) = yvalues@_FillValue
461 ;#############################################################
462 ;using observed biome class:
463 ; set the following 4 classes to _FillValue:
464 ; Water Bodies(0), Urban and Build-Up(13),
465 ; Permenant Snow and Ice(15), Unclassified(17)
467 if (i.eq.0 .or. i.eq.13 .or. i.eq.15 .or. i.eq.17) then
468 yvalues(t,n,i) = yvalues@_FillValue
470 ;#############################################################
473 ;#############################################################
474 ; using model biome class:
475 ; set the following 4 classes to _FillValue:
476 ; (3)Needleleaf Deciduous Boreal Tree,
477 ; (8)Broadleaf Deciduous Boreal Tree,
478 ; (9)Broadleaf Evergreen Shrub,
481 ; if (i.eq.3 .or. i.eq.8 .or. i.eq.9 .or. i.eq.16) then
482 ; yvalues(t,n,i) = yvalues@_FillValue
484 ;#############################################################
499 global_bin = sum(area_bin)
502 ;----------------------------------------------------------------
505 good = ind(.not.ismissing(area_bin))
507 area_g = area_bin(good)
509 n_biome = dimsizes(good)
511 global_good = sum(area_g)
514 ;----------------------------------------------------------------
515 ; data for tseries plot
517 yvalues_g = new((/ntime,data_n,n_biome/),float)
519 yvalues_g@units = "TgC/month"
521 ; change unit to Tg C/month
522 ; change unit from g to Tg (Tera gram)
525 yvalues_g = yvalues(:,:,good) * factor_unit
529 ;-------------------------------------------------------------------
530 ; general settings for line plot
533 res@xyDashPatterns = (/0,0/) ; make lines solid
534 res@xyLineThicknesses = (/2.0,2.0/) ; make lines thicker
535 res@xyLineColors = (/"blue","red"/) ; line color
537 res@trXMinF = year_start
538 res@trXMaxF = year_end + 1
540 res@vpHeightF = 0.4 ; change aspect ratio of plot
544 res@tiMainFontHeightF = 0.025 ; size of title
546 res@tmXBFormat = "f" ; not to add trailing zeros
548 ; res@gsnMaximize = True
550 ;----------------------------------------------
551 ; Add a boxed legend using the simple method
553 res@pmLegendDisplayMode = "Always"
554 ; res@pmLegendWidthF = 0.1
555 res@pmLegendWidthF = 0.08
556 res@pmLegendHeightF = 0.06
557 res@pmLegendOrthogonalPosF = -1.17
558 ; res@pmLegendOrthogonalPosF = -1.00 ;(downward)
559 ; res@pmLegendOrthogonalPosF = -0.30 ;(downward)
561 ; res@pmLegendParallelPosF = 0.18
562 res@pmLegendParallelPosF = 0.23 ;(rightward)
563 res@pmLegendParallelPosF = 0.73 ;(rightward)
564 res@pmLegendParallelPosF = 0.83 ;(rightward)
566 ; res@lgPerimOn = False
567 res@lgLabelFontHeightF = 0.015
568 res@xyExplicitLegendLabels = (/"observed",model_name/)
570 ;*******************************************************************
571 ; (A) time series plot: monthly ( 2 lines per plot)
572 ;*******************************************************************
574 ; x-axis in time series plot
576 timeI = new((/ntime/),integer)
577 timeF = new((/ntime/),float)
578 timeI = ispan(1,ntime,1)
579 timeF = year_start + (timeI-1)/12.
580 timeF@long_name = "year"
582 plot_data = new((/2,ntime/),float)
583 plot_data@long_name = "TgC/month"
585 ;----------------------------------------------
586 ; time series plot : per biome
590 plot_name = "monthly_biome_"+ m
592 wks = gsn_open_wks (plot_type,plot_name)
594 title = "Fire : "+ row_head(m)
595 res@tiMainString = title
597 plot_data(0,:) = yvalues_g(:,0,m)
598 plot_data(1,:) = yvalues_g(:,1,m)
600 plot = gsn_csm_xy(wks,timeF,plot_data,res)
602 system("convert "+plot_name+"."+plot_type+" "+plot_name+"."+plot_type_new+";"+ \
603 "rm "+plot_name+"."+plot_type)
610 ;------------------------------------------
611 ; data for table : per biome
613 ; unit change from TgC/month to PgC/month
618 tmp_ob = new((/ntime/),float)
619 tmp_mod = new((/ntime/),float)
621 total_ob = new((/n_biome/),float)
622 total_mod = new((/n_biome/),float)
623 Mscore2 = new((/n_biome/),float)
627 tmp_ob = yvalues_g(:,0,m)
628 tmp_mod = yvalues_g(:,1,m)
630 total_ob(m) = avg(month_to_annual(tmp_ob, 0)) * unit_factor
631 total_mod(m) = avg(month_to_annual(tmp_mod,0)) * unit_factor
633 cc_time = esccr(tmp_mod,tmp_ob,0)
635 ratio = total_mod(m)/total_ob(m)
637 good = ind(tmp_ob .ne. 0. .and. tmp_mod .ne. 0.)
639 bias = sum( abs( tmp_mod(good)-tmp_ob(good) )/( abs(tmp_mod(good))+abs(tmp_ob(good)) ) )
640 Mscore2(m) = (1.- (bias/dimsizes(good)))*score_max
644 text(m,0) = sprintf("%.2f",total_ob(m))
645 text(m,1) = sprintf("%.2f",total_mod(m))
646 text(m,2) = sprintf("%.2f",cc_time)
647 text(m,3) = sprintf("%.2f",ratio)
648 text(m,4) = sprintf("%.2f",Mscore2(m))
649 text(m,5) = "<a href=./monthly_biome_"+m+".png>model_vs_ob</a>"
655 ;--------------------------------------------
656 ; time series plot: all biome
658 plot_name = "monthly_global"
660 wks = gsn_open_wks (plot_type,plot_name)
662 title = "Fire : "+ row_head(n_biome)
663 res@tiMainString = title
666 plot_data(0,k) = sum(yvalues_g(k,0,:))
667 plot_data(1,k) = sum(yvalues_g(k,1,:))
670 plot = gsn_csm_xy(wks,timeF,plot_data,res)
672 system("convert "+plot_name+"."+plot_type+" "+plot_name+"."+plot_type_new+";"+ \
673 "rm "+plot_name+"."+plot_type)
678 ;------------------------------------------
679 ; data for table : global
683 tmp_ob = ndtooned(yvalues_g(:,0,:))
684 tmp_mod = ndtooned(yvalues_g(:,1,:))
686 cc_time = esccr(tmp_mod,tmp_ob,0)
688 ratio = sum(total_mod)/sum(total_ob)
690 good = ind(tmp_ob .ne. 0. .and. tmp_mod .ne. 0.)
692 bias = sum( abs( tmp_mod(good)-tmp_ob(good) )/( abs(tmp_mod(good))+abs(tmp_ob(good)) ) )
693 Mscore3 = (1.- (bias/dimsizes(good)))*score_max
699 text(nrow-1,0) = sprintf("%.2f",sum(total_ob))
700 text(nrow-1,1) = sprintf("%.2f",sum(total_mod))
701 text(nrow-1,2) = sprintf("%.2f",cc_time)
702 text(nrow-1,3) = sprintf("%.2f",ratio)
703 ; text(nrow-1,4) = sprintf("%.2f",avg(Mscore2))
704 text(nrow-1,4) = sprintf("%.2f", Mscore3)
705 text(nrow-1,5) = "<a href=./monthly_global.png>model_vs_ob</a>"
707 ;**************************************************
709 ;**************************************************
711 header_text = "<H1>Fire Emission (1997-2004): Model "+model_name+"</H1>"
713 header = (/"<HTML>" \
715 ,"<TITLE>CLAMP metrics</TITLE>" \
722 "<table border=1 cellspacing=0 cellpadding=3 width=60%>" \
724 ," <th bgcolor=DDDDDD >Biome Type</th>" \
725 ," <th bgcolor=DDDDDD >"+col_head(0)+"</th>" \
726 ," <th bgcolor=DDDDDD >"+col_head(1)+"</th>" \
727 ," <th bgcolor=DDDDDD >"+col_head(2)+"</th>" \
728 ," <th bgcolor=DDDDDD >"+col_head(3)+"</th>" \
729 ," <th bgcolor=DDDDDD >"+col_head(4)+"</th>" \
730 ," <th bgcolor=DDDDDD >"+col_head(5)+"</th>" \
733 table_footer = "</table>"
737 lines = new(50000,string)
740 set_line(lines,nline,header)
741 set_line(lines,nline,table_header)
742 ;-----------------------------------------------
746 set_line(lines,nline,row_header)
756 set_line(lines,nline,"<th>"+txt0+"</th>")
757 set_line(lines,nline,"<th>"+txt1+"</th>")
758 set_line(lines,nline,"<th>"+txt2+"</th>")
759 set_line(lines,nline,"<th>"+txt3+"</th>")
760 set_line(lines,nline,"<th>"+txt4+"</th>")
761 set_line(lines,nline,"<th>"+txt5+"</th>")
762 set_line(lines,nline,"<th>"+txt6+"</th>")
764 set_line(lines,nline,row_footer)
766 ;-----------------------------------------------
767 set_line(lines,nline,table_footer)
768 set_line(lines,nline,footer)
770 ; Now write to an HTML file.
772 output_html = "table_fire.html"
774 idx = ind(.not.ismissing(lines))
775 if(.not.any(ismissing(idx))) then
776 asciiwrite(output_html,lines(idx))