[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[netCDF #AOX-617597]: 2D character string array (Fortran 90)
- Subject: [netCDF #AOX-617597]: 2D character string array (Fortran 90)
- Date: Fri, 08 May 2009 14:13:27 -0600
Ruslan,
> Could you explain the same for f77 interface (NF_PUT_VAR_TEXT,
> NF_PUT_VARA_TEXT). Some people are still using it. I'm just
> guessing if 1D array should be treated as 2D array where the second
> dimension is the length of character string should the same logic be
> applied to 2D array?
No, actually all that matters is that the characters are contiguous in
memory. Before presenting an F77 example, here's the f90 example
with a third variable for which a 2D array is output:
-------------------------
program chartst
use netcdf
integer :: ncid, var1id, var2id, var3id, dim1id, dim2id
character (len = 1), dimension (15) :: ch = (/'a', 'b', 'c', 'd', 'e', &
'f', 'g', 'h', 'i', 'j', &
'k', 'l', 'm', 'n', 'o' /)
character (len = 15) :: ch15 = "abcdefghijklmno"
character (len = 5), dimension(3) :: ch5 = (/"abcde","fghij","klmno" /)
call check(nf90_create('CharTest.nc', nf90_clobber, ncid))
call check(nf90_def_dim(ncid, 'Dim1', 5, dim1id))
call check(nf90_def_dim(ncid, 'Dim2', 3, dim2id))
call check(nf90_def_var(ncid, 'Var1', nf90_char, (/dim1id, dim2id/), var1id))
call check(nf90_def_var(ncid, 'Var2', nf90_char, (/dim2id, dim1id/), var2id))
call check(nf90_def_var(ncid, 'Var3', nf90_char, (/dim1id, dim2id/), var3id))
call check(nf90_enddef(ncid))
call check(nf90_put_var(ncid, var1id, ch, start=(/ 1, 1/), count=(/ 5, 3 /)))
call check(nf90_put_var(ncid, var2id, ch15, start=(/ 1, 1/), count=(/ 3, 5 /)))
call check(nf90_put_var(ncid, var3id, ch5, start=(/ 1, 1/), count=(/ 5, 3 /)))
call check(nf90_close(ncid))
contains
subroutine check(status)
integer, intent ( in) :: status
if(status /= nf90_noerr) then
print *, trim(nf90_strerror(status))
stop 2
end if
end subroutine check
end program chartst
-------------------------
The ncdump output from the resulting file looks like this:
$ ncdump CharTest.nc
netcdf CharTest {
dimensions:
Dim1 = 5 ;
Dim2 = 3 ;
variables:
char Var1(Dim2, Dim1) ;
char Var2(Dim1, Dim2) ;
char Var3(Dim2, Dim1) ;
data:
Var1 =
"abcde",
"fghij",
"klmno" ;
Var2 =
"abc",
"def",
"ghi",
"jkl",
"mno" ;
Var3 =
"abcde",
"fghij",
"klmno" ;
}
Here's an F77 example of the same program:
-------------------------
program chartst
include 'netcdf.inc'
integer ncid, var1id, var2id, var3id, dim1id, dim2id
integer ndims
parameter(NDIMS = 2)
integer dimids(NDIMS), start(NDIMS), count(NDIMS)
character*1 ch(15)
data ch /"a","b","c","d","e","f","g","h","i","j","k","l","m","n"
$ ,"o"/
character*15 ch15
data ch15 /"abcdefghijklmno"/
character*5 ch5(3)
data ch5 /"abcde","fghij","klmno"/
integer status
status = nf_create('CharTest.nc', nf_clobber, ncid)
if(status .ne. nf_noerr) stop 1
status = nf_def_dim(ncid, 'Dim1', 5, dim1id)
if(status .ne. nf_noerr) stop 1
status = nf_def_dim(ncid, 'Dim2', 3, dim2id)
if(status .ne. nf_noerr) stop 1
dimids(1) = dim1id
dimids(2) = dim2id
status = nf_def_var(ncid, 'Var1', nf_char, NDIMS, dimids, var1id)
if(status .ne. nf_noerr) stop 1
dimids(1) = dim2id
dimids(2) = dim1id
status = nf_def_var(ncid, 'Var2', nf_char, NDIMS, dimids, var2id)
if(status .ne. nf_noerr) stop 1
dimids(1) = dim1id
dimids(2) = dim2id
status = nf_def_var(ncid, 'Var3', nf_char, NDIMS, dimids, var3id)
if(status .ne. nf_noerr) stop 1
status = nf_enddef(ncid)
if(status .ne. nf_noerr) stop 1
start(1) = 1
start(2) = 1
count(1) = 5
count(2) = 3
status = nf_put_vara_text(ncid, var1id, start, count, ch)
if(status .ne. nf_noerr) stop 1
count(1) = 3
count(2) = 5
status = nf_put_vara_text(ncid, var2id, start, count, ch15)
if(status .ne. nf_noerr) stop 1
count(1) = 5
count(2) = 3
status = nf_put_vara_text(ncid, var3id, start, count, ch5)
if(status .ne. nf_noerr) stop 1
status = nf_close(ncid)
if(status .ne. nf_noerr) stop 1
end
-------------------------
which produces an identical CharTest.nc file as the f90 example above.
> Should it be treated as 3D array where one of dimensions is the
> length of character string?
As you can see from the examples above, you may treat it that way or
not, since the Fortran function doesn't know the shape of the array it
gets passed.
> --- On Fri, 8/5/09, Unidata netCDF Support <address@hidden> wrote:
>
>
> From: Unidata netCDF Support <address@hidden>
> Subject: [netCDF #AOX-617597]: 2D character string array (Fortran 90)
> To: support-netcdf
> Cc: address@hidden
> Received: Friday, 8 May, 2009, 2:18 AM
>
>
> Hi Ruslan,
>
> > I've got an issue with writing (and reading) 2-dimensional character
> > string arrays in Fortran 90. I found an example how to do it in
> > java but it's not quite helpful because the language concept is
> > different. Could you provide me with the example for Fortran 90,
> > please?
>
> Sure, it looks like our documentation is really lacking in examples of
> writing character data using the f90 interface. I'll put the example
> inline rather than as an attachment, so it can be found more easily by
> others searching for such examples in the future.
>
> ----------------------------------
> program chartst
> use netcdf
>
> integer :: ncid, var1id, var2id, dim1id, dim2id;
> character (len = 1), dimension (15) :: ch = (/'a', 'b', 'c', 'd', 'e', &
> 'f', 'g', 'h', 'i', 'j', &
> 'k', 'l', 'm', 'n', 'o' /)
> character (len = 15) :: ch15 = "abcdefghijklmno";
>
> print *, 'Start: ', ch
> call check(nf90_create('CharTest.nc', nf90_clobber, ncid))
> call check(nf90_def_dim(ncid, 'Dim1', 5, dim1id))
> call check(nf90_def_dim(ncid, 'Dim2', 3, dim2id))
> call check(nf90_def_var(ncid, 'Var1', nf90_char, (/dim1id, dim2id/), var1id))
> call check(nf90_def_var(ncid, 'Var2', nf90_char, (/dim2id, dim1id/), var2id))
> call check(nf90_enddef(ncid))
>
> call check(nf90_put_var(ncid, var1id, ch, start=(/ 1, 1/), count=(/ 5, 3 /)))
> call check(nf90_put_var(ncid, var2id, ch15, start=(/ 1, 1/), count=(/ 3, 5
> /)))
> call check(nf90_close(ncid))
> print *, 'End: ', dims
>
> contains
> subroutine check(status)
> integer, intent ( in) :: status
>
> if(status /= nf90_noerr) then
> print *, trim(nf90_strerror(status))
> stop 2
> end if
> end subroutine check
> end program chartst
> ----------------------------------
>
> When you compile and run the program above, it creates CharTest.nc.
> Here's the result of running "ncdump CharTest.nc":
>
> $ ncdump CharTest.nc
> netcdf CharTest {
> dimensions:
> Dim1 = 5 ;
> Dim2 = 3 ;
> variables:
> char Var1(Dim2, Dim1) ;
> char Var2(Dim1, Dim2) ;
> data:
>
> Var1 =
> "abcde",
> "fghij",
> "klmno" ;
>
> Var2 =
> "abc",
> "def",
> "ghi",
> "jkl",
> "mno" ;
> }
Russ Rew UCAR Unidata Program
address@hidden http://www.unidata.ucar.edu
Ticket Details
===================
Ticket ID: AOX-617597
Department: Support netCDF
Priority: Normal
Status: Closed