Soil Water Balance (SWB2)
Loading...
Searching...
No Matches
swbstats2.F90
Go to the documentation of this file.
1program swbstats2
2
3 use iso_c_binding
7 use exceptions, only : assert, die
8 use datetime, only : datetime_t, assignment(=), operator(>)
9 use grid
12 use fstring_list, only : fstring_list_t, &
14 use fstring
15 use version_control, only : swb_version, git_commit_hash_string, &
16 git_branch_string, compile_date, &
17 compile_time, system_name
18
19 use iso_fortran_env, only : output_unit, compiler_options, &
20 compiler_version
21
23 implicit none
24
25 character (len=256) :: command_arg_str
26 character (len=256) :: temp_string, sub_string
27 character (len=70), allocatable :: usage_string(:)
28
29 integer (c_int) :: inumargs
30 character (len=1024) :: scompilerflags
31 character (len=256) :: scompilerversion
32 character (len=256) :: sversionstring
33 character (len=256) :: sgithashstring
34 character (len=256) :: sprogramname
35 character (len=256) :: scompilationdatestring
36 character (len=256) :: scompilationsystemstring
37 character (len=:), allocatable :: start_date_string
38 character (len=:), allocatable :: end_date_string
39 integer (c_int) :: icount
40 integer (c_int) :: iindex
41 integer (c_int), allocatable ::iindex_array(:)
42 integer (c_int) :: ilen
43 real (c_double) :: start_date_dbl
44 real (c_double) :: end_date_dbl
45 integer (c_int) :: time_bnds_varid
46 integer (c_int) :: month_index
47
48 logical (c_bool) :: netcdf_active = false
49
50 type (fstring_list_t) :: name_list
51 type (fstring_list_t) :: value_list
52
53 type (swbstats_t) :: swbstats
54
55 allocate( swbstats%ncfile_in )
56
57 inumargs = command_argument_count()
58
59 sprogramname = " SWB Statistics Calculator (SWBSTATS2), a companion to"
60 sversionstring = " Soil Water Balance Code version "//trim( swb_version )
61 scompilationdatestring = " compilation date : " &
62 //trim(compile_date)//" "//trim(compile_time)
63 scompilationsystemstring = " compiled on : "//trim(system_name)
64
65 if ( (system_name .containssimilar. "Windows") &
66 .or. (system_name .containssimilar. "Mingw") ) then
68 else
70 endif
71
72 sgithashstring = " Git branch and commit hash : " &
73 //trim( adjustl(git_branch_string ) ) &
74 //", "//trim( git_commit_hash_string )
75
76 icount = max( len_trim( sversionstring ), len_trim( sgithashstring ) )
77 icount = max( icount, len_trim( scompilationsystemstring ) )
78 icount = max( icount, len_trim( sprogramname) )
79
80 write(unit=*, fmt="(/,a)") repeat("-",icount + 4)
81 write(unit=*, fmt="(a,/)") trim( sprogramname )
82 write(unit=*,fmt="(a,/)") trim( sversionstring )
83 write(unit=*,fmt="(a)") trim( scompilationdatestring )
84 write(unit=*,fmt="(a)") trim( scompilationsystemstring )
85 write(unit=*,fmt="(a)") trim( sgithashstring )
86 write(unit=*, fmt="(a,/)") repeat("-",icount + 4)
87
88 if(inumargs == 0 ) then
89
90#ifdef __GFORTRAN__l
91 scompilerflags = compiler_options()
92 scompilerversion = compiler_version()
93 write(unit=*,fmt="(a,/)") "Compiled with: gfortran ("//trim(scompilerversion)//")"
94 write(unit=*,fmt="(a)") "Compiler flags:"
95 write(unit=*,fmt="(a)") "-------------------------------"
96 write(unit=*,fmt="(a,/)") trim(scompilerflags)
97#endif
98
99#ifdef __INTEL_COMPILER
100 write(unit=*,fmt="(a)") "Compiled with: Intel Fortran version " &
101 //trim(ascharacter(__intel_compiler))
102 write(unit=*,fmt="(a,/)") "Compiler build date:"//trim(ascharacter(__intel_compiler_build_date))
103#endif
104
105 allocate(usage_string(50))
106
107 usage_string = [ &
108 "usage: swbstats2 [options] netcdf_file_name ", &
109 " ", &
110 " options: ", &
111 " ", &
112 " [ --output_prefix= ] ", &
113 " text to place in front of the default output filename(s) ", &
114 " [ --annual_statistics ] ", &
115 " calculate statistics for every calendar year between start and end", &
116 " [ --monthly_statistics ] ", &
117 " calculate statistics for every month between start and end ", &
118 " [ --daily_statistics ] ", &
119 " calculate statistics for every day between start and end ", &
120 " [ --annualize_sums ] ", &
121 " express sums on an annual basis (e.g. inches per year) ", &
122 " [ --report_as_volume ] ", &
123 " express statistics as a volume (cubic meters) ", &
124 " [ --report_in_meters ] ", &
125 " express output statistics in *meters* ", &
126 " [ --slice= ] ", &
127 " dates over which statistics should be calculated, ", &
128 " with start date and end date formatted as yyyy-mm-dd,yyyy-mm-dd ", &
129 " [ --stress_period_file= ] ", &
130 " comma-delimited file containing stress period start and ", &
131 " end date, with header labels and comments starting with'#': ", &
132 " id,start_date,end_date ", &
133 " #2,1870-01-01,1898-12-31 ", &
134 " 5,1920-01-01,1925-12-31 ", &
135 " 6,1925-01-01,1930-12-31 ", &
136 " [ --comparison_scale_factor= ] ", &
137 " value to multiply comparison grid by before calculating statistics", &
138 " [ --comparison_grid= ] ", &
139 " name of real-valued grid to compare SWB output against ", &
140 " [ --comparison_period_file= ] ", &
141 " comma-delimited file containing comparison period start and ", &
142 " end date, with header labels and comments starting with'#': ", &
143 " id,start_date,end_date,comparison_grid_filename ", &
144 " #2,1870-01-01,1898-12-31,comparison_file_period_2.asc ", &
145 " 5,1920-01-01,1925-12-31,comparison_file_period_5.asc ", &
146 " 6,1925-01-01,1930-12-31,comparison_file_period_6.asc ", &
147 " [ --zone_grid= ] ", &
148 " name of integer-valued grid for which zonal statistics are desired", &
149 " [ --zone_period_file= ] ", &
150 " comma-delimited file containing calculation period start and ", &
151 " end date, with header labels and comments starting with'#': ", &
152 " id,start_date,end_date,zone_grid_filename ", &
153 " #2,1870-01-01,1898-12-31,zone_grid_file_period_2.asc ", &
154 " 5,1920-01-01,1925-12-31,zone_grid_file_period_5.asc ", &
155 " 6,1925-01-01,1930-12-31,zone_grid_file_period_6.asc ", &
156 " [ --{no_}netcdf_output ] ", &
157 " toggle whether netCDF file is target for gridded output ", &
158 " [ --{no_}arcgrid_output ] ", &
159 " toggle whether an ASCII Arc Grid is target for gridded output " &
160 ]
161
162 do iindex=1,ubound(usage_string,1)
163 write(unit=*, fmt="(a)") trim(usage_string(iindex))
164 enddo
165
166 stop
167
168 end if
169
170 output_files(stats_sum)%output_active = true
171 output_files(stats_mean)%output_active = true
172
173 call swbstats%slice_start_date%setDateFormat("YYYY-MM-DD")
174 call swbstats%slice_end_date%setDateFormat("YYYY-MM-DD")
175 swbstats%filename_modifier_string = ""
176
177 do iindex=1, inumargs
178
179 call get_command_argument( iindex, command_arg_str )
180
181 if ( command_arg_str .containssimilar. "comparison_scale_factor" ) then
182
183 sub_string = right(command_arg_str, substring="=")
184 swbstats%comparison_grid_conversion_factor = asfloat(sub_string)
185
186 elseif ( command_arg_str .containssimilar. "output_prefix" ) then
187
188 sub_string = right(command_arg_str, substring="=")
189 swbstats%output_file_prefix = trim(sub_string)
190
191 elseif ( command_arg_str .containssimilar. "annual_statistics" ) then
192
193 swbstats%calculation_time_period = calc_period_annual
194 swbstats%filename_modifier_string = "YEARLY"
195
196 elseif ( command_arg_str .containssimilar. "daily_statistics" ) then
197
198 swbstats%calculation_time_period = calc_period_daily
199 swbstats%filename_modifier_string = "DAILY"
200
201 elseif ( command_arg_str .containssimilar. "monthly_statistics" ) then
202
203 swbstats%calculation_time_period = calc_period_monthly
204 swbstats%filename_modifier_string = "MONTHLY"
205
206 elseif ( command_arg_str .containssimilar. "dump_options" ) then
207
208 swbstats%dump_options_to_screen = true
209
210 elseif ( command_arg_str .containssimilar. "report_as_volume" ) then
211
212 swbstats%report_as_volume = true
213
214 elseif ( command_arg_str .containssimilar. "report_in_meters" ) then
215
216 swbstats%report_in_meters = true
217
218 elseif ( command_arg_str .containssimilar. "annualize_sums" ) then
219
220 swbstats%annualize_stats = true
221
222 elseif ( command_arg_str .containssimilar. "stress_period_file" ) then
223
224 swbstats%calculation_time_period = calc_period_slice_multiple
225 swbstats%stress_period_filename = right(command_arg_str, substring="=")
226 call swbstats%read_date_range_file( &
227 csv_filename=swbstats%stress_period_filename, &
228 date_range_id_list=swbstats%date_range_id_list, &
229 start_date_list=swbstats%start_date_list, &
230 end_date_list=swbstats%end_date_list )
231 swbstats%filename_modifier_string = "STRESS_PERIOD_STATS"
232
233 elseif ( command_arg_str .containssimilar. "zone_period_file" ) then
234
235 swbstats%calculation_time_period = calc_period_slice_multiple
236 swbstats%multiple_zone_grids = true
237 swbstats%calc_zonal_stats = true
238 swbstats%write_csv = true
239
240 swbstats%zone_period_filename = right(command_arg_str, substring="=")
241 call swbstats%read_zone_period_file( &
242 csv_filename=swbstats%zone_period_filename , &
243 date_range_id_list=swbstats%date_range_id_list, &
244 start_date_list=swbstats%start_date_list, &
245 end_date_list=swbstats%end_date_list, &
246 zonal_stats_grid_file_list=swbstats%zone_grid_file_list )
247
248 elseif ( command_arg_str .containssimilar. "comparison_period_file" ) then
249
250 swbstats%calculation_time_period = calc_period_slice_multiple
251 swbstats%multiple_comparison_grids = true
252 swbstats%compare_to_obs_values = true
253 swbstats%write_csv = true
254 swbstats%filename_modifier_string = "COMPARISON_PERIOD_STATS"
255
256 swbstats%comparison_period_filename = right(command_arg_str, substring="=")
257 call swbstats%read_comparison_period_file( &
258 csv_filename=swbstats%comparison_period_filename, &
259 date_range_id_list=swbstats%date_range_id_list, &
260 start_date_list=swbstats%start_date_list, &
261 end_date_list=swbstats%end_date_list, &
262 comparison_grid_file_list=swbstats%comparison_grid_file_list )
263
264 elseif ( command_arg_str .containssimilar. "slice" ) then
265
266 sub_string = right(command_arg_str, substring="=")
267 start_date_string = left(sub_string, substring=",")
268 end_date_string = right(sub_string, substring=",")
269
270 swbstats%calculation_time_period = calc_period_slice_single
271
272 call swbstats%slice_start_date%parseDate(start_date_string)
273 call swbstats%slice_start_date%calcGregorianDate()
274
275 call swbstats%slice_end_date%parseDate(end_date_string)
276 call swbstats%slice_end_date%calcGregorianDate()
277 swbstats%filename_modifier_string = "SLICE_STATS--" &
278 //swbstats%slice_start_date%prettydate()//"_to_" &
279 //swbstats%slice_end_date%prettydate()
280
281 elseif ( command_arg_str .containssimilar. "zone_grid=" ) then
282
283 swbstats%zone_grid_filename = right(command_arg_str, substring="=")
284 swbstats%calc_zonal_stats = true
285 swbstats%write_csv = true
286
287 elseif ( command_arg_str .containssimilar. "zone_grid2=" ) then
288
289 swbstats%zone_grid2_filename = right(command_arg_str, substring="=")
290 swbstats%calc_zonal_stats = true
291 swbstats%write_csv = true
292
293 elseif ( command_arg_str .containssimilar. "comparison_grid" ) then
294
295 swbstats%comparison_grid_filename = right(command_arg_str, substring="=")
296 swbstats%compare_to_obs_values = true
297 swbstats%write_csv = true
298
299 elseif ( command_arg_str .strapprox. "--netcdf_output") then
300
301 output_files%write_netcdf = true
302
303 elseif ( command_arg_str .strapprox. "--no_netcdf_output" ) then
304
305 output_files%write_netcdf = false
306
307 elseif ( command_arg_str .strapprox. "--arcgrid_output" ) then
308
309 output_files%write_arcgrid = true
310
311 elseif ( command_arg_str .strapprox. "--no_arcgrid_output" ) then
312
313 output_files%write_arcgrid = false
314
315 elseif ( command_arg_str .contains. "--" ) then
316
317 ! ifort barfs if 'sQuote' embedded in stop statement. revert to print *
318 print *, "Unknown swbstats2 option: "//squote(command_arg_str)//"."
319 stop
320
321 else
322
323 ! no match on the command-line argument flags; must be the netCDF file
324 swbstats%netcdf_input_filename = trim(command_arg_str)
325
326 call netcdf_open_and_prepare_for_merging( swbstats%ncfile_in, &
327 swbstats%netcdf_input_filename, &
328 guess_z_var_name=true )
329
330 ! extract integer start and end Julian dates from netCDF file
331 start_date_dbl = real( swbstats%ncfile_in%iFirstDayJD, c_double )
332 end_date_dbl = real( swbstats%ncfile_in%iLastDayJD, c_double )
333
334 ! populate datetime data structure
335 call swbstats%data_start_date%setJulianDate(start_date_dbl)
336 call swbstats%data_start_date%calcGregorianDate()
337 call swbstats%data_end_date%setJulianDate(end_date_dbl)
338 call swbstats%data_end_date%calcGregorianDate()
339
340 swbstats%netcdf_input_file_is_open = true
341
342 endif
343
344 enddo
345
346 if (.not. swbstats%netcdf_input_file_is_open) &
347 stop("No netCDF file was specified or there was an error opening the file.")
348
349!----------------------------------------------------------------------------
350! end of argument processing; now take action based on the options selected
351!----------------------------------------------------------------------------
352
353 ! get the attributes associated with the coordinate reference system (CRS) variable
354 call netcdf_get_attribute_list_for_variable( ncfile=swbstats%ncfile_in, &
355 variable_name="crs", &
356 attribute_name_list=name_list, &
357 attribute_value_list=value_list )
358
359 ! extract PROJ4 string from netCDF file
360 iindex_array = name_list%which("proj4_string")
361 temp_string = value_list%get( iindex_array(1) )
362 swbstats%target_proj4_string = trim(temp_string)
363
364 swbstats%netcdf_variable_name_string = trim(swbstats%ncfile_in%pNC_VAR(nc_z)%sVariableName)
365
366 ! get the attributes associated with the SWB2 output variable
368 ncfile=swbstats%ncfile_in, &
369 variable_name=swbstats%netcdf_variable_name_string, &
370 attribute_name_list=name_list, &
371 attribute_value_list=value_list )
372
373 ! extract units description string from netCDF file
374 iindex_array = name_list%which("units")
375 swbstats%netcdf_variable_units_string = value_list%get( iindex_array(1) )
376
377 ! create working grids with dimensions extracted from netCDF file being munged
378 call swbstats%create_working_grids()
379
380 call rstat%initialize(nx=swbstats%ncfile_in%iNX, &
381 ny=swbstats%ncfile_in%iNY, &
382 x0=swbstats%ncfile_in%rX(0), &
383 y0=swbstats%ncfile_in%rY(0), &
384 x1=swbstats%ncfile_in%rX(1), &
385 y1=swbstats%ncfile_in%rY(1), &
386 nodata_value=-9999._c_double)
387
388 ! if user wants annual or monthly statistics, calculate a list of annual or
389 ! monthly starting and ending dates for each time slice
390 if (swbstats%calculation_time_period == calc_period_annual) then
391
392 call swbstats%create_date_list_for_annual_statistics()
393
394 elseif (swbstats%calculation_time_period == calc_period_monthly) then
395
396 call swbstats%create_date_list_for_monthly_statistics()
397 call swbstats%create_monthly_working_grids()
398
399 ! initialize the 12 grids that will be used to calculate mean monthly values
400 do month_index=1,12
401
402 call mon_stat(month_index)%initialize(nx=swbstats%ncfile_in%iNX, &
403 ny=swbstats%ncfile_in%iNY, &
404 x0=swbstats%ncfile_in%rX(0), &
405 y0=swbstats%ncfile_in%rY(0), &
406 x1=swbstats%ncfile_in%rX(1), &
407 y1=swbstats%ncfile_in%rY(1), &
408 nodata_value=-9999._c_double)
409
410 enddo
411
412 elseif (swbstats%calculation_time_period == calc_period_daily) then
413
414 call swbstats%create_date_list_for_daily_statistics()
415
416 endif
417
418 if (swbstats%report_in_meters) then
419
420 ! set unit conversions needed to obtain output units of "meters"
421 if (swbstats%netcdf_variable_units_string .containssimilar. "inch") then
422 swbstats%unit_conversion_factor = 0.0254_c_double
423 elseif (swbstats%netcdf_variable_units_string .containssimilar. "cm") then
424 swbstats%unit_conversion_factor = 0.01_c_double
425 elseif (swbstats%netcdf_variable_units_string .containssimilar. "mm") then
426 swbstats%unit_conversion_factor = 0.001_c_double
427 else
428 call die("Was attempting to determine the output unit conversion factor," &
429 //" but the netCDF variable has units of " &
430 //squote(swbstats%netcdf_variable_units_string)//", which cannot" &
431 //" be converted to units of 'meters'.")
432 endif
433
434 swbstats%filename_modifier_string = trim(swbstats%filename_modifier_string) &
435 //"__meters"
436 endif
437
438 ! for use with MODFLOW, the output needs to be expressed as a volume; set the
439 ! conversion factors based on the information contained in the netCDF proj4 string
440 if (swbstats%report_as_volume) then
441
442 if (swbstats%report_as_volume) then
443 if (swbstats%target_proj4_string .containssimilar. "units=m") then
444 swbstats%length_conversion_factor = 1.0_c_double
445 elseif (swbstats%target_proj4_string .containssimilar. "units=us-ft") then
446 swbstats%length_conversion_factor = 0.3048006096012192_c_double
447 elseif (swbstats%target_proj4_string .containssimilar. "units=ft") then
448 swbstats%length_conversion_factor = 0.3048_c_double
449 else
450 call die("Was attempting to define length conversion factor, but no units " &
451 //"information found in input PROJ4 string.")
452 endif
453 swbstats%grid_cell_area_sq_meters = (swbstats%grd_native%rGridCellSize &
454 * swbstats%length_conversion_factor)**2
455 swbstats%output_conversion_factor = swbstats%grid_cell_area_sq_meters &
456 * swbstats%unit_conversion_factor
457 else
458 swbstats%output_conversion_factor = swbstats%unit_conversion_factor
459 endif
460
461 swbstats%filename_modifier_string = trim(swbstats%filename_modifier_string) &
462 //"__cubic_meters"
463
464 endif
465
466 call assert(.not. (swbstats%report_as_volume .and. swbstats%report_in_meters), &
467 "Cannot use '--report_as_volume' and '--report_in_meters' in the same" &
468 //" swbstats run")
469
470 if (swbstats%compare_to_obs_values) then
471 call swbstats%initialize_comparison_grid(grid_filename=swbstats%comparison_grid_filename)
472 endif
473
474 if ( swbstats%calculation_time_period == calc_period_slice_single) then
475
476 ! force slice dates to honor bounds of data dates
477 if ( swbstats%slice_start_date < swbstats%data_start_date ) &
478 swbstats%slice_start_date = swbstats%data_start_date
479 if ( swbstats%slice_end_date > swbstats%data_end_date ) &
480 swbstats%slice_end_date = swbstats%data_end_date
481
482 call sim_dt%initialize( swbstats%slice_start_date, swbstats%slice_end_date )
483 call swbstats%create_date_list_for_period_statistics( swbstats%slice_start_date, swbstats%slice_end_date )
484
485 elseif (swbstats%calculation_time_period == calc_period_all) then
486 ! no slice dates were provided; default to a single slice with start/end date
487 ! corresponding to the start/end date of the data bounds
488 swbstats%calculation_time_period = calc_period_slice_single
489 call sim_dt%initialize( swbstats%data_start_date, swbstats%data_end_date )
490 call swbstats%create_date_list_for_period_statistics( swbstats%data_start_date, swbstats%data_end_date )
491 else
492 ! default time slice = all data in netcdf file
493 call sim_dt%initialize( swbstats%data_start_date, swbstats%data_end_date )
494 endif
495
496 ! initialize data needed to calculate zonal statistics for a *SINGLE* zone grid
497 if (swbstats%calc_zonal_stats) then
498 if (.not. swbstats%multiple_zone_grids) then
499 call swbstats%initialize_zone_grid(grid_filename=swbstats%zone_grid_filename)
500 call swbstats%get_unique_int(swbstats%grd_zone%pGrdBase%iData, swbstats%unique_zone_list)
501
502 if (len_trim(swbstats%zone_grid2_filename) > 0) then
503 call swbstats%initialize_secondary_zone_grid(grid_filename=swbstats%zone_grid2_filename)
504 call swbstats%get_unique_int(swbstats%grd_zone2%pGrdBase%iData, swbstats%unique_zone2_list)
505 endif
506
507 endif
508
509 if ( allocated( swbstats%output_file_prefix) ) then
510 temp_string = trim(swbstats%output_file_prefix)//"__zonal_stats__"//trim(swbstats%netcdf_variable_name_string)//".csv"
511 else
512 temp_string = "zonal_stats__"//trim(swbstats%netcdf_variable_name_string)//".csv"
513 endif
514
515 call swbstats%open_zonal_stats_output_file(trim(temp_string))
516
517 endif ! initialize data structures needed to calculate zonal statistics for a *SINGLE* zone grid
518
519
520 ! establish data range string for use in output file naming
521 swbstats%date_range_string = swbstats%data_start_date%prettydate() &
522 //"_to_"//swbstats%data_end_date%prettydate()
523
524 call swbstats%open_output_netcdf_files(output_files)
525
526 ! Done with preliminaries (opening files, setting options, etc.); begin calcs
527
528 if (swbstats%dump_options_to_screen) call swbstats%print_all_options()
529
530 ! depending on options selected, we will have a list of:
531 ! a) arbitrary time periods based on user-supplied date ranges;
532 ! b) time periods bracketing the start and end of all months within the
533 ! netCDF start and end period; or
534 ! c) time periods bracketing complete calendar years within the start and
535 ! end dates contained within the netCDF file to be munged.
536
537
538! .o8 o8o o8o oooo
539!"888 `"' `"' `888
540! 888oooo. .ooooo. .oooooooo oooo ooo. .oo. ooo. .oo. .oo. .oooo. oooo ooo. .oo. 888 .ooooo. .ooooo. oo.ooooo.
541! d88' `88b d88' `88b 888' `88b `888 `888P"Y88b `888P"Y88bP"Y88b `P )88b `888 `888P"Y88b 888 d88' `88b d88' `88b 888' `88b
542! 888 888 888ooo888 888 888 888 888 888 888 888 888 .oP"888 888 888 888 888 888 888 888 888 888 888
543! 888 888 888 .o `88bod8P' 888 888 888 888 888 888 d8( 888 888 888 888 888 888 888 888 888 888 888
544! `Y8bod8P' `Y8bod8P' `8oooooo. o888o o888o o888o o888o o888o o888o `Y888""8o o888o o888o o888o o888o `Y8bod8P' `Y8bod8P' 888bod8P'
545! d" YD 888
546! "Y88888P' o888o
547
548
549! One potential use case: several hundred lines that look like the entry below.
550! Need to ensure that all resources are deallocated promptly to avoid memory leak
551
552! *** snippet of a 'zone_period_file' ***
553!-------------------------------------------------
554! id,start_date,end_date,zone_grid_filename
555! 1,2013-05-01,2013-05-31,corn2013_zone_1000m.asc
556! 2,2013-06-01,2013-06-30,corn2013_zone_1000m.asc
557! 3,2013-07-01,2013-07-31,corn2013_zone_1000m.asc
558! 4,2013-08-01,2013-08-31,corn2013_zone_1000m.asc
559! 5,2013-09-01,2013-09-30,corn2013_zone_1000m.asc
560
561! for the use case given above, date_range_id_list%count should equal the number of rows in the zone period file
562
563 do iindex=1, swbstats%date_range_id_list%count
564
565 ! set the date format that is expected in subsequent calls to parseDate
566 call swbstats%slice_start_date%setDateFormat("YYYY-MM-DD")
567 call swbstats%slice_end_date%setDateFormat("YYYY-MM-DD")
568
569 ! set start and end date for slice calculation to the value corresponding to its position
570 ! in the input zone or observation file list.
571 start_date_string = swbstats%start_date_list%get( iindex )
572 end_date_string = swbstats%end_date_list%get( iindex )
573
574 ! parse start and end dates for slice into date objects
575 call swbstats%slice_start_date%parseDate( start_date_string )
576 call swbstats%slice_end_date%parseDate( end_date_string )
577
578 ! create date range string for use in output filenames
579 swbstats%slice_range_string = swbstats%slice_start_date%prettydate() &
580 //"_to_"//swbstats%slice_end_date%prettydate()
581
582 write(*,fmt="(a)") ""
583 write(*,fmt="(a)") "Processing slice: ", swbstats%slice_start_date%prettydate() &
584 //" to "//swbstats%slice_end_date%prettydate()
585 write(*,fmt="(a)") repeat("-", 70)
586
587 ! grid_sum = simple addition over stack of grids;
588 ! grid_mean is the grid_sum divided by number of days = daily mean
589 !
590 ! first step is to calculate the statistics over the entire grid
591 call swbstats%calculate_slice_statistics( start_date=swbstats%slice_start_date, &
592 end_date=swbstats%slice_end_date, &
593 grd_sum=output_files(stats_sum)%grid_ptr%dpData, &
594 grd_mean=output_files(stats_mean)%grid_ptr%dpData, &
595 grd_var=output_files(stats_variance)%grid_ptr%dpData)
596
597 ! idea here is to tack on a set of accumulator grids that can be used to sum up
598 ! results from all grid vals for every January within the simulation timeframe,
599 ! all grid vals for every February within simulation timeframe, etc.
600 if (swbstats%calculation_time_period == calc_period_monthly) then
601 call swbstats%calculate_monthly_statistics(month_num=swbstats%slice_start_date%iMonth, finalize=false)
602 endif
603
604 if (swbstats%multiple_comparison_grids) then
605 swbstats%comparison_grid_filename = swbstats%comparison_grid_file_list%get( iindex )
606 call swbstats%initialize_comparison_grid(grid_filename=swbstats%comparison_grid_filename)
607 endif
608
609 if (swbstats%multiple_zone_grids) then
610 swbstats%zone_grid_filename = swbstats%zone_grid_file_list%get( iindex )
611 call swbstats%initialize_zone_grid(grid_filename=swbstats%zone_grid_filename)
612 endif
613
614 call swbstats%write_stats_to_netcdf(output_files=output_files, &
615 start_date=swbstats%slice_start_date, &
616 end_date=swbstats%slice_end_date)
617
618 call swbstats%write_stats_to_arcgrid(output_files=output_files, &
619 start_date=swbstats%slice_start_date, &
620 end_date=swbstats%slice_end_date, &
621 date_range_string=swbstats%slice_range_string, &
622 output_file_prefix=swbstats%output_file_prefix)
623
624 if (swbstats%calc_zonal_stats) then
625 if ( len_trim(swbstats%zone_grid2_filename) > 0) then
626
627 if ( associated(swbstats%grd_comparison) ) then
628
629 call swbstats%output_zonal_stats( &
630 start_date=swbstats%slice_start_date, &
631 end_date=swbstats%slice_end_date, &
632 values=output_files(stats_sum)%grid_ptr%dpData, &
633 zone_ids=swbstats%grd_zone%pGrdBase%iData, &
634 unique_zone_list=swbstats%unique_zone_list, &
635 zone2_ids=swbstats%grd_zone2%pGrdBase%iData, &
636 unique_zone2_list=swbstats%unique_zone2_list, &
637 comparison_values=swbstats%grd_comparison%pGrdBase%dpData, &
638 funit=swbstats%zonal_stats_output_file%unit() )
639
640 else
641 call swbstats%output_zonal_stats( &
642 start_date=swbstats%slice_start_date, &
643 end_date=swbstats%slice_end_date, &
644 values=output_files(stats_sum)%grid_ptr%dpData, &
645 zone_ids=swbstats%grd_zone%pGrdBase%iData, &
646 unique_zone_list=swbstats%unique_zone_list, &
647 zone2_ids=swbstats%grd_zone2%pGrdBase%iData, &
648 unique_zone2_list=swbstats%unique_zone2_list, &
649 funit=swbstats%zonal_stats_output_file%unit() )
650
651 endif
652
653 else ! perform calculation for a single zone grid
654 if ( associated(swbstats%grd_comparison) ) then
655 call swbstats%output_zonal_stats( &
656 start_date=swbstats%slice_start_date, &
657 end_date=swbstats%slice_end_date, &
658 values=output_files(stats_sum)%grid_ptr%dpData, &
659 zone_ids=swbstats%grd_zone%pGrdBase%iData, &
660 unique_zone_list=swbstats%unique_zone_list, &
661 comparison_values=swbstats%grd_comparison%pGrdBase%dpData, &
662 funit=swbstats%zonal_stats_output_file%unit() )
663
664 else
665 call swbstats%output_zonal_stats( &
666 start_date=swbstats%slice_start_date, &
667 end_date=swbstats%slice_end_date, &
668 values=output_files(stats_sum)%grid_ptr%dpData, &
669 zone_ids=swbstats%grd_zone%pGrdBase%iData, &
670 unique_zone_list=swbstats%unique_zone_list, &
671 funit=swbstats%zonal_stats_output_file%unit() )
672
673 endif
674 endif
675 endif
676
677 ! icky hack; need to advance the record number for the multiple slice calc
678 recnum = recnum + 1
679
680 enddo
681
682 !call netcdf_close_file(NCFILE=ncfile_out)
683 call swbstats%close_output_netcdf_files(output_files=output_files)
684
685 if (swbstats%calculation_time_period == calc_period_monthly) then
686 call swbstats%calculate_monthly_statistics(month_num=swbstats%slice_start_date%iMonth, finalize=true)
687 call swbstats%write_monthly_stats_to_arcgrid(output_files=output_files, &
688 date_range_string=swbstats%date_range_string, &
689 output_file_prefix=swbstats%output_file_prefix)
690 endif
691
692 if (swbstats%write_csv) call swbstats%zonal_stats_output_file%close()
693
694! endif
695
696 if (swbstats%dump_options_to_screen) call swbstats%print_all_options()
697
698end program swbstats2
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
logical(c_bool), parameter, public false
integer(c_int), parameter datatype_float
integer(c_int), parameter datatype_int
This module contains the DATETIME_T class and associated time and date-related routines,...
Definition datetime.F90:9
subroutine, public die(smessage, smodule, iline, shints, scalledby, icalledbyline)
Provides support for input and output of gridded ASCII data, as well as for creation and destruction ...
Definition grid.F90:8
Provide support for use of netCDF files as input for time-varying, gridded meteorlogic data,...
subroutine, public netcdf_get_attribute_list_for_variable(ncfile, variable_name, attribute_name_list, attribute_value_list)
subroutine, public netcdf_open_and_prepare_for_merging(ncfile, sfilename, guess_z_var_name)
integer(c_int), parameter, public nc_z
type(date_range_t), public sim_dt
type(running_stats_t) rstat
integer(c_size_t) recnum
type(file_collection_t), dimension(39) output_files
type(running_stats_t), dimension(12) mon_stat
program swbstats2
Definition swbstats2.F90:1