25 use netcdf,
only: nf90_inquire_attribute, nf90_get_att, &
26 nf90_put_att, nf90_open, nf90_close, nf90_inquire, &
27 nf90_inq_attname, nf90_inquire_dimension, &
28 nf90_inquire_variable, nf90_def_dim, nf90_def_var, &
29 nf90_def_var_chunking, nf90_def_var_deflate, &
30 nf90_byte, nf90_short, nf90_int, nf90_float, nf90_double, &
31 nf90_char, nf90_fill_byte, nf90_fill_short, nf90_fill_int, &
32 nf90_fill_float, nf90_fill_double, nf90_fill_char, &
33 nf90_global, nf90_nowrite, nf90_enotatt, &
34 nf90_noerr, nf90_max_name, nf90_unlimited, nf90_chunked
41 character(len=*),
intent(in) :: attr_name
42 integer(i_long),
intent(in) :: var_id_in
43 integer(i_long),
intent(in),
optional :: var_id_out
45 integer(i_byte),
dimension(:),
allocatable :: byte_arr
46 integer(i_short),
dimension(:),
allocatable :: short_arr
47 integer(i_long),
dimension(:),
allocatable :: long_arr
48 real(r_single),
dimension(:),
allocatable :: rsingle_arr
49 real(r_double),
dimension(:),
allocatable :: rdouble_arr
50 character(len=:),
allocatable :: string_arr
52 integer(i_long) :: attr_type, attr_len, final_var_id_out
55 xtype = attr_type, len = attr_len))
57 if (.NOT.
present(var_id_out))
then 58 if (var_id_in /= nf90_global) &
59 call ncdc_error(
"BUG! var_id_out not specified even when var_id_in is var-specific!")
60 final_var_id_out = var_id_in
62 final_var_id_out = var_id_out
65 if (attr_type == nf90_byte)
then 66 allocate(byte_arr(attr_len))
70 else if (attr_type == nf90_short)
then 71 allocate(short_arr(attr_len))
75 else if (attr_type == nf90_int)
then 76 allocate(long_arr(attr_len))
80 else if (attr_type == nf90_float)
then 81 allocate(rsingle_arr(attr_len))
84 deallocate(rsingle_arr)
85 else if (attr_type == nf90_double)
then 86 allocate(rdouble_arr(attr_len))
89 deallocate(rdouble_arr)
90 else if (attr_type == nf90_char)
then 91 allocate(
character(len=attr_len) :: string_arr)
94 deallocate(string_arr)
96 call ncdc_error(
"Unable to copy attribute for unknown type!")
101 character(len=1000) :: err_string
102 integer(i_long) :: old_dim_arr_total = 0, old_var_arr_total = 0
104 integer(i_long) :: tmp_dim_index, tmp_attr_index
105 integer(i_long) :: input_ndims, cached_ndims = -1
106 integer(i_long) :: input_nvars, cached_nvars = -1
107 integer(i_long) :: input_nattrs
109 character(len=NF90_MAX_NAME) :: tmp_var_name
110 integer(i_long) :: tmp_var_type, tmp_var_ndims
111 integer(i_long),
dimension(:),
allocatable :: tmp_var_dimids
112 character(len=NF90_MAX_NAME) ,
allocatable :: tmp_var_dim_names(:)
114 integer(i_long),
dimension(:),
allocatable :: unlim_dims
115 logical :: is_unlim = .false.
117 character(len=NF90_MAX_NAME) :: tmp_dim_name, tmp_attr_name
118 integer(i_long) :: tmp_dim_size
120 integer(i_long) :: arg_index, var_index, i
122 integer(i_long) :: nc_err
124 character(:),
allocatable :: input_file_cut
132 call ncdc_info(
"Scanning NetCDF files for dimensions and variables...")
136 call get_command_argument(2 + arg_index,
input_file)
140 if (len(input_file_cut) <= 0)
then 141 call ncdc_usage(
"Invalid input file name - likely blank!")
145 call ncdc_warning(
" -> Ignoring output file in input file list.")
146 call ncdc_info(
" -> Skipping " // input_file_cut //
" since it is the output file...")
152 call ncdc_info(
" -> Opening " // input_file_cut //
" for reading...")
159 nvariables = input_nvars, nattributes = input_nattrs))
162 if (cur_proc == 0)
then 165 do tmp_attr_index = 1, input_nattrs
169 nf90_global, trim(tmp_attr_name))
172 if (nc_err == nf90_enotatt)
then 174 else if (nc_err /= nf90_noerr)
then 183 write (*,
"(A, I0)")
"Number of dimensions: ", input_ndims
186 if (cached_ndims == -1) &
187 cached_ndims = input_ndims
190 if (input_ndims == 0)
then 192 call ncdc_warning(
"No dimensions found in file " // input_file_cut //
"! Skipping file...")
199 if (input_nvars == 0) &
200 call ncdc_warning(
"No variables found in file " // input_file_cut //
"!")
202 if (cached_ndims /= input_ndims) &
210 write (*,
"(A, I0)")
"Number of unlimited dimensions: ",
num_unlims 218 do tmp_dim_index = 1, input_ndims
220 tmp_dim_name, tmp_dim_size))
225 if (tmp_dim_index == unlim_dims(i))
then 233 write (*,
"(A, I0, A, I0, A)")
" => Dimension #", tmp_dim_index,
": " // &
234 trim(tmp_dim_name) //
" (size: ", &
241 write (*,
"(A, I0, A, I0, A)")
" => Dimension #", tmp_dim_index,
": " // &
242 trim(tmp_dim_name) //
" (size: ", &
250 deallocate(unlim_dims)
254 write (*,
"(A, I0)")
"Number of variables: ", input_nvars
257 if (cached_nvars == -1) cached_nvars = input_nvars
259 if (cached_nvars /= input_nvars) &
263 if (input_nvars == 0)
then 269 do var_index = 1, input_nvars
272 ndims = tmp_var_ndims, xtype = tmp_var_type))
275 allocate(tmp_var_dimids(tmp_var_ndims))
276 allocate(tmp_var_dim_names(tmp_var_ndims))
281 xtype = tmp_var_type))
283 if ((tmp_var_ndims <= 2) .OR. &
284 ((tmp_var_ndims == 3) .AND. (tmp_var_type == nf90_char)))
then 287 write (*,
"(A, I0, A, I0)")
" => Variable #", var_index,
": " // &
289 write (*,
"(A)", advance =
"NO")
" => Dimension IDs: " 291 do i = 1, tmp_var_ndims
292 if (i /= 1)
write (*,
"(A)", advance =
"NO")
", " 293 write (*,
"(I0)", advance =
"NO") tmp_var_dimids(i)
298 write (*,
"(A)", advance =
"NO")
" => Dimensions: " 301 do i = 1, tmp_var_ndims
303 if (i /= 1)
write (*,
"(A)", advance =
"NO")
", " 307 write (*,
"(A)", advance =
"NO") trim(tmp_var_dim_names(i))
317 write (err_string,
"(A, I0, A)") &
318 "Variables with >2 dimensions NOT supported." // &
320 "(Variable '" // trim(tmp_var_name) //
"' has ", &
326 deallocate(tmp_var_dimids)
327 deallocate(tmp_var_dim_names)
331 write (*,
"(A)")
" => For all variables, the order of dimensions are INVERTED!" 343 integer(i_long) :: i, j
345 call ncdc_info(
"Creating new dimensions and variables for output file...")
347 call ncdc_info(
" -> Defining dimensions...")
350 call ncdc_warning(
"No dimensions found in input files, so not defining anything.")
361 write(*,
"(A, I0, A, I0)")
"STORED DIMID for dim " // trim(
dim_names(i)) //
": ", &
367 call ncdc_warning(
"No variables found in input files, so not defining anything.")
369 call ncdc_info(
" -> Defining variables...")
375 write(*,
"(A, I0)")
"Paired ID for dim " // trim(
var_dim_names(i)%dim_names(j)) //
": ", &
381 write (*,
"(A, I0, A)")
"Defining variable: " // trim(
var_names(i)) //
" (type = ",
var_types(i),
")" 383 print *,
"var_dim_names(i)%output_dim_ids",
var_dim_names(i)%output_dim_ids
384 print *,
"LEN var_dim_names(i)%output_dim_ids",
size(
var_dim_names(i)%output_dim_ids)
435 integer(i_long),
dimension(3) :: alloc_dim_sizes = 0
439 call ncdc_info(
" -> Allocating data storage for variables...")
445 alloc_dim_sizes = (/ &
451 if (alloc_dim_sizes(1) == -1) &
452 alloc_dim_sizes(1) = &
455 if (
var_types(i) == nf90_byte)
allocate(data_blobs(i)%byte_buffer(alloc_dim_sizes(1)))
456 if (
var_types(i) == nf90_short)
allocate(data_blobs(i)%short_buffer(alloc_dim_sizes(1)))
457 if (
var_types(i) == nf90_int)
allocate(data_blobs(i)%long_buffer(alloc_dim_sizes(1)))
458 if (
var_types(i) == nf90_float)
allocate(data_blobs(i)%rsingle_buffer(alloc_dim_sizes(1)))
459 if (
var_types(i) == nf90_double)
allocate(data_blobs(i)%rdouble_buffer(alloc_dim_sizes(1)))
460 if (
var_types(i) == nf90_char)
call ncdc_error(
"1D character variable type not supported!")
462 if (
var_types(i) == nf90_byte) data_blobs(i)%byte_buffer = nf90_fill_byte
463 if (
var_types(i) == nf90_short) data_blobs(i)%short_buffer = nf90_fill_short
464 if (
var_types(i) == nf90_int) data_blobs(i)%long_buffer = nf90_fill_int
465 if (
var_types(i) == nf90_float) data_blobs(i)%rsingle_buffer = nf90_fill_float
466 if (
var_types(i) == nf90_double) data_blobs(i)%rdouble_buffer = nf90_fill_double
468 alloc_dim_sizes = (/ &
474 if (alloc_dim_sizes(2) == -1) &
475 alloc_dim_sizes(2) = &
478 if (
var_types(i) == nf90_byte)
allocate(data_blobs(i)%byte_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
479 if (
var_types(i) == nf90_short)
allocate(data_blobs(i)%short_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
480 if (
var_types(i) == nf90_int)
allocate(data_blobs(i)%long_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
481 if (
var_types(i) == nf90_float)
allocate(data_blobs(i)%rsingle_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
482 if (
var_types(i) == nf90_double)
allocate(data_blobs(i)%rdouble_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
483 if (
var_types(i) == nf90_char)
allocate(data_blobs(i)%string_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2)))
485 if (
var_types(i) == nf90_byte) data_blobs(i)%byte_2d_buffer = nf90_fill_byte
486 if (
var_types(i) == nf90_short) data_blobs(i)%short_2d_buffer = nf90_fill_short
487 if (
var_types(i) == nf90_int) data_blobs(i)%long_2d_buffer = nf90_fill_int
488 if (
var_types(i) == nf90_float) data_blobs(i)%rsingle_2d_buffer = nf90_fill_float
489 if (
var_types(i) == nf90_double) data_blobs(i)%rdouble_2d_buffer = nf90_fill_double
490 if (
var_types(i) == nf90_char) data_blobs(i)%string_buffer = nf90_fill_char
493 alloc_dim_sizes = (/ &
500 if (alloc_dim_sizes(3) == -1) &
501 alloc_dim_sizes(3) = &
505 allocate(data_blobs(i)%string_2d_buffer(alloc_dim_sizes(1), alloc_dim_sizes(2), alloc_dim_sizes(3)))
506 data_blobs(i)%string_2d_buffer = nf90_fill_char
508 call ncdc_error(
"3D non-character variable type not supported!")
512 data_blobs(i)%alloc_size = alloc_dim_sizes
517 print *,
"!! END DEFINITION PASS" integer(i_long) var_arr_total
integer(i_long), dimension(:), allocatable dim_output_ids
integer(i_long), parameter nc_diag_cat_gzip_compress
integer, parameter, public i_byte
character(len=10000000) output_file
subroutine nc_diag_cat_metadata_add_dim(dim_name, dim_size, dim_ul_size)
integer(c_int) function pf_nf90_inq_unlimdims(ncid, num_unlim_dims, unlim_dims)
integer(i_long), dimension(:), allocatable var_types
integer, parameter, public i_long
character(len=100), dimension(:), allocatable dim_names
integer(i_long) cli_arg_count
subroutine ncdc_usage(err)
integer(i_long), parameter nc_diag_cat_chunk_size
integer(i_long) function nc_diag_cat_lookup_dim(dim_name)
character(len=100), dimension(:), allocatable var_names
integer(i_long) ncid_output
subroutine ncdc_error(err)
integer(i_long) ncid_input
subroutine ncdc_info(ifo)
subroutine ncdc_warning(warn)
integer(i_long), dimension(:), allocatable dim_unlim_sizes
integer(i_long) input_count
subroutine ncdc_check(status)
subroutine nc_diag_cat_metadata_add_var(var_name, var_type, var_ndims, var_dims)
logical, dimension(:), allocatable var_hasunlim
integer, parameter, public i_short
type(nc_diag_cat_dim_names), dimension(:), allocatable var_dim_names
integer(i_long), dimension(:), allocatable var_output_ids
integer(i_long) dim_arr_total
integer, parameter, public r_double
integer, parameter, public r_single
integer(i_long), dimension(:), allocatable dim_sizes
character(len=10000000) input_file
integer(i_long) num_unlims