24 module drifters_input_mod
29 public :: drifters_input_type, drifters_input_new, drifters_input_del, drifters_input_save,
assignment(=)
32 integer,
parameter,
private :: MAX_STR_LEN = 128
34 #include<file_version.h>
35 character,
parameter,
private :: SEPARATOR =
' '
43 type drifters_input_type
46 character(len=MAX_STR_LEN),
allocatable :: position_names(:)
47 character(len=MAX_STR_LEN),
allocatable :: position_units(:)
48 character(len=MAX_STR_LEN),
allocatable :: field_names(:)
49 character(len=MAX_STR_LEN),
allocatable :: field_units(:)
50 character(len=MAX_STR_LEN),
allocatable :: velocity_names(:)
51 real ,
allocatable :: positions(:,:)
52 integer ,
allocatable :: ids(:)
53 character(len=MAX_STR_LEN) :: time_units
54 character(len=MAX_STR_LEN) :: title
55 character(len=MAX_STR_LEN) :: version
56 end type drifters_input_type
60 interface assignment(=)
61 module procedure drifters_input_copy_new
71 subroutine drifters_input_new(self, filename, ermesg)
74 use netcdf_nf_interfaces
75 type(drifters_input_type) :: self
76 character(len=*),
intent(in) :: filename
77 character(len=*),
intent(out):: ermesg
80 integer :: ier, ncid, nd, nf, np, ipos, j, id, i, isz
81 character(len=MAX_STR_LEN) :: attribute
85 ier = nf_open(filename, nf_nowrite, ncid)
86 if(ier/=nf_noerr)
then
87 ermesg =
'drifters_input: ERROR could not open netcdf file '//filename
92 ier = nf_put_att_text(ncid, nf_global,
'version', len(version), version)
94 ier = nf_inq_dimid(ncid,
'nd', id)
95 if(ier/=nf_noerr)
then
96 ermesg =
'drifters_input: ERROR could not find "nd" (number of dimensions)'
100 ier = nf_inq_dimlen(ncid, id, nd)
104 ier = nf_get_att_text(ncid, nf_global,
'field_names', attribute)
105 isz = min(len(attribute), len(trim(attribute))+1)
106 attribute(isz:isz) =
' '
110 if(attribute(i:i)==separator)
then
115 ier = nf_inq_dimid(ncid,
'np', id)
116 if(ier/=nf_noerr)
then
117 ermesg =
'drifters_input: ERROR could not find "np" (number of particles)'
121 ier = nf_inq_dimlen(ncid, id, np)
123 allocate(self%position_names(nd))
124 allocate(self%position_units(nd))
125 allocate(self%field_names(nf))
126 allocate(self%field_units(nf))
127 allocate(self%velocity_names(nd))
128 allocate(self%ids(np))
129 allocate(self%positions(nd, np))
131 ier = nf_inq_varid(ncid,
'ids', id)
132 if(ier/=nf_noerr)
then
133 ermesg =
'drifters_input: ERROR could not find "ids"'
137 ier = nf_get_var_int(ncid, id, self%ids)
139 ier = nf_inq_varid(ncid,
'positions', id)
140 if(ier/=nf_noerr)
then
141 ermesg =
'drifters_input: ERROR could not find "positions"'
145 ier = nf90_get_var(ncid, id, self%positions)
148 ier = nf_get_att_text(ncid, nf_global,
'version', attribute)
149 self%version = trim(attribute)
152 ier = nf_get_att_text(ncid, nf_global,
'time_units', attribute)
153 self%time_units = trim(attribute)
156 ier = nf_get_att_text(ncid, nf_global,
'title', attribute)
157 self%title = trim(attribute)
160 ier = nf_get_att_text(ncid, id,
'names', attribute)
161 isz = min(len(attribute), len(trim(attribute))+1)
162 attribute(isz:isz) =
' '
166 if(attribute(i:i)==separator)
then
167 self%position_names(j) = trim(adjustl(attribute(ipos:i-1)))
175 ier = nf_get_att_text(ncid, id,
'units', attribute)
176 isz = min(len(attribute), len(trim(attribute))+1)
177 attribute(isz:isz) =
' '
181 if(attribute(i:i)==separator)
then
182 self%position_units(j) = trim(adjustl(attribute(ipos:i-1)))
190 ier = nf_get_att_text(ncid, nf_global,
'field_names', attribute)
191 isz = min(len(attribute), len(trim(attribute))+1)
192 attribute(isz:isz) =
' '
196 if(attribute(i:i)==separator)
then
197 self%field_names(j) = trim(adjustl(attribute(ipos:i-1)))
205 ier = nf_get_att_text(ncid, nf_global,
'field_units', attribute)
206 isz = min(len(attribute), len(trim(attribute))+1)
207 attribute(isz:isz) =
' '
211 if(attribute(i:i)==separator)
then
212 self%field_units(j) = trim(adjustl(attribute(ipos:i-1)))
220 ier = nf_get_att_text(ncid, nf_global,
'velocity_names', attribute)
221 isz = min(len(attribute), len(trim(attribute))+1)
222 attribute(isz:isz) =
' '
226 if(attribute(i:i)==separator)
then
227 self%velocity_names(j) = trim(adjustl(attribute(ipos:i-1)))
234 end subroutine drifters_input_new
237 subroutine drifters_input_del(self, ermesg)
238 type(drifters_input_type) :: self
239 character(len=*),
intent(out):: ermesg
245 deallocate(self%position_names, stat=iflag)
246 deallocate(self%position_units, stat=iflag)
247 deallocate(self%field_names, stat=iflag)
248 deallocate(self%field_units, stat=iflag)
249 deallocate(self%velocity_names, stat=iflag)
250 deallocate(self%ids, stat=iflag)
251 deallocate(self%positions, stat=iflag)
253 end subroutine drifters_input_del
256 subroutine drifters_input_copy_new(new_instance, old_instance)
258 type(drifters_input_type),
intent(inout) :: new_instance
259 type(drifters_input_type),
intent(in) :: old_instance
261 allocate(new_instance%position_names(
size(old_instance%position_names) ))
262 allocate(new_instance%position_units(
size(old_instance%position_units) ))
263 allocate(new_instance%field_names(
size(old_instance%field_names) ))
264 allocate(new_instance%field_units(
size(old_instance%field_units) ))
265 allocate(new_instance%velocity_names(
size(old_instance%velocity_names) ))
266 new_instance%position_names = old_instance%position_names
267 new_instance%position_units = old_instance%position_units
268 new_instance%field_names = old_instance%field_names
269 new_instance%field_units = old_instance%field_units
270 new_instance%velocity_names = old_instance%velocity_names
271 new_instance%time_units = old_instance%time_units
272 new_instance%title = old_instance%title
273 new_instance%version = old_instance%version
274 allocate(new_instance%positions(
size(old_instance%positions,1),
size(old_instance%positions,2) ))
275 new_instance%positions = old_instance%positions
276 allocate(new_instance%ids(
size(old_instance%ids)))
277 new_instance%ids = old_instance%ids
279 end subroutine drifters_input_copy_new
283 subroutine drifters_input_save(self, filename, geolon, geolat, ermesg)
287 use netcdf_nf_interfaces
288 type(drifters_input_type) :: self
289 character(len=*),
intent(in ):: filename
290 real,
intent(in),
optional :: geolon(:), geolat(:)
291 character(len=*),
intent(out):: ermesg
294 integer ncid, nc_nd, nc_np, ier, nd, np, nf, nc_pos, nc_ids, i, j, n
295 integer nc_lon, nc_lat
296 character(len=MAX_STR_LEN) :: att
301 ier = nf_create(filename, nf_clobber, ncid)
302 if(ier/=nf_noerr)
then
303 ermesg =
'drifters_input: ERROR cannot create '//filename
307 nd =
size(self%positions, 1)
308 np =
size(self%positions, 2)
309 nf =
size(self%field_names)
312 ier = nf_def_dim(ncid,
'nd', nd, nc_nd)
313 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating dim "nd" '//nf_strerror(ier)
315 ier = nf_def_dim(ncid,
'np', np, nc_np)
316 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating dim "np" '//nf_strerror(ier)
319 ier = nf_put_att_text(ncid, nf_global,
'title', len_trim(self%title), self%title)
320 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "title" ' &
323 ier = nf_put_att_text(ncid, nf_global,
'time_units', len_trim(self%time_units), self%time_units)
324 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "time_units" ' &
330 n = len_trim(self%field_units(i))
331 att(j:j+n+1) = trim(self%field_units(i)) //
' '
334 ier = nf_put_att_text(ncid, nf_global,
'field_units', len_trim(att), &
336 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "field_units" ' &
342 n = len_trim(self%field_names(i))
343 att(j:j+n+1) = trim(self%field_names(i)) //
' '
346 ier = nf_put_att_text(ncid, nf_global,
'field_names', len_trim(att), &
348 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "field_names" ' &
354 n = len_trim(self%velocity_names(i))
355 att(j:j+n+1) = trim(self%velocity_names(i)) //
' '
358 ier = nf_put_att_text(ncid, nf_global,
'velocity_names', len_trim(att), &
360 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting global att "velocity_names" ' &
364 ier = nf_def_var(ncid,
'positions', nf_double, 2, (/nc_nd, nc_np/), nc_pos)
365 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "positions" '//nf_strerror(ier)
367 ier = nf_def_var(ncid,
'ids', nf_int, 1, (/nc_np/), nc_ids)
368 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "ids" '//nf_strerror(ier)
371 if(
present(geolon))
then
372 ier = nf_def_var(ncid,
'longitude', nf_double, 1, (/nc_np/), nc_lon)
373 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "longitude" ' &
376 ier = nf_put_att_text(ncid, nc_lon,
'units', len(trim(att)), trim(att))
377 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "longitude" ' &
380 if(
present(geolat))
then
381 ier = nf_def_var(ncid,
'latitude', nf_double, 1, (/nc_np/), nc_lat)
382 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR creating var "latitude" ' &
384 att =
'degrees_north'
385 ier = nf_put_att_text(ncid, nc_lat,
'units', len(trim(att)), trim(att))
386 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "latitude" ' &
395 n = len_trim(self%position_units(i))
396 att(j:j+n+1) = trim(self%position_units(i)) //
' '
399 ier = nf_put_att_text(ncid, nc_pos,
'units', len_trim(att), &
401 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "units" to "positions" ' &
407 n = len_trim(self%position_names(i))
408 att(j:j+n+1) = trim(self%position_names(i)) //
' '
411 ier = nf_put_att_text(ncid, nc_pos,
'names', len_trim(att), &
413 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR setting att "names" to "positions" ' &
417 ier = nf_enddef(ncid)
418 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not end define mode ' &
422 ier = nf90_put_var(ncid, nc_pos, self%positions)
423 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "positions" ' &
426 ier = nf90_put_var(ncid, nc_ids, self%ids)
427 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "ids" ' &
430 if(
present(geolon))
then
431 ier = nf90_put_var(ncid, nc_lon, geolon)
432 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "geolon" ' &
435 if(
present(geolat))
then
436 ier = nf90_put_var(ncid, nc_lat, geolat)
437 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not write "geolat" ' &
443 if(ier/=nf_noerr) ermesg =
'drifters_input_save: ERROR could not close file ' &
446 end subroutine drifters_input_save
448 end module drifters_input_mod