[Dart-dev] [6592] DART/trunk/utilities: update the existing tool to by default compare all
nancy at ucar.edu
nancy at ucar.edu
Fri Nov 8 16:31:03 MST 2013
Revision: 6592
Author: nancy
Date: 2013-11-08 16:31:03 -0700 (Fri, 08 Nov 2013)
Log Message:
-----------
update the existing tool to by default compare all
integer, float, and double variables in the netcdf files.
update the documentation, the default nml, and the
test code to match.
Modified Paths:
--------------
DART/trunk/utilities/compare_states.f90
DART/trunk/utilities/compare_states.html
DART/trunk/utilities/compare_states.nml
DART/trunk/utilities/test/input.nml
-------------- next part --------------
Modified: DART/trunk/utilities/compare_states.f90
===================================================================
--- DART/trunk/utilities/compare_states.f90 2013-11-08 23:29:55 UTC (rev 6591)
+++ DART/trunk/utilities/compare_states.f90 2013-11-08 23:31:03 UTC (rev 6592)
@@ -37,16 +37,18 @@
! variables used to read the netcdf info
integer, parameter :: maxd = 7
-integer :: i, j, ndims, odims, ncrc, etype, nitems
+integer :: i, j, ndims, odims, ncrc, etype, nitems, nvars, xtype
integer :: ncinid1, ncinid2 ! netcdf id for file
integer :: invarid1, invarid2
integer :: dimid(maxd), dimlen(maxd), odimid(maxd), odimlen(maxd)
character(128) :: dimname(maxd), odimname(maxd)
integer :: nin1Dimensions, nin1Variables, nin1Attributes, in1unlimitedDimID
integer :: nin2Dimensions, nin2Variables, nin2Attributes, in2unlimitedDimID
-real(r8) :: min1, min2, max1, max2, delmin, delmax
+real(r8) :: min1, min2, max1, max2, delmin, delmax
+integer :: imin1, imin2, imax1, imax2, idelmin, idelmax
-! arrays for all possible dimensions
+! arrays for all possible dimensions, real and int
+real(r8) :: zerod1, zerod2
real(r8), pointer :: oned1(:), oned2(:)
real(r8), pointer :: twod1(:,:), twod2(:,:)
real(r8), pointer :: threed1(:,:,:), threed2(:,:,:)
@@ -55,6 +57,15 @@
real(r8), pointer :: sixd1(:,:,:,:,:,:), sixd2(:,:,:,:,:,:)
real(r8), pointer :: sevend1(:,:,:,:,:,:,:), sevend2(:,:,:,:,:,:,:)
+integer :: izerod1, izerod2
+integer, pointer :: ioned1(:), ioned2(:)
+integer, pointer :: itwod1(:,:), itwod2(:,:)
+integer, pointer :: ithreed1(:,:,:), ithreed2(:,:,:)
+integer, pointer :: ifourd1(:,:,:,:), ifourd2(:,:,:,:)
+integer, pointer :: ifived1(:,:,:,:,:), ifived2(:,:,:,:,:)
+integer, pointer :: isixd1(:,:,:,:,:,:), isixd2(:,:,:,:,:,:)
+integer, pointer :: isevend1(:,:,:,:,:,:,:), isevend2(:,:,:,:,:,:,:)
+
logical, save :: module_initialized = .false.
! arg parsing code
@@ -66,15 +77,17 @@
character(len=NF90_MAX_NAME) :: nextfield
logical :: from_file
-character(len=128) :: msgstring, msgstring2, tmpstring
+character(len=512) :: msgstring, msgstring2, tmpstring
integer :: iunit, io
logical :: debug = .false. ! or .true.
logical :: fail_on_missing_field = .true. ! or .false.
+logical :: do_all_numeric_fields = .true. ! or .false.
character(len=128) :: fieldnames(1000) = '' ! something large
character(len=128) :: fieldlist_file = ''
! fieldnames here?
namelist /compare_states_nml/ debug, fail_on_missing_field, &
+ do_all_numeric_fields, &
fieldnames, fieldlist_file
! main code here
@@ -118,21 +131,26 @@
infile1 = argwords(1)
infile2 = argwords(2)
-! make sure the namelist specifies one or the other but not both
-if (fieldnames(1) /= '' .and. fieldlist_file /= '') then
- call error_handler(E_ERR,'compare_states', &
- 'cannot specify both fieldnames and fieldlist_file', &
- source,revision,revdate)
-endif
-
call error_handler(E_MSG, 'compare_states', ' reading file: '//trim(infile1))
call error_handler(E_MSG, 'compare_states', ' and file: '//trim(infile2))
-if (fieldlist_file /= '') then
- call error_handler(E_MSG, 'compare_states', ' list of fields file: '//trim(fieldlist_file))
- from_file = .true.
+if (do_all_numeric_fields) then
+ call error_handler(E_MSG, 'compare_states', ' doing all numeric fields')
else
- call error_handler(E_MSG, 'compare_states', ' field names specified in namelist.')
- from_file = .false.
+ ! make sure the namelist specifies one or the other but not both
+ ! only if we aren't trying to do all fields in the file.
+ if (fieldnames(1) /= '' .and. fieldlist_file /= '') then
+ call error_handler(E_ERR,'compare_states', &
+ 'cannot specify both fieldnames and fieldlist_file', &
+ source,revision,revdate)
+ endif
+
+ if (fieldlist_file /= '') then
+ call error_handler(E_MSG, 'compare_states', ' list of fields file: '//trim(fieldlist_file))
+ from_file = .true.
+ else
+ call error_handler(E_MSG, 'compare_states', ' field names specified in namelist.')
+ from_file = .false.
+ endif
endif
! do they exist? can they be opened?
@@ -143,12 +161,19 @@
call nc_check(nf90_open(infile1, NF90_NOWRITE, ncinid1), 'nf90_open', 'infile1')
call nc_check(nf90_open(infile2, NF90_NOWRITE, ncinid2), 'nf90_open', 'infile2')
+call nc_check(nf90_inquire(ncinid1, nin1Dimensions, nin1Variables, &
+ nin1Attributes, in1unlimitedDimID), 'nf90_inquire', 'infile1')
+call nc_check(nf90_inquire(ncinid2, nin2Dimensions, nin2Variables, &
+ nin2Attributes, in2unlimitedDimID), 'nf90_inquire', 'infile2')
+
+! for now, loop over the number of vars in file 1. at some point we
+! should print out vars that are in 1 but not 2, and in 2 but not 1.
+! but for that we need more logic to track which vars are processed.
+! this code loops over the names in file 1 and finds them (or not)
+! in file 2 but doesn't complain about unused vars in file 2.
+nvars = nin1Variables
+
if (debug) then
- call nc_check(nf90_inquire(ncinid1, nin1Dimensions, nin1Variables, &
- nin1Attributes, in1unlimitedDimID), 'nf90_inquire', 'infile1')
- call nc_check(nf90_inquire(ncinid2, nin2Dimensions, nin2Variables, &
- nin2Attributes, in2unlimitedDimID), 'nf90_inquire', 'infile2')
-
write(msgstring, *) 'infile1 ndim, nvar, nattr:',nin1Dimensions, &
nin1Variables,nin1Attributes
call error_handler(E_MSG, 'compare_states', msgstring)
@@ -160,14 +185,26 @@
! input files to get data from
! list of netcdf fields to compare
-fieldloop : do i=1, 10000
+fieldloop : do i=1, 100000
- if (from_file) then
- nextfield = get_next_filename(fieldlist_file, i)
+ if (do_all_numeric_fields) then
+ if (i > nvars) exit fieldloop
+ call nc_check(nf90_inquire_variable(ncinid1, i, nextfield, xtype), &
+ 'nf90_inquire_variable', 'infile1')
+ if (xtype /= NF90_INT .and. xtype /= NF90_FLOAT .and. xtype /= NF90_DOUBLE) then
+ tmpstring = ' not integer, float, or double'
+ msgstring = 'skipping variable '//trim(nextfield)//','//trim(tmpstring)
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ cycle fieldloop
+ endif
else
- nextfield = fieldnames(i)
+ if (from_file) then
+ nextfield = get_next_filename(fieldlist_file, i)
+ else
+ nextfield = fieldnames(i)
+ endif
+ if (nextfield == '') exit fieldloop
endif
- if (nextfield == '') exit fieldloop
! inquire in inputs for fieldname
ncrc = nf90_inq_varid(ncinid1, trim(nextfield), invarid1)
@@ -249,6 +286,8 @@
select case(ndims)
+ case (0)
+ write(tmpstring, '(2A)') trim(nextfield), ' [scalar value]'
case (1)
write(tmpstring, '(2A,1I5,A)') trim(nextfield), '(', dimlen(1), ')'
case (2)
@@ -279,8 +318,153 @@
! arrays it is hard to do much else. we could overload a subroutine
! with each dimension but we'd end up with the same amount of replicated code
- select case(ndims)
+ select case(xtype)
+ case(NF90_INT)
+ select case(ndims)
+ case (0)
+ call nc_check(nf90_get_var(ncinid1, invarid1, izerod1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, izerod2), 'nf90_get_var', 'infile2')
+ imin1 = izerod1
+ imax1 = izerod1
+ imin2 = izerod2
+ imax2 = izerod2
+ idelmin = abs(izerod1-izerod2)
+ idelmax = abs(izerod1-izerod2)
+ if(izerod1 .ne. izerod2) then
+ nitems = 1
+ else
+ nitems = 0
+ endif
case (1)
+ allocate(ioned1(dimlen(1)))
+ allocate(ioned2(dimlen(1)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, ioned1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, ioned2), 'nf90_get_var', 'infile2')
+ imin1 = minval(ioned1)
+ imax1 = maxval(ioned1)
+ imin2 = minval(ioned2)
+ imax2 = maxval(ioned2)
+ idelmin = minval(abs(ioned1-ioned2))
+ idelmax = maxval(abs(ioned1-ioned2))
+ nitems = count(ioned1 .ne. ioned2)
+ deallocate(ioned1, ioned2)
+ case (2)
+ allocate(itwod1(dimlen(1),dimlen(2)))
+ allocate(itwod2(dimlen(1),dimlen(2)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, itwod1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, itwod2), 'nf90_get_var', 'infile2')
+ imin1 = minval(itwod1)
+ imax1 = maxval(itwod1)
+ imin2 = minval(itwod2)
+ imax2 = maxval(itwod2)
+ idelmin = minval(abs(itwod1-itwod2))
+ idelmax = maxval(abs(itwod1-itwod2))
+ nitems = count(itwod1 .ne. itwod2)
+ deallocate(itwod1, itwod2)
+ case (3)
+ allocate(ithreed1(dimlen(1),dimlen(2),dimlen(3)))
+ allocate(ithreed2(dimlen(1),dimlen(2),dimlen(3)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, ithreed1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, ithreed2), 'nf90_get_var', 'infile2')
+ imin1 = minval(ithreed1)
+ imax1 = maxval(ithreed1)
+ imin2 = minval(ithreed2)
+ imax2 = maxval(ithreed2)
+ idelmin = minval(abs(ithreed1-ithreed2))
+ idelmax = maxval(abs(ithreed1-ithreed2))
+ nitems = count(ithreed1 .ne. ithreed2)
+ deallocate(ithreed1, ithreed2)
+ case (4)
+ allocate(ifourd1(dimlen(1),dimlen(2),dimlen(3),dimlen(4)))
+ allocate(ifourd2(dimlen(1),dimlen(2),dimlen(3),dimlen(4)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, ifourd1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, ifourd2), 'nf90_get_var', 'infile2')
+ imin1 = minval(ifourd1)
+ imax1 = maxval(ifourd1)
+ imin2 = minval(ifourd2)
+ imax2 = maxval(ifourd2)
+ idelmin = minval(abs(ifourd1-ifourd2))
+ idelmax = maxval(abs(ifourd1-ifourd2))
+ nitems = count(ifourd1 .ne. ifourd2)
+ deallocate(ifourd1, ifourd2)
+ case (5)
+ allocate(ifived1(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5)))
+ allocate(ifived2(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, ifived1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, ifived2), 'nf90_get_var', 'infile2')
+ imin1 = minval(ifived1)
+ imax1 = maxval(ifived1)
+ imin2 = minval(ifived2)
+ imax2 = maxval(ifived2)
+ idelmin = minval(abs(ifived1-ifived2))
+ idelmax = maxval(abs(ifived1-ifived2))
+ nitems = count(ifived1 .ne. ifived2)
+ deallocate(ifived1, ifived2)
+ case (6)
+ allocate(isixd1(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5),dimlen(6)))
+ allocate(isixd2(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5),dimlen(6)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, isixd1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, isixd2), 'nf90_get_var', 'infile2')
+ imin1 = minval(isixd1)
+ imax1 = maxval(isixd1)
+ imin2 = minval(isixd2)
+ imax2 = maxval(isixd2)
+ idelmin = minval(abs(isixd1-isixd2))
+ idelmax = maxval(abs(isixd1-isixd2))
+ nitems = count(isixd1 .ne. isixd2)
+ deallocate(isixd1, isixd2)
+ case (7)
+ allocate(isevend1(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5),dimlen(6),dimlen(7)))
+ allocate(isevend2(dimlen(1),dimlen(2),dimlen(3),dimlen(4),dimlen(5),dimlen(6),dimlen(7)))
+ call nc_check(nf90_get_var(ncinid1, invarid1, isevend1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, isevend2), 'nf90_get_var', 'infile2')
+ imin1 = minval(isevend1)
+ imax1 = maxval(isevend1)
+ imin2 = minval(isevend2)
+ imax2 = maxval(isevend2)
+ idelmin = minval(abs(isevend1-isevend2))
+ idelmax = maxval(abs(isevend1-isevend2))
+ nitems = count(isevend1 .ne. isevend2)
+ deallocate(isevend1, isevend2)
+ case default
+ ! "really can't happen"
+ write(msgstring, *) 'array dimension is illegal value: ', ndims
+ call error_handler(E_ERR, 'compare_states', msgstring, source, revision, revdate)
+ end select
+ ! common reporting code for integers
+ if (nitems > 0) then
+ write(msgstring, *) 'arrays differ in ', nitems, ' places'
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max file1: ', imin1, imax1
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max file2: ', imin2, imax2
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'delta min/max: ', idelmin, idelmax
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ else
+ write(msgstring, *) 'arrays same'
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max value: ', imin1, imax1
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ endif
+
+ case default
+ select case(ndims)
+ case (0)
+ call nc_check(nf90_get_var(ncinid1, invarid1, zerod1), 'nf90_get_var', 'infile1')
+ call nc_check(nf90_get_var(ncinid2, invarid2, zerod2), 'nf90_get_var', 'infile2')
+ min1 = zerod1
+ max1 = zerod1
+ min2 = zerod2
+ max2 = zerod2
+ delmin = abs(zerod1-zerod2)
+ delmax = abs(zerod1-zerod2)
+ if(zerod1 .ne. zerod2) then
+ nitems = 1
+ else
+ nitems = 0
+ endif
+ case (1)
allocate(oned1(dimlen(1)))
allocate(oned2(dimlen(1)))
call nc_check(nf90_get_var(ncinid1, invarid1, oned1), 'nf90_get_var', 'infile1')
@@ -375,25 +559,26 @@
! "really can't happen"
write(msgstring, *) 'array dimension is illegal value: ', ndims
call error_handler(E_ERR, 'compare_states', msgstring, source, revision, revdate)
+ end select
+
+ ! common reporting code for reals
+ if (nitems > 0) then
+ write(msgstring, *) 'arrays differ in ', nitems, ' places'
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max file1: ', min1, max1
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max file2: ', min2, max2
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'delta min/max: ', delmin, delmax
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ else
+ write(msgstring, *) 'arrays same'
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ write(msgstring, *) 'min/max value: ', min1, max1
+ call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
+ endif
end select
- ! common reporting code
- if (nitems > 0) then
- write(msgstring, *) 'arrays differ in ', nitems, ' places'
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- write(msgstring, *) 'min/max file1: ', min1, max1
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- write(msgstring, *) 'min/max file2: ', min2, max2
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- write(msgstring, *) 'delta min/max: ', delmin, delmax
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- else
- write(msgstring, *) 'arrays same'
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- write(msgstring, *) 'min/max value: ', min1, max1
- call error_handler(E_MSG, 'compare_states', msgstring, source, revision, revdate)
- endif
-
enddo fieldloop
! close up
@@ -401,8 +586,10 @@
call nc_check(nf90_close(ncinid2), 'nf90_close', 'infile2')
if (debug) then
- write(msgstring, *) 'closing files', trim(infile1), ' and ', trim(infile2)
+ write(msgstring, *) 'closing files ', trim(infile1)
call error_handler(E_MSG, 'compare_states', msgstring)
+ write(msgstring, *) 'and ', trim(infile2)
+ call error_handler(E_MSG, 'compare_states', msgstring)
endif
call finalize_utilities('compare_states')
Modified: DART/trunk/utilities/compare_states.html
===================================================================
--- DART/trunk/utilities/compare_states.html 2013-11-08 23:29:55 UTC (rev 6591)
+++ DART/trunk/utilities/compare_states.html 2013-11-08 23:31:03 UTC (rev 6592)
@@ -39,18 +39,19 @@
Utility program to compare fields in two NetCDF files and
print out the min and max values from each file and the
min and max of the differences between the two fields.
-The fields to be compared can be named directly in the
-namelist, or can be in a separate file.
-The two input filenames are read from the console or
+The default is to compare all numeric variables in the files,
+but specific variables can be specified in the namelist or
+in a separate file.
+The two input NetCDF filenames are read from the console or
can be echo'd into the standard input of the program.
</P>
<P>
-Specify the list of field names to compare either in
+If you want to restrict the comparison to only specific
+variables in the files,
+specify the list of field names to compare either in
the namelist, or put a list of fields, one per line,
in a text file and specify the name of the text file.
-There should be an option to compare all data fields
-in the file (this is not implemented yet.)
Only data arrays can be compared, not character arrays,
strings, or attribute values.
</P>
@@ -80,6 +81,7 @@
<div class=namelist>
<pre>
&compare_states_nml
+ do_all_numeric_fields = .true.,
fieldnames = '',
fieldlist_file = '',
fail_on_missing_field = .true.,
@@ -101,15 +103,27 @@
<TBODY valign=top>
+<TR><TD>do_all_numeric_fields</TD>
+ <TD>logical</TD>
+ <TD>If .true., all integer, float, and double variables in the
+NetCDF files will have their values compared. If .false. the list of
+specific variables to be compared must be given either directly in
+the namelist in the <em class=code>fieldnames</em> item, or else the
+field names must be listed in an ASCII file, one name per line, and
+the name of that file is specified in <em class=code>fieldlist_file</em>.
+</TD></TR>
+
<TR><TD>fieldnames</TD>
<TD>character list</TD>
<TD>One or more names of arrays in the NetCDF files to be compared.
+Only read if <em class=code>do_all_numeric_fields</em> is .false.
</TD></TR>
<TR><TD>fieldlist_file</TD>
<TD>character</TD>
<TD>Name of a text file containing the fieldnames, one per line. It is an
error to specify both the fieldnames namelist item and this one.
+Only read if <em class=code>do_all_numeric_fields</em> is .false.
</TD></TR>
<TR><TD>fail_on_missing_field</TD>
Modified: DART/trunk/utilities/compare_states.nml
===================================================================
--- DART/trunk/utilities/compare_states.nml 2013-11-08 23:29:55 UTC (rev 6591)
+++ DART/trunk/utilities/compare_states.nml 2013-11-08 23:31:03 UTC (rev 6592)
@@ -1,4 +1,5 @@
&compare_states_nml
+ do_all_numeric_fields = .true.,
fieldnames = '',
fieldlist_file = '',
fail_on_missing_field = .true.,
Modified: DART/trunk/utilities/test/input.nml
===================================================================
--- DART/trunk/utilities/test/input.nml 2013-11-08 23:29:55 UTC (rev 6591)
+++ DART/trunk/utilities/test/input.nml 2013-11-08 23:31:03 UTC (rev 6592)
@@ -1,3 +1,10 @@
&utilities_nml
+ module_details = .false.,
+ write_nml = 'none'
/
+&compare_states_nml
+ do_all_numeric_fields = .true.,
+ debug = .false.
+/
+
More information about the Dart-dev
mailing list