6 use iso_fortran_env,
only : output_unit
52 character (len=24) :: unit_name
53 character (len=10) :: unit_abbrev
54 real (c_double) :: conversion_factor_from_inches
58 character (len=24) :: unit_name
59 character (len=10) :: unit_abbrev
60 real (c_double) :: conversion_factor_from_cubic_feet
66 character (len=8) :: stats_description
67 integer (c_int) :: n_count = 0
68 logical (c_bool) :: write_netcdf =
false
69 logical (c_bool) :: write_arcgrid =
false
70 logical (c_bool) :: output_active =
false
71 real (c_float) :: valid_min = 10000.
72 real (c_float) :: valid_max = -10000.
76 logical (c_bool) :: dump_options_to_screen =
false
77 logical (c_bool) :: write_csv =
false
79 logical (c_bool) :: compare_to_obs_values =
false
80 logical (c_bool) :: annualize_stats =
false
81 logical (c_bool) :: report_as_volume =
false
82 logical (c_bool) :: report_in_meters =
false
83 character (len=:),
allocatable :: output_file_prefix
84 character (len=:),
allocatable :: target_proj4_string
89 character (len=:),
allocatable :: slice_range_string
90 character (len=:),
allocatable :: date_range_string
92 character (len=:),
allocatable :: stress_period_filename
93 character (len=:),
allocatable :: comparison_period_filename
94 character (len=:),
allocatable :: zone_period_filename
95 character (len=:),
allocatable :: comparison_grid_filename
96 character (len=:),
allocatable :: zone_grid_filename
97 character (len=:),
allocatable :: zone_grid2_filename
98 character (len=:),
allocatable :: netcdf_input_filename
99 character (len=:),
allocatable :: netcdf_variable_units_string
100 character (len=:),
allocatable :: netcdf_variable_name_string
101 character (len=:),
allocatable :: filename_modifier_string
102 logical (c_bool) :: netcdf_input_file_is_open =
false
103 logical (c_bool) :: multiple_zone_grids =
false
104 logical (c_bool) :: multiple_comparison_grids =
false
105 real (c_double) :: comparison_grid_conversion_factor = 1.0_c_double
113 real (c_double) :: output_conversion_factor = 1.0_c_double
114 real (c_double) :: unit_conversion_factor = 1.0_c_double
115 real (c_double) :: grid_cell_area_sq_meters = 1.0_c_double
116 real (c_double) :: length_conversion_factor = 1.0_c_double
170 length_unit_t(
"feet ",
"ft", 1.0_c_double / 12.0_c_double), &
174 volume_unit_t(
"billions of gallons",
"BG ", 7.4805194805e-9_c_double ), &
175 volume_unit_t(
"millions of gallons",
"MG ", 7.4805194805e-6_c_double), &
176 volume_unit_t(
"acre-feet ",
"ac-ft", 0.000022956840808_c_double) ]
193 this%grd_native =>
grid_create( inx=this%ncfile_in%iNX, &
194 iny=this%ncfile_in%iNY, &
195 rx0=this%ncfile_in%rX(
nc_left), &
198 ry1=this%ncfile_in%rY(
nc_top), &
202 inx=this%ncfile_in%iNX, &
203 iny=this%ncfile_in%iNY, &
204 rx0=this%ncfile_in%rX(
nc_left), &
207 ry1=this%ncfile_in%rY(
nc_top), &
212 inx=this%ncfile_in%iNX, &
213 iny=this%ncfile_in%iNY, &
214 rx0=this%ncfile_in%rX(
nc_left), &
217 ry1=this%ncfile_in%rY(
nc_top), &
222 inx=this%ncfile_in%iNX, &
223 iny=this%ncfile_in%iNY, &
224 rx0=this%ncfile_in%rX(
nc_left), &
227 ry1=this%ncfile_in%rY(
nc_top), &
232 this%grd_delta =>
grid_create( inx=this%ncfile_in%iNX, &
233 iny=this%ncfile_in%iNY, &
234 rx0=this%ncfile_in%rX(
nc_left), &
237 ry1=this%ncfile_in%rY(
nc_top), &
240 this%grd_delta2 =>
grid_create( inx=this%ncfile_in%iNX, &
241 iny=this%ncfile_in%iNY, &
242 rx0=this%ncfile_in%rX(
nc_left), &
245 ry1=this%ncfile_in%rY(
nc_top), &
250 bnds%iNumCols = this%ncfile_in%iNX
251 bnds%iNumRows = this%ncfile_in%iNY
252 bnds%fX_ll = this%grd_native%rX0
253 bnds%fY_ll = this%grd_native%rY0
254 bnds%fX_ur = this%grd_native%rX1
255 bnds%fY_ur = this%grd_native%rY1
256 bnds%fGridCellSize = this%grd_native%rGridCellSize
257 bnds%sPROJ4_string = this%target_proj4_string
267 integer (c_int) :: month_num
268 integer (c_int) :: sum_index_num
269 integer (c_int) :: mean_index_num
270 integer (c_int) :: variance_index_num
271 character (len=3) :: month_name
276 month_name =
months(month_num)%sName
277 sum_index_num = ( month_num - 1 ) * 3 + 1
278 mean_index_num = ( month_num - 1 ) * 3 + 2
279 variance_index_num = ( month_num - 1 ) * 3 + 3
282 inx=this%ncfile_in%iNX, &
283 iny=this%ncfile_in%iNY, &
284 rx0=this%ncfile_in%rX(
nc_left), &
287 ry1=this%ncfile_in%rY(
nc_top), &
293 inx=this%ncfile_in%iNX, &
294 iny=this%ncfile_in%iNY, &
295 rx0=this%ncfile_in%rX(
nc_left), &
298 ry1=this%ncfile_in%rY(
nc_top), &
304 inx=this%ncfile_in%iNX, &
305 iny=this%ncfile_in%iNY, &
306 rx0=this%ncfile_in%rX(
nc_left), &
309 ry1=this%ncfile_in%rY(
nc_top), &
311 output_files(variance_index_num)%stats_description =
"VARIANCE"
321 real (c_double),
intent(inout) :: values(:,:)
322 integer (c_int),
intent(inout) :: zone_ids(:,:)
323 integer (c_int),
intent(inout) :: target_id
324 real (c_double),
intent(inout),
allocatable :: result_vector(:)
325 real (c_double),
intent(inout),
optional :: comparison_values(:,:)
328 real (c_double) :: min_val
329 real (c_double) :: max_val
330 real (c_double) :: mean_val
331 real (c_double) :: sum_val
332 real (c_double) :: n_val
334 real (c_double) :: min_val_comp
335 real (c_double) :: max_val_comp
336 real (c_double) :: mean_val_comp
337 real (c_double) :: sum_val_comp
338 real (c_double) :: n_val_comp
340 mean_val = 0.0; mean_val_comp = 0.0
341 max_val = 0.0; max_val_comp = 0.0
342 min_val = 0.0; min_val_comp = 0.0
343 sum_val = 0.0; sum_val_comp = 0.0
344 n_val = 0.0; n_val_comp = 0.0
346 n_val = count( zone_ids==target_id .and. values >
nc_fill_float )
348 if ( n_val > 0 )
then
349 sum_val = sum( values, zone_ids==target_id .and. values >
nc_fill_float )
350 mean_val = sum_val / n_val
351 min_val = minval( values, zone_ids==target_id .and. values >
nc_fill_float )
352 max_val = maxval( values, zone_ids==target_id .and. values >
nc_fill_float )
355 if (
allocated(result_vector) )
deallocate(result_vector)
357 if (
present( comparison_values ) )
then
359 n_val_comp = count( zone_ids==target_id .and. comparison_values >
nc_fill_float )
361 if ( n_val_comp > 0 )
then
362 n_val_comp = count( zone_ids==target_id .and. comparison_values >
nc_fill_float )
363 sum_val_comp = sum( comparison_values, zone_ids==target_id .and. comparison_values >
nc_fill_float )
364 mean_val_comp = sum_val_comp / n_val_comp
365 min_val_comp = minval( comparison_values, zone_ids==target_id .and. comparison_values >
nc_fill_float )
366 max_val_comp = maxval( comparison_values, zone_ids==target_id .and. comparison_values >
nc_fill_float )
369 allocate( result_vector(10) )
370 result_vector(6) = min_val_comp
371 result_vector(7) = max_val_comp
372 result_vector(8) = mean_val_comp
373 result_vector(9) = sum_val_comp
374 result_vector(10) = n_val_comp
376 allocate (result_vector(5))
379 result_vector(1) = min_val
380 result_vector(2) = max_val
381 result_vector(3) = mean_val
382 result_vector(4) = sum_val
383 result_vector(5) = n_val
390 target_id, target2_id, result_vector, comparison_values)
392 real (c_double),
intent(inout) :: values(:,:)
393 integer (c_int),
intent(inout) :: zone_ids(:,:)
394 integer (c_int),
intent(inout) :: zone2_ids(:,:)
395 integer (c_int),
intent(inout) :: target_id
396 integer (c_int),
intent(inout) :: target2_id
397 real (c_double),
intent(inout),
allocatable :: result_vector(:)
398 real (c_double),
intent(inout),
optional :: comparison_values(:,:)
401 real (c_double) :: min_val
402 real (c_double) :: max_val
403 real (c_double) :: mean_val
404 real (c_double) :: sum_val
405 real (c_double) :: n_val
407 real (c_double) :: min_val_comp
408 real (c_double) :: max_val_comp
409 real (c_double) :: mean_val_comp
410 real (c_double) :: sum_val_comp
411 real (c_double) :: n_val_comp
413 mean_val = 0.0; mean_val_comp = 0.0
414 max_val = 0.0; max_val_comp = 0.0
415 min_val = 0.0; min_val_comp = 0.0
416 sum_val = 0.0; sum_val_comp = 0.0
417 n_val = 0.0; n_val_comp = 0.0
419 n_val = count( zone_ids==target_id .and. zone2_ids==target2_id &
422 if ( n_val > 0 )
then
423 sum_val = sum( values, zone_ids==target_id .and. zone2_ids==target2_id &
425 mean_val = sum_val / n_val
426 min_val = minval( values, zone_ids==target_id .and. zone2_ids==target2_id &
428 max_val = maxval( values, zone_ids==target_id .and. zone2_ids==target2_id &
432 if (
allocated(result_vector) )
deallocate(result_vector)
434 if (
present( comparison_values ) )
then
436 n_val_comp = count( zone_ids==target_id .and. zone2_ids==target2_id &
439 if ( n_val_comp > 0 )
then
440 n_val_comp = count( zone_ids==target_id .and. zone2_ids==target2_id &
442 sum_val_comp = sum( comparison_values, zone_ids==target_id .and. zone2_ids==target2_id &
444 mean_val_comp = sum_val_comp / n_val_comp
445 min_val_comp = minval( comparison_values, zone_ids==target_id .and. zone2_ids==target2_id &
447 max_val_comp = maxval( comparison_values, zone_ids==target_id .and. zone2_ids==target2_id &
451 allocate( result_vector(10) )
452 result_vector(6) = min_val_comp
453 result_vector(7) = max_val_comp
454 result_vector(8) = mean_val_comp
455 result_vector(9) = sum_val_comp
456 result_vector(10) = n_val_comp
458 allocate (result_vector(5))
461 result_vector(1) = min_val
462 result_vector(2) = max_val
463 result_vector(3) = mean_val
464 result_vector(4) = sum_val
465 result_vector(5) = n_val
474 integer (c_int),
intent(in) :: grid_values(:,:)
475 type (FSTRING_LIST_T),
intent(inout) :: unique_val_list
478 integer (c_int) :: ix, iy
479 character (len=20) :: sval
481 do ix=1,ubound(grid_values,1)
482 do iy=1,ubound(grid_values,2)
484 if (grid_values(ix, iy) < 0 ) cycle
488 if ( unique_val_list%count == 0)
then
489 call unique_val_list%append(sval)
492 if ( unique_val_list%count_matching( sval ) > 0 ) cycle
493 call unique_val_list%append(sval)
509 integer (c_int) :: indx
510 type (DATE_RANGE_T) :: ANN_DT
514 call ann_dt%initialize( this%data_start_date, this%data_end_date )
518 call this%start_date_list%append( ann_dt%curr%prettydate() )
519 call ann_dt%advance_to_last_doy()
520 call this%date_range_id_list%append(
ascharacter(indx) )
521 if ( ann_dt%curr < ann_dt%end )
then
522 call this%end_date_list%append( ann_dt%curr%prettydate() )
525 call this%end_date_list%append( ann_dt%end%prettydate() )
539 integer (c_int) :: indx
540 type (DATE_RANGE_T) :: MON_DT
544 call mon_dt%initialize( this%data_start_date, this%data_end_date )
548 call this%start_date_list%append( mon_dt%curr%prettydate() )
549 call mon_dt%advance_to_last_day_of_month()
550 call this%date_range_id_list%append(
ascharacter(indx) )
551 if ( mon_dt%curr < mon_dt%end )
then
552 call this%end_date_list%append( mon_dt%curr%prettydate() )
555 call this%end_date_list%append( mon_dt%end%prettydate() )
569 integer (c_int) :: indx
570 type (DATE_RANGE_T) :: DAILY_DT
574 call daily_dt%initialize( this%data_start_date, this%data_end_date )
578 call this%start_date_list%append( daily_dt%curr%prettydate() )
579 call this%end_date_list%append( daily_dt%curr%prettydate() )
580 call this%date_range_id_list%append(
ascharacter(indx) )
582 if ( daily_dt%curr < daily_dt%end )
then
583 call daily_dt%addDay()
596 type (DATETIME_T),
intent(in) :: start_date
597 type (DATETIME_T),
intent(in) :: end_date
599 call this%start_date_list%append( start_date%prettydate() )
600 call this%date_range_id_list%append(
"1" )
601 call this%end_date_list%append( end_date%prettydate() )
610 character (len=*),
intent(inout) :: grid_filename
613 character (len=:),
allocatable :: description_str
614 character (len=:),
allocatable :: OUTPUT_FILESname_str
615 character (len=256),
save :: previous_zone_filename
619 if ( .not. trim(previous_zone_filename)==trim(grid_filename) )
then
622 description_str =
left( grid_filename, substring=
".")
623 if (description_str .contains.
"/") description_str =
right( description_str, substring=
"/")
624 if (description_str .contains.
"\") description_str =
right( description_str, substring=
"\")
626 output_filesname_str =
"zone_grid__"//trim(description_str)//
"__as_read_into_SWBSTATS2.asc"
629 if (
associated(this%grd_zone))
deallocate(this%grd_zone)
630 nullify(this%grd_zone)
631 allocate(this%grd_zone)
633 call this%grd_zone%set_target_PROJ4(this%target_proj4_string)
634 call this%grd_zone%initialize( &
635 sdescription=
"Zone Grid", &
636 sfiletype=
"ARC_GRID", &
637 sfilename=trim(grid_filename), &
640 call this%grd_zone%getvalues()
649 previous_zone_filename = trim(grid_filename)
651 call this%unique_zone_list%clear()
652 call this%get_unique_int(this%grd_zone%pGrdBase%iData, this%unique_zone_list)
663 character (len=*),
intent(inout) :: grid_filename
666 character (len=:),
allocatable :: description_str
667 character (len=:),
allocatable :: OUTPUT_FILESname_str
668 character (len=256),
save :: previous_zone_filename
672 if ( .not. trim(previous_zone_filename)==trim(grid_filename) )
then
674 description_str =
left( grid_filename, substring=
".")
675 if (description_str .contains.
"/") description_str =
right( description_str, substring=
"/")
676 if (description_str .contains.
"\") description_str =
right( description_str, substring=
"\")
678 output_filesname_str =
"zone_grid2__"//trim(description_str)//
"__as_read_into_SWBSTATS2.asc"
681 if (
associated(this%grd_zone2))
deallocate(this%grd_zone2)
682 nullify(this%grd_zone2)
683 allocate(this%grd_zone2)
685 call this%grd_zone2%set_target_PROJ4(this%target_proj4_string)
686 call this%grd_zone2%initialize( &
687 sdescription=
"Zone Grid", &
688 sfiletype=
"ARC_GRID", &
689 sfilename=trim(grid_filename), &
692 call this%grd_zone2%getvalues()
700 previous_zone_filename = trim(grid_filename)
711 character (len=*),
intent(inout) :: grid_filename
714 integer (c_int) :: iStat
715 character (len=:),
allocatable :: description_str
716 character (len=:),
allocatable :: OUTPUT_FILESname_str
717 character (len=256),
save :: previous_comparison_filename
721 if ( .not. trim(previous_comparison_filename)==trim(grid_filename) )
then
723 description_str =
left( grid_filename, substring=
".")
724 if (description_str .contains.
"/") description_str =
right( description_str, substring=
"/")
725 if (description_str .contains.
"\") description_str =
right( description_str, substring=
"\")
727 output_filesname_str =
"Comparison_grid__"//trim(description_str)//
"__as_read_into_SWBSTATS2.asc"
730 if (.not.
associated(this%grd_comparison))
allocate(this%grd_comparison, stat=istat)
732 call this%grd_comparison%set_target_PROJ4(this%target_proj4_string)
734 call this%grd_comparison%initialize( &
735 sdescription=
"Comparison Grid", &
736 sfiletype=
"ARC_GRID", &
737 sfilename=trim(grid_filename), &
740 call this%grd_comparison%getvalues()
745 this%grd_comparison%pGrdBase%dpData = this%grd_comparison%pGrdBase%dpData &
746 * this%comparison_grid_conversion_factor
751 previous_comparison_filename = trim(grid_filename)
761 if (this%report_as_volume)
then
762 if (this%target_proj4_string .containssimilar.
"units=m")
then
763 this%length_conversion_factor = 1.0_c_double
764 elseif (this%target_proj4_string .containssimilar.
"units=us-ft")
then
765 this%length_conversion_factor = 0.3048006096012192_c_double
766 elseif (this%target_proj4_string .containssimilar.
"units=ft")
then
767 this%length_conversion_factor = 0.3048_c_double
769 call die(
"Was attempting to define length conversion factor, but no units " &
770 //
"information found in input PROJ4 string.")
772 this%grid_cell_area_sq_meters = (this%grd_native%rGridCellSize &
773 * this%length_conversion_factor)**2
774 this%output_conversion_factor = this%grid_cell_area_sq_meters &
775 * this%unit_conversion_factor
777 this%output_conversion_factor = this%unit_conversion_factor
780 this%filename_modifier_string = trim(this%filename_modifier_string) &
792 type (FILE_COLLECTION_T),
intent(inout) :: OUTPUT_FILES(:)
793 type (DATETIME_T),
intent(inout) :: start_date
794 type (DATETIME_T),
intent(inout) :: end_date
797 real (c_double) :: start_bnd
798 real (c_double) :: end_bnd
799 integer (c_size_t) :: nx, ny
800 type (T_NETCDF4_FILE),
pointer :: ncfile_out
801 type (GENERAL_GRID_T),
pointer :: grid_ptr
802 integer (c_int) :: stat_indx
807 start_bnd =
sim_dt%days_from_origin( start_date )
808 end_bnd =
sim_dt%days_from_origin( end_date )
812 if ( .not. output_files(stat_indx)%output_active ) cycle
814 if ( output_files(stat_indx)%write_netcdf )
then
816 ncfile_out => output_files(stat_indx)%nc_ptr
817 grid_ptr => output_files(stat_indx)%grid_ptr
820 ivarid=ncfile_out%iVarID(
nc_time), &
822 icount=[1_c_size_t], &
823 istride=[1_c_size_t], &
825 rvalues=[ real(start_bnd, c_float) ] )
837 ivarid=ncfile_out%iVarID(
nc_z), &
838 istart=[
recnum , 0_c_size_t, 0_c_size_t], &
839 icount=[ 1_c_size_t, ny, nx ], &
840 istride=[1_c_size_t, 1_c_size_t, 1_c_size_t], &
841 rvalues=real(grid_ptr%dpData, c_float) )
843 output_files(stat_indx)%valid_min = &
846 output_files(stat_indx)%valid_max = &
862 type (FILE_COLLECTION_T),
intent(inout) :: OUTPUT_FILES(:)
863 character (len=*),
intent(in),
optional :: date_range_string
864 character (len=*),
intent(in),
optional :: output_file_prefix
867 character (len=:),
allocatable :: filename
868 integer (c_int) :: nx, ny
869 type (GENERAL_GRID_T),
pointer :: grid_ptr
870 character (len=8) :: stats_description
871 character (len=:),
allocatable :: units_string
872 character (len=:),
allocatable :: filename_modifier
873 character (len=:),
allocatable :: file_prefix
875 integer (c_int) :: sum_index_num
876 integer (c_int) :: mean_index_num
877 integer (c_int) :: variance_index_num
878 character (len=3) :: month_name
879 integer (c_int) :: month_num
887 month_name =
months(month_num)%sName
888 sum_index_num = ( month_num - 1 ) * 3 + 1
889 mean_index_num = ( month_num - 1 ) * 3 + 2
890 variance_index_num = ( month_num - 1 ) * 3 + 3
892 if ( output_files(mean_index_num)%write_arcgrid)
then
894 if (this%report_as_volume)
then
895 units_string =
"cubic meters"
896 elseif (this%report_in_meters)
then
897 units_string =
"meters"
899 units_string = trim(this%netcdf_variable_units_string)
902 call replace(units_string,
' ',
'_' )
905 filename_modifier =
clean(units_string,
",")
911 grid_ptr => output_files(mean_index_num)%grid_ptr
912 call assert(
associated(grid_ptr),
"Unallocated array", __file__, __line__)
913 stats_description = output_files(mean_index_num)%stats_description
915 if (
present(output_file_prefix) )
then
916 file_prefix = output_file_prefix //
"__" //
"monthly_mean_over_all"
918 file_prefix =
"monthly_mean_over_all"
921 filename = trim(file_prefix) &
922 //
"_"//trim(month_name) &
923 //
"__"//trim(this%netcdf_variable_name_string) &
924 //
"__"//trim(this%date_range_string) &
926 //
"__"//trim(filename_modifier)//
".asc"
931 grid_ptr => output_files(variance_index_num)%grid_ptr
932 call assert(
associated(grid_ptr),
"Unallocated array", __file__, __line__)
933 stats_description = output_files(variance_index_num)%stats_description
935 if (
present(output_file_prefix) )
then
936 file_prefix = output_file_prefix //
"__" //
"monthly_variance_over_all"
938 file_prefix =
"monthly_variance_over_all"
941 filename = trim(file_prefix) &
942 //
"_"//trim(month_name) &
943 //
"__"//trim(this%netcdf_variable_name_string) &
944 //
"__"//trim(this%date_range_string) &
946 //
"__"//trim(filename_modifier)//
".asc"
961 end_date, date_range_string, &
965 type (FILE_COLLECTION_T),
intent(inout) :: OUTPUT_FILES(:)
966 type (DATETIME_T),
intent(inout) :: start_date
967 type (DATETIME_T),
intent(inout) :: end_date
968 character (len=*),
intent(in),
optional :: date_range_string
969 character (len=:),
allocatable,
intent(in),
optional :: output_file_prefix
972 character (len=:),
allocatable :: filename
973 integer (c_int) :: nx, ny
974 type (GENERAL_GRID_T),
pointer :: grid_ptr
975 integer (c_int) :: stat_indx
976 character (len=8) :: stats_description
977 character (len=:),
allocatable :: units_string
978 character (len=:),
allocatable :: filename_modifier
979 character (len=:),
allocatable :: file_prefix
981 if (
present(output_file_prefix) )
then
982 if (
allocated(output_file_prefix)) file_prefix = output_file_prefix //
"__"
992 if ( .not. output_files(stat_indx)%output_active ) cycle
994 if ( output_files(stat_indx)%write_arcgrid)
then
996 if ( this%annualize_stats .and. stat_indx ==
stats_sum)
then
997 units_string = trim(this%netcdf_variable_units_string)//
", per year"
998 elseif (this%report_as_volume)
then
999 units_string =
"cubic meters"
1000 elseif (this%report_in_meters)
then
1001 units_string =
"meters"
1003 units_string = trim(this%netcdf_variable_units_string)
1006 call replace(units_string,
' ',
'_' )
1009 filename_modifier =
clean(units_string,
",")
1011 grid_ptr => output_files(stat_indx)%grid_ptr
1012 stats_description = output_files(stat_indx)%stats_description
1014 if (
present(date_range_string) )
then
1016 filename = output_file_prefix &
1017 //trim(this%netcdf_variable_name_string) &
1018 //
"__"//trim(date_range_string) &
1020 //
"__"//trim(stats_description) &
1021 //
"__"//trim(filename_modifier)//
".asc"
1023 filename = output_file_prefix &
1024 //trim(this%netcdf_variable_name_string) &
1025 //
"__"//start_date%prettydate()//
"_to_"//end_date%prettydate() &
1027 //
"__"//trim(filename_modifier)//
".asc"
1032 grid_ptr%dpData = -9999.
1178 type (DATETIME_T),
intent(inout) :: start_date
1179 type (DATETIME_T),
intent(inout) :: end_date
1180 real (c_double),
intent(inout) :: grd_sum(:,:)
1181 real (c_double),
intent(inout) :: grd_mean(:,:)
1182 real (c_double),
intent(inout) :: grd_var(:,:)
1185 integer (c_int) :: julian_day_number
1186 integer (c_int) :: day_count
1187 logical (c_bool),
allocatable :: local_mask(:,:)
1188 real (c_float),
allocatable :: rTemp(:,:)
1189 real (c_double),
allocatable :: grd_new(:,:)
1192 if ( start_date < this%data_start_date ) start_date = this%data_start_date
1193 if ( end_date > this%data_end_date ) end_date = this%data_end_date
1195 allocate(local_mask(this%ncfile_in%iNX,this%ncfile_in%iNY))
1196 allocate(rtemp(this%ncfile_in%iNX,this%ncfile_in%iNY))
1197 allocate(grd_new(this%ncfile_in%iNX,this%ncfile_in%iNY))
1214 if (
sim_dt%curr > start_date )
then
1215 call sim_dt%set_current_date(start_date)
1220 if (
sim_dt%curr < start_date )
then
1225 julian_day_number = int(
sim_dt%curr%dJulianDate, c_int)
1228 day_count = day_count + 1
1239 grd_new = real(rtemp, c_double) * this%output_conversion_factor
1241 if (day_count == 1)
then
1245 call rstat%push(grd_data=grd_new, mask=local_mask)
1258 if (
sim_dt%curr > end_date )
exit
1262 call rstat%mean(grd_mean)
1263 call rstat%sum(grd_sum)
1264 call rstat%variance(grd_var)
1266 where ( .not. local_mask )
1274 if (this%annualize_stats)
then
1275 where ( local_mask )
1278 grd_sum = grd_sum / real( day_count, c_double ) * 365.25
1286 deallocate(local_mask)
1299 integer (c_short),
intent(in) :: month_num
1300 logical (c_bool),
intent(in) :: finalize
1302 integer (c_int) :: sum_index_num
1303 integer (c_int) :: mean_index_num
1304 integer (c_int) :: variance_index_num
1305 character (len=3) :: month_name
1306 integer (c_int) :: month_index
1308 if (.not. finalize)
then
1311 mask=
logical(OUTPUT_FILES(STATS_SUM)%grid_ptr%dpData > -9999._c_double, c_bool))
1317 month_name =
months(month_index)%sName
1318 sum_index_num = ( month_index - 1 ) * 3 + 1
1319 mean_index_num = ( month_index- 1 ) * 3 + 2
1320 variance_index_num = ( month_index- 1 ) * 3 + 3
1322 call mon_stat(month_index)%mean(output_files(mean_index_num)%grid_ptr%dpData)
1323 call mon_stat(month_index)%sum(output_files(sum_index_num)%grid_ptr%dpData)
1324 call mon_stat(month_index)%variance(output_files(variance_index_num)%grid_ptr%dpData)
1360 date_range_id_list, &
1365 character (len=*),
intent(inout) :: csv_filename
1366 type (FSTRING_LIST_T),
intent(out) :: date_range_id_list
1367 type (FSTRING_LIST_T),
intent(out) :: start_date_list
1368 type (FSTRING_LIST_T),
intent(out) :: end_date_list
1371 type (ASCII_FILE_T),
allocatable :: DF
1372 character (len=256) :: sRecord, sItem
1377 call df%open(sfilename = csv_filename, &
1379 scommentchars =
"%#!", &
1383 srecord = df%readLine()
1386 do while ( .not. df%isEOF() )
1389 srecord = df%readLine()
1392 if ( len_trim(srecord) == 0 ) cycle
1394 call chomp( srecord, sitem, delimiter_chr=
"," )
1395 call this%date_range_id_list%append( sitem )
1397 call chomp( srecord, sitem, delimiter_chr=
"," )
1398 call this%start_date_list%append( sitem )
1399 call this%end_date_list%append( srecord )
1412 date_range_id_list, &
1415 comparison_grid_file_list)
1418 character (len=*),
intent(inout) :: csv_filename
1419 type (FSTRING_LIST_T),
intent(out) :: date_range_id_list
1420 type (FSTRING_LIST_T),
intent(out) :: start_date_list
1421 type (FSTRING_LIST_T),
intent(out) :: end_date_list
1422 type (FSTRING_LIST_T),
intent(out) :: comparison_grid_file_list
1425 type (ASCII_FILE_T),
allocatable :: DF
1426 character (len=256) :: sRecord, sItem
1431 call df%open(sfilename = csv_filename, &
1433 scommentchars =
"%#!", &
1437 srecord = df%readLine()
1440 do while ( .not. df%isEOF() )
1443 srecord = df%readLine()
1446 if ( len_trim(srecord) == 0 ) cycle
1448 call chomp( srecord, sitem, delimiter_chr=
"," )
1449 call this%date_range_id_list%append( sitem )
1451 call chomp( srecord, sitem, delimiter_chr=
"," )
1452 call this%start_date_list%append( sitem )
1454 call chomp( srecord, sitem, delimiter_chr=
"," )
1455 call this%end_date_list%append( sitem )
1457 call this%comparison_grid_file_list%append( srecord )
1469 date_range_id_list, &
1472 zonal_stats_grid_file_list)
1475 character (len=*),
intent(inout) :: csv_filename
1476 type (FSTRING_LIST_T),
intent(out) :: date_range_id_list
1477 type (FSTRING_LIST_T),
intent(out) :: start_date_list
1478 type (FSTRING_LIST_T),
intent(out) :: end_date_list
1479 type (FSTRING_LIST_T),
intent(out) :: zonal_stats_grid_file_list
1482 type (ASCII_FILE_T),
allocatable :: DF
1483 character (len=256) :: sRecord, sItem
1488 call df%open(sfilename = csv_filename, &
1490 scommentchars =
"%#!", &
1494 srecord = df%readLine()
1497 do while ( .not. df%isEOF() )
1500 srecord = df%readLine()
1503 if ( len_trim(srecord) == 0 ) cycle
1505 call chomp( srecord, sitem, delimiter_chr=
"," )
1506 call this%date_range_id_list%append( sitem )
1508 call chomp( srecord, sitem, delimiter_chr=
"," )
1509 call this%start_date_list%append( sitem )
1511 call chomp( srecord, sitem, delimiter_chr=
"," )
1512 call this%end_date_list%append( sitem )
1514 call this%zone_grid_file_list%append( srecord )
1533 unique_zone2_list, &
1537 type (DATETIME_T),
intent(in) :: start_date
1538 type (DATETIME_T),
intent(in) :: end_date
1539 real (c_double),
intent(inout) :: values(:,:)
1540 integer (c_int),
intent(inout) :: zone_ids(:,:)
1541 type (FSTRING_LIST_T),
intent(inout) :: unique_zone_list
1542 character (len=*),
intent(in),
optional :: delimiter
1543 integer (c_int),
intent(in),
optional :: funit
1544 integer (c_int),
intent(inout),
optional :: zone2_ids(:,:)
1545 type (FSTRING_LIST_T),
intent(inout),
optional :: unique_zone2_list
1546 real (c_double),
intent(inout),
optional :: comparison_values(:,:)
1549 integer (c_int) :: n, m
1550 integer (c_int) :: i, j
1551 integer (c_int),
allocatable :: zone_values(:)
1552 integer (c_int),
allocatable :: zone2_values(:)
1553 real (c_double),
allocatable :: stats(:)
1554 integer (c_int) :: funit_l
1555 character (len=:),
allocatable :: delimiter_
1556 character (len=6),
parameter :: NUM_FMT =
"g25.16"
1558 if (
present(funit))
then
1561 funit_l = output_unit
1564 if (
present(delimiter) )
then
1565 delimiter_ = trim(delimiter)
1570 if (
present(zone2_ids) .and.
present(unique_zone2_list))
then
1573 call unique_zone_list%sort_integer()
1574 call unique_zone2_list%sort_integer()
1577 zone_values = unique_zone_list%get_integer()
1578 zone2_values = unique_zone2_list%get_integer()
1580 if (
present(comparison_values))
then
1582 do i=1,ubound(zone_values,1)
1583 do j=1,ubound(zone2_values,1)
1587 result_vector=stats, &
1588 zone2_ids=zone2_ids, &
1589 comparison_values=comparison_values)
1591 write(unit=funit_l, fmt=
"(2(a,a),2(i0,a),4("//num_fmt//
",a),i0,a,4("//num_fmt//
",a),i0)") &
1592 start_date%prettydate(),delimiter_, &
1593 end_date%prettydate(), delimiter_, &
1594 n, delimiter_, m, delimiter_, &
1595 stats(1), delimiter_, stats(2), delimiter_, stats(3), delimiter_, &
1596 stats(4), delimiter_, int(stats(5)), delimiter_, &
1597 stats(6), delimiter_, stats(7), delimiter_, stats(8), delimiter_, &
1598 stats(9), delimiter_, int(stats(10))
1605 do i=1,ubound(zone_values,1)
1606 do j=1,ubound(zone2_values,1)
1611 result_vector=stats, zone2_ids=zone2_ids)
1613 write(unit=funit_l, fmt=
"(2(a,a),2(i0,a),4("//num_fmt//
",a),i0)") &
1614 start_date%prettydate(), delimiter_, &
1615 end_date%prettydate(), delimiter_, &
1616 n, delimiter_, m, delimiter_, &
1617 stats(1), delimiter_, stats(2), delimiter_, stats(3), delimiter_, &
1618 stats(4), delimiter_, int(stats(5))
1626 zone_values = unique_zone_list%get_integer()
1628 if (
present(comparison_values))
then
1630 do i=1,ubound(zone_values,1)
1633 call calc_zonal_stats(values, zone_ids, target_id=n, result_vector=stats, &
1634 comparison_values=comparison_values)
1635 write(unit=funit_l, fmt=
"(2(a,a),i0,a,4("//num_fmt//
",a),i0,a,4("//num_fmt//
",a),i0)") &
1636 start_date%prettydate(), delimiter_, &
1637 end_date%prettydate(), delimiter_, &
1639 stats(1), delimiter_, stats(2), delimiter_, stats(3), delimiter_, &
1640 stats(4), delimiter_, int(stats(5)), delimiter_, &
1641 stats(6), delimiter_, stats(7), delimiter_, stats(8), delimiter_, &
1642 stats(9), delimiter_, int(stats(10))
1648 do i=1,ubound(zone_values,1)
1652 write(unit=funit_l, fmt=
"(2(a,a),i0,a,4("//num_fmt//
",a),i0)") &
1653 start_date%prettydate(), delimiter_, &
1654 end_date%prettydate(), delimiter_, &
1656 stats(1), delimiter_, stats(2), delimiter_, stats(3), delimiter_, &
1657 stats(4), delimiter_, int(stats(5))
1672 type (FILE_COLLECTION_T),
intent(inout) :: OUTPUT_FILES(:)
1675 integer (c_int) :: stat_indx
1676 integer (c_int) :: status
1677 type (T_NETCDF4_FILE),
pointer :: ncfile_out
1678 character (len=:),
allocatable :: units_string
1679 character (len=:),
allocatable :: filename_prefix
1681 if (
allocated( this%output_file_prefix) )
then
1682 filename_prefix = this%output_file_prefix
1684 filename_prefix =
""
1689 if ( .not. output_files(stat_indx)%output_active ) cycle
1691 if (output_files(stat_indx)%write_netcdf)
then
1693 if ( this%annualize_stats .and. stat_indx ==
stats_sum)
then
1694 units_string = trim(this%netcdf_variable_units_string)//
", per year"
1695 elseif (this%report_as_volume)
then
1696 units_string =
"cubic meters"
1697 elseif (this%report_in_meters)
then
1698 units_string =
"meters"
1700 units_string = trim(this%netcdf_variable_units_string)
1703 allocate( output_files(stat_indx)%nc_ptr, stat=status)
1704 call assert( status==0,
"Problem allocating netcdf file data structure.", &
1706 ncfile_out => output_files(stat_indx)%nc_ptr
1709 ncfile=ncfile_out, &
1710 svariablename=trim(this%netcdf_variable_name_string), &
1711 svariableunits=units_string, &
1712 inx=this%ncfile_in%iNX, &
1713 iny=this%ncfile_in%iNY, &
1714 fx=this%ncfile_in%rX_Coords, &
1715 fy=this%ncfile_in%rY_Coords, &
1716 proj4_string=trim(this%target_proj4_string), &
1717 startdate=
sim_dt%start, &
1719 executable_name=
"SWBSTATS2", &
1720 filename_prefix=filename_prefix, &
1721 filename_modifier=this%filename_modifier_string &
1722 //
"_"//output_files(stat_indx)%stats_description )
1735 type (FILE_COLLECTION_T),
intent(inout) :: OUTPUT_FILES(:)
1738 integer (c_int) :: stat_indx
1739 type (T_NETCDF4_FILE),
pointer :: ncfile_out
1743 if ( .not. output_files(stat_indx)%output_active ) cycle
1745 if (output_files(stat_indx)%write_netcdf)
then
1748 svariablename=trim(this%netcdf_variable_name_string), &
1749 sattributename=
'valid_min', &
1750 rattributevalue=[output_files(stat_indx)%valid_min])
1753 svariablename=trim(this%netcdf_variable_name_string), &
1754 sattributename=
'valid_max', &
1755 rattributevalue=[output_files(stat_indx)%valid_max])
1758 svariablename=trim(this%netcdf_variable_name_string), &
1759 sattributename=
'valid_range', &
1760 rattributevalue=[output_files(stat_indx)%valid_min, &
1761 output_files(stat_indx)%valid_max])
1763 ncfile_out => output_files(stat_indx)%nc_ptr
1777 character (len=*) :: filename
1778 character (len=*),
intent(in),
optional :: delimiter
1781 character (len=256) :: header_str
1782 character (len=:),
allocatable :: delimiter_
1784 if (
present(delimiter))
then
1785 delimiter_ = delimiter
1790 call this%zonal_stats_output_file%open(filename)
1792 if (len_trim(this%zone_grid2_filename) > 0)
then
1794 if (this%multiple_comparison_grids .or. this%compare_to_obs_values)
then
1795 header_str =
"start_date"//delimiter_//
"end_date"//delimiter_//
"zone_id" &
1796 //delimiter_//
"zone2_id"//delimiter_//
"minimum_swb"//delimiter_ &
1797 //
"maximum_swb"//delimiter_//
"mean_swb"//delimiter_//
"sum_swb" &
1798 //delimiter_//
"count_swb"//delimiter_//
"minimum_obs"//delimiter_ &
1799 //
"maximum_obs"//delimiter_//
"mean_obs"//delimiter_//
"sum_obs" &
1800 //delimiter_//
"count_obs"
1802 header_str =
"start_date"//delimiter_//
"end_date"//delimiter_//
"zone_id" &
1803 //delimiter_//
"zone2_id"//delimiter_//
"minimum_swb"//delimiter_ &
1804 //
"maximum_swb"//delimiter_//
"mean_swb"//delimiter_//
"sum_swb" &
1805 //delimiter_//
"count_swb"
1810 if (this%multiple_comparison_grids .or. this%compare_to_obs_values)
then
1812 header_str =
"start_date"//delimiter_//
"end_date"//delimiter_//
"zone_id" &
1813 //delimiter_//
"minimum_swb"//delimiter_ &
1814 //
"maximum_swb"//delimiter_//
"mean_swb"//delimiter_//
"sum_swb" &
1815 //delimiter_//
"count_swb"//delimiter_//
"minimum_obs"//delimiter_ &
1816 //
"maximum_obs"//delimiter_//
"mean_obs"//delimiter_//
"sum_obs" &
1817 //delimiter_//
"count_obs"
1821 header_str =
"start_date"//delimiter_//
"end_date"//delimiter_//
"zone_id" &
1822 //delimiter_//
"minimum_swb"//delimiter_ &
1823 //
"maximum_swb"//delimiter_//
"mean_swb"//delimiter_//
"sum_swb" &
1824 //delimiter_//
"count_swb"
1830 call this%zonal_stats_output_file%writeLine(trim(header_str))
1841 character (len=:),
allocatable :: fmt_string
1843 write(*,fmt=
"(/,/,a)")
" :: Dump of swbstats2 program this ::"
1844 write(*,fmt=
"(a,/)") repeat(
"-", 43)
1846 fmt_string =
"(a,t30,': ',l)"
1847 write(*,fmt=fmt_string)
"write_csv", this%write_csv
1858 fmt_string =
"(a,t40,': ',l)"
1859 write(*,fmt=fmt_string)
"grid pointer allocated? (SUM)",
associated(
output_files(
stats_sum)%grid_ptr)
1863 fmt_string =
"(a,t30,': ',l)"
1864 write(*,fmt=fmt_string)
"calc_zonal_stats", this%calc_zonal_stats
1865 write(*,fmt=fmt_string)
"compare_to_obs_values", this%compare_to_obs_values
1866 write(*,fmt=fmt_string)
"annualize_stats", this%annualize_stats
1868 fmt_string =
"(a,t30,': ',a)"
1869 write(*,fmt=fmt_string)
"target_proj4_string", this%target_proj4_string
1870 write(*,fmt=fmt_string)
"data_start_date", this%data_start_date%prettydate()
1871 write(*,fmt=fmt_string)
"data_end_date", this%data_end_date%prettydate()
1872 write(*,fmt=fmt_string)
"slice_start_date", this%slice_start_date%prettydate()
1873 write(*,fmt=fmt_string)
"slice_end_date", this%slice_end_date%prettydate()
1876 fmt_string =
"(a,t30,': ',i0)"
1877 write(*,fmt=fmt_string)
"input grid bounds, nx",
bnds%iNumCols
1878 write(*,fmt=fmt_string)
"input grid bounds, ny",
bnds%iNumRows
1880 fmt_string =
"(a,t35,': ',f16.5)"
1881 write(*,fmt=fmt_string)
"input grid bounds, X_ll",
bnds%fX_ll
1882 write(*,fmt=fmt_string)
"input grid bounds, Y_ll",
bnds%fY_ll
1883 write(*,fmt=fmt_string)
"input grid bounds, X_ur",
bnds%fX_ur
1884 write(*,fmt=fmt_string)
"input grid bounds, Y_ur",
bnds%fY_ur
1885 write(*,fmt=fmt_string)
"input grid bounds, grid-cell size",
bnds%fGridCellSize
1887 fmt_string =
"(a,t30,': ',i0)"
1888 write(*,fmt=fmt_string)
"calculation_time_period", this%calculation_time_period
1890 fmt_string =
"(a,t30,': ',a)"
1891 write(*,fmt=fmt_string)
"stress_period_filename", this%stress_period_filename
1892 write(*,fmt=fmt_string)
"comparison_period_filename", this%comparison_period_filename
1893 write(*,fmt=fmt_string)
"zone_period_filename", this%zone_period_filename
1894 write(*,fmt=fmt_string)
"comparison_grid_filename", this%comparison_grid_filename
1895 write(*,fmt=fmt_string)
"zone_grid_filename", this%zone_grid_filename
1896 write(*,fmt=fmt_string)
"netcdf_input_filename", this%netcdf_input_filename
1897 write(*,fmt=fmt_string)
"netcdf_variable_name_string", this%netcdf_variable_name_string
1898 write(*,fmt=fmt_string)
"netcdf_variable_units_string", this%netcdf_variable_units_string
1900 fmt_string =
"(a,t30,': ',l)"
1901 write(*,fmt=fmt_string)
"netcdf_input_file_is_open : ", this%netcdf_input_file_is_open
1902 write(*,fmt=fmt_string)
"multiple_zone_grids : ", this%multiple_zone_grids
1903 write(*,fmt=fmt_string)
"multiple_comparison_grids : ", this%multiple_comparison_grids
1905 fmt_string =
"(/,a,/,'"//repeat(
"-",62)//
"')"
1906 write(*,fmt=fmt_string)
"Start date list"
1907 call this%start_date_list%print()
1908 write(*,fmt=fmt_string)
"End date list"
1909 call this%end_date_list%print()
1910 write(*,fmt=fmt_string)
"Date index list"
1911 call this%date_range_id_list%print()
1912 write(*,fmt=fmt_string)
"Unique zone id list"
1913 call this%unique_zone_list%print()
1914 write(*,fmt=fmt_string)
"Comparison grid file list"
1915 call this%comparison_grid_file_list%print()
1916 write(*,fmt=fmt_string)
"Zone grid file list"
1917 call this%zone_grid_file_list%print()
1925 real (c_float),
intent(in) :: current_minimum
1926 real (c_float),
intent(in) :: values(:,:)
1928 real (c_float) :: new_minimum
1930 new_minimum = min(current_minimum, minval(values))
1938 real (c_float),
intent(in) :: current_maximum
1939 real (c_float),
intent(in) :: values(:,:)
1941 real (c_float) :: new_maximum
1943 new_maximum = max(current_maximum, maxval(values))
This module contains physical constants and convenience functions aimed at performing unit conversion...
logical(c_bool), parameter, public true
character(len=1) os_native_path_delimiter
type(bounds_t), public bnds
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,...
type(month_t), dimension(12), target, public months
Month information.
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 ...
real(c_float), parameter nc_fill_float
subroutine, public grid_writearcgrid(sfilename, pgrd)
integer(c_int), parameter, public grid_datatype_double
Provide support for use of netCDF files as input for time-varying, gridded meteorlogic data,...
integer(c_int), parameter, public nc_bottom
subroutine, public netcdf_open_and_prepare_as_output(ncfile, svariablename, svariableunits, inx, iny, fx, fy, startdate, enddate, proj4_string, history_list, executable_name, dplat, dplon, fvalidmin, fvalidmax, write_time_bounds, filename_prefix, filename_modifier)
integer(c_int), parameter, public nc_top
integer(c_int), parameter, public nc_right
subroutine, public netcdf_get_variable_slice(ncfile, rvalues, dpvalues, ivalues)
subroutine, public netcdf_close_file(ncfile)
integer(c_int), parameter, public nc_time
@TODO: implement a more flexible way of tracking variable IDs; presently the code can break if lat an...
integer(c_int), parameter, public nc_left
subroutine, public netcdf_put_variable_array(ncfile, ivarid, istart, icount, istride, ivalues, i2values, rvalues, dpvalues)
subroutine, public netcdf_put_variable_vector(ncfile, ivarid, istart, icount, istride, ivalues, i2values, rvalues, dpvalues)
logical(c_bool) function, public netcdf_update_time_starting_index(ncfile, ijulianday)
integer(c_int), parameter, public nc_z
subroutine, public netcdf_rewrite_attribute(ncfile, svariablename, sattributename, sattributevalue, iattributevalue, rattributevalue, dpattributevalue)
type(date_range_t), public sim_dt
subroutine initialize_zone_grid(this, grid_filename)
type(length_unit_t), dimension(3), parameter length_units
subroutine write_stats_to_netcdf(this, output_files, start_date, end_date)
subroutine create_date_list_for_monthly_statistics(this)
subroutine close_output_netcdf_files(this, output_files)
subroutine create_working_grids(this)
type(running_stats_t) rstat
subroutine calculate_monthly_statistics(this, month_num, finalize)
type(data_catalog_entry_t) input_data_obj
subroutine write_monthly_stats_to_arcgrid(this, output_files, date_range_string, output_file_prefix)
type(file_collection_t), dimension(39) output_files
type(running_stats_t), dimension(12) mon_stat
subroutine print_all_options(this)
subroutine initialize_comparison_grid(this, grid_filename)
subroutine create_date_list_for_period_statistics(this, start_date, end_date)
subroutine create_date_list_for_annual_statistics(this)
subroutine create_monthly_working_grids(this)
subroutine read_zone_period_file(this, csv_filename, date_range_id_list, start_date_list, end_date_list, zonal_stats_grid_file_list)
subroutine create_date_list_for_daily_statistics(this)
subroutine get_unique_int(this, grid_values, unique_val_list)
subroutine open_output_netcdf_files(this, output_files)
subroutine output_zonal_stats(this, start_date, end_date, values, zone_ids, unique_zone_list, delimiter, funit, zone2_ids, unique_zone2_list, comparison_values)
subroutine write_stats_to_arcgrid(this, output_files, start_date, end_date, date_range_string, output_file_prefix)
type(volume_unit_t), dimension(3), parameter volume_units
subroutine calc_multizonal_stats(values, zone_ids, zone2_ids, target_id, target2_id, result_vector, comparison_values)
subroutine initialize_secondary_zone_grid(this, grid_filename)
subroutine set_conversion_factors_sub(this)
pure real(c_float) function update_maximum_value(current_maximum, values)
@ calc_period_slice_single
@ calc_period_slice_multiple
subroutine read_comparison_period_file(this, csv_filename, date_range_id_list, start_date_list, end_date_list, comparison_grid_file_list)
pure real(c_float) function update_minimum_value(current_minimum, values)
subroutine read_date_range_file(this, csv_filename, date_range_id_list, start_date_list, end_date_list)
subroutine calculate_slice_statistics(this, start_date, end_date, grd_sum, grd_mean, grd_var)
subroutine open_zonal_stats_output_file(this, filename, delimiter)
subroutine calc_zonal_stats(values, zone_ids, target_id, result_vector, comparison_values)